Merge lp:~mardy/webbrowser-app/multi-account-no-ui into lp:webbrowser-app
- multi-account-no-ui
- Merge into trunk
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 |
Related bugs: |
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-
--name=Twitter --icon=
PS Jenkins bot (ps-jenkins) wrote : | # |
- 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.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:975
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 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
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:976
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:978
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 979. By Alberto Mardegan
-
UI changes
- 980. By Alberto Mardegan
-
Fixes
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:979
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 981. By Alberto Mardegan
-
UI updates
- 982. By Alberto Mardegan
-
alignment
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:981
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:982
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
system-apps-ci-bot (system-apps-ci-bot) wrote : | # |
FAILED: Continuous integration, rev:982
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
Click here to trigger a rebuild:
https:/
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
1 | === added file 'src/app/webcontainer/AccountChooserDialog.qml' | |||
2 | --- src/app/webcontainer/AccountChooserDialog.qml 1970-01-01 00:00:00 +0000 | |||
3 | +++ src/app/webcontainer/AccountChooserDialog.qml 2015-04-16 14:53:15 +0000 | |||
4 | @@ -0,0 +1,129 @@ | |||
5 | 1 | /* | ||
6 | 2 | * Copyright 2013-2014 Canonical Ltd. | ||
7 | 3 | * | ||
8 | 4 | * This file is part of webbrowser-app. | ||
9 | 5 | * | ||
10 | 6 | * webbrowser-app is free software; you can redistribute it and/or modify | ||
11 | 7 | * it under the terms of the GNU General Public License as published by | ||
12 | 8 | * the Free Software Foundation; version 3. | ||
13 | 9 | * | ||
14 | 10 | * webbrowser-app is distributed in the hope that it will be useful, | ||
15 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | 13 | * GNU General Public License for more details. | ||
18 | 14 | * | ||
19 | 15 | * You should have received a copy of the GNU General Public License | ||
20 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
21 | 17 | */ | ||
22 | 18 | |||
23 | 19 | import QtQuick 2.0 | ||
24 | 20 | import Qt.labs.settings 1.0 | ||
25 | 21 | import Ubuntu.Components 1.1 | ||
26 | 22 | import Ubuntu.Components.ListItems 1.0 as ListItem | ||
27 | 23 | import Ubuntu.Components.Popups 1.0 | ||
28 | 24 | import Ubuntu.OnlineAccounts 0.1 | ||
29 | 25 | import Ubuntu.OnlineAccounts.Client 0.1 | ||
30 | 26 | |||
31 | 27 | Dialog { | ||
32 | 28 | id: root | ||
33 | 29 | |||
34 | 30 | property string providerId: "" | ||
35 | 31 | property string applicationId: "" | ||
36 | 32 | property bool accountMandatory: true | ||
37 | 33 | property var accountsModel: null | ||
38 | 34 | |||
39 | 35 | signal accountSelected(int accountId) | ||
40 | 36 | signal cancel() | ||
41 | 37 | |||
42 | 38 | property var __selectedAccount: settings.selectedAccount | ||
43 | 39 | |||
44 | 40 | Settings { | ||
45 | 41 | id: settings | ||
46 | 42 | property int selectedAccount | ||
47 | 43 | } | ||
48 | 44 | |||
49 | 45 | Setup { | ||
50 | 46 | id: setup | ||
51 | 47 | applicationId: root.applicationId | ||
52 | 48 | providerId: root.providerId | ||
53 | 49 | onFinished: { | ||
54 | 50 | if ("accountId" in reply) { | ||
55 | 51 | root.chooseAccount(reply.accountId) | ||
56 | 52 | } else { | ||
57 | 53 | root.cancel() | ||
58 | 54 | } | ||
59 | 55 | } | ||
60 | 56 | } | ||
61 | 57 | |||
62 | 58 | Repeater { | ||
63 | 59 | model: accountsModel | ||
64 | 60 | AccountItem { | ||
65 | 61 | providerName: model.providerName | ||
66 | 62 | accountName: model.displayName | ||
67 | 63 | selected: model.accountId === root.__selectedAccount | ||
68 | 64 | onClicked: root.__selectedAccount = model.accountId | ||
69 | 65 | } | ||
70 | 66 | } | ||
71 | 67 | |||
72 | 68 | ListItem.Standard { | ||
73 | 69 | id: addAccountButton | ||
74 | 70 | text: i18n.tr("Add account") | ||
75 | 71 | iconName: "add" | ||
76 | 72 | selected: root.__selectedAccount === -1 | ||
77 | 73 | onClicked: root.__selectedAccount = -1 | ||
78 | 74 | } | ||
79 | 75 | |||
80 | 76 | ListItem.Standard { | ||
81 | 77 | id: skipButton | ||
82 | 78 | visible: !root.accountMandatory | ||
83 | 79 | text: i18n.tr("Don't use an account") | ||
84 | 80 | selected: root.__selectedAccount === -2 | ||
85 | 81 | onClicked: root.__selectedAccount = -2 | ||
86 | 82 | } | ||
87 | 83 | |||
88 | 84 | Item { | ||
89 | 85 | anchors.left: parent.left | ||
90 | 86 | anchors.right: parent.right | ||
91 | 87 | anchors.margins: units.gu(1) | ||
92 | 88 | height: childrenRect.height + units.gu(1) | ||
93 | 89 | |||
94 | 90 | Button { | ||
95 | 91 | id: cancelButton | ||
96 | 92 | anchors.left: parent.left | ||
97 | 93 | width: parent.width / 2 - units.gu(1) | ||
98 | 94 | text: i18n.tr("Cancel") | ||
99 | 95 | onClicked: root.cancel() | ||
100 | 96 | } | ||
101 | 97 | |||
102 | 98 | Button { | ||
103 | 99 | anchors.right: parent.right | ||
104 | 100 | width: cancelButton.width | ||
105 | 101 | text: i18n.tr("OK") | ||
106 | 102 | onClicked: root.onConfirmed() | ||
107 | 103 | } | ||
108 | 104 | } | ||
109 | 105 | |||
110 | 106 | function chooseAccount(accountId) { | ||
111 | 107 | for (var i = 0; i < accountsModel.count; i++) { | ||
112 | 108 | if (accountsModel.get(i, "accountId") === accountId) { | ||
113 | 109 | settings.selectedAccount = accountId | ||
114 | 110 | root.accountSelected(accountId) | ||
115 | 111 | return | ||
116 | 112 | } | ||
117 | 113 | } | ||
118 | 114 | |||
119 | 115 | // The selected account was not found | ||
120 | 116 | settings.selectedAccount = -1 | ||
121 | 117 | root.cancel() | ||
122 | 118 | } | ||
123 | 119 | |||
124 | 120 | function onConfirmed() { | ||
125 | 121 | if (__selectedAccount === -2) { | ||
126 | 122 | root.selectedAccount(0) | ||
127 | 123 | } else if (__selectedAccount === -1) { | ||
128 | 124 | setup.exec() | ||
129 | 125 | } else { | ||
130 | 126 | chooseAccount(__selectedAccount) | ||
131 | 127 | } | ||
132 | 128 | } | ||
133 | 129 | } | ||
134 | 0 | 130 | ||
135 | === renamed file 'src/app/webcontainer/AccountItemView.qml' => 'src/app/webcontainer/AccountItem.qml' | |||
136 | --- src/app/webcontainer/AccountItemView.qml 2014-07-29 21:51:07 +0000 | |||
137 | +++ src/app/webcontainer/AccountItem.qml 2015-04-16 14:53:15 +0000 | |||
138 | @@ -20,14 +20,12 @@ | |||
139 | 20 | import Ubuntu.Components 1.1 | 20 | import Ubuntu.Components 1.1 |
140 | 21 | import Ubuntu.Components.ListItems 1.0 as ListItem | 21 | import Ubuntu.Components.ListItems 1.0 as ListItem |
141 | 22 | 22 | ||
143 | 23 | ListItem.Standard { | 23 | ListItem.Subtitled { |
144 | 24 | id: root | 24 | id: root |
145 | 25 | 25 | ||
146 | 26 | property string providerName | ||
147 | 26 | property string accountName | 27 | property string accountName |
148 | 27 | 28 | ||
152 | 28 | text: accountName | 29 | text: providerName |
153 | 29 | 30 | subText: accountName | |
151 | 30 | iconSource: Qt.resolvedUrl("/usr/share/icons/ubuntu-mobile/actions/scalable/contact.svg") | ||
154 | 31 | } | 31 | } |
155 | 32 | |||
156 | 33 | |||
157 | 34 | 32 | ||
158 | === modified file 'src/app/webcontainer/AccountsLoginPage.qml' | |||
159 | --- src/app/webcontainer/AccountsLoginPage.qml 2014-10-06 12:52:34 +0000 | |||
160 | +++ src/app/webcontainer/AccountsLoginPage.qml 2015-04-16 14:53:15 +0000 | |||
161 | @@ -17,18 +17,19 @@ | |||
162 | 17 | */ | 17 | */ |
163 | 18 | 18 | ||
164 | 19 | import QtQuick 2.0 | 19 | import QtQuick 2.0 |
165 | 20 | import Qt.labs.settings 1.0 | ||
166 | 20 | import Ubuntu.Components 1.1 | 21 | import Ubuntu.Components 1.1 |
167 | 21 | import Ubuntu.Components.ListItems 1.0 as ListItem | 22 | import Ubuntu.Components.ListItems 1.0 as ListItem |
168 | 22 | import Ubuntu.OnlineAccounts 0.1 | 23 | import Ubuntu.OnlineAccounts 0.1 |
170 | 23 | 24 | import Ubuntu.OnlineAccounts.Client 0.1 | |
171 | 24 | 25 | ||
172 | 25 | Item { | 26 | Item { |
173 | 26 | id: root | 27 | id: root |
174 | 27 | 28 | ||
177 | 28 | property string accountProvider: "" | 29 | property var accountsModel |
176 | 29 | property string applicationName: "" | ||
178 | 30 | 30 | ||
180 | 31 | signal done(variant credentialsId) | 31 | signal accountSelected(int accountId) |
181 | 32 | signal done(bool successful) | ||
182 | 32 | 33 | ||
183 | 33 | Timer { | 34 | Timer { |
184 | 34 | id: checkTimer | 35 | id: checkTimer |
185 | @@ -38,14 +39,21 @@ | |||
186 | 38 | interval: 100 | 39 | interval: 100 |
187 | 39 | } | 40 | } |
188 | 40 | 41 | ||
194 | 41 | AccountsModel { | 42 | Settings { |
195 | 42 | id: accountsModel | 43 | id: settings |
196 | 43 | accountProvider: root.accountProvider | 44 | property int selectedAccount: -1 |
197 | 44 | applicationName: root.applicationName | 45 | } |
198 | 45 | onCountChanged: checkAccounts() | 46 | |
199 | 47 | Setup { | ||
200 | 48 | id: setup | ||
201 | 49 | applicationId: accountsModel.applicationId | ||
202 | 50 | providerId: accountsModel.provider | ||
203 | 46 | onFinished: { | 51 | onFinished: { |
206 | 47 | if (count === 0) { | 52 | if ("accountId" in reply) { |
207 | 48 | Qt.quit(); | 53 | settings.selectedAccount = reply.accountId |
208 | 54 | root.accountSelected(reply.accountId) | ||
209 | 55 | } else { | ||
210 | 56 | Qt.quit() | ||
211 | 49 | } | 57 | } |
212 | 50 | } | 58 | } |
213 | 51 | } | 59 | } |
214 | @@ -64,137 +72,46 @@ | |||
215 | 64 | checkTimer.stop() | 72 | checkTimer.stop() |
216 | 65 | console.log("Accounts: " + accountsModel.count) | 73 | console.log("Accounts: " + accountsModel.count) |
217 | 66 | if (accountsModel.count === 0) { | 74 | if (accountsModel.count === 0) { |
330 | 67 | accountsModel.createNewAccount() | 75 | setup.exec(); |
331 | 68 | } else { | 76 | } else if (settings.selectedAccount > 0) { |
332 | 69 | doLogin(accountsModel.model.get(0, "accountServiceHandle")) | 77 | // check that the account exists |
333 | 70 | } | 78 | for (var i = 0; i < accountsModel.count; i++) { |
334 | 71 | 79 | if (accountsModel.get(i, "accountId") === settings.selectedAccount) { | |
335 | 72 | // Note: Disable the account selection for now until we have a clearer view of | 80 | break; |
336 | 73 | // the design and behavior related to the feature. Keep the code for reference. | 81 | } |
337 | 74 | /* | 82 | } |
338 | 75 | if (accountsModel.count === 1) { | 83 | if (i >= accountsModel.count) { |
339 | 76 | doLogin(accountsModel.model.get(0, "accountServiceHandle")) | 84 | // The selected account was not found, pick the first account |
340 | 77 | } else { | 85 | settings.selectedAccount = accountsModel.get(0, "accountId") |
341 | 78 | accountsViewLoader.sourceComponent = accountsSelectionViewComponent | 86 | } |
342 | 79 | } | 87 | } |
343 | 80 | */ | 88 | |
344 | 81 | } | 89 | root.accountSelected(settings.selectedAccount) |
345 | 82 | 90 | } | |
346 | 83 | Component { | 91 | |
347 | 84 | id: accountsAdditionToolbarViewComponent | 92 | function login(account, forceCookieRefresh) { |
348 | 85 | Item { | 93 | console.log("Preparing for login, forced = " + forceCookieRefresh) |
237 | 86 | id: addAccountView | ||
238 | 87 | |||
239 | 88 | Label { | ||
240 | 89 | id: label | ||
241 | 90 | anchors.centerIn: parent | ||
242 | 91 | text: i18n.tr("No local account found for ") + root.accountProvider + "." | ||
243 | 92 | } | ||
244 | 93 | |||
245 | 94 | Label { | ||
246 | 95 | id: skipLabel | ||
247 | 96 | text: i18n.tr("Skip account creation step") | ||
248 | 97 | color: UbuntuColors.orange | ||
249 | 98 | fontSize: "small" | ||
250 | 99 | |||
251 | 100 | anchors.top: label.bottom | ||
252 | 101 | anchors.horizontalCenter: parent.horizontalCenter | ||
253 | 102 | |||
254 | 103 | Icon { | ||
255 | 104 | anchors.left: parent.right | ||
256 | 105 | anchors.verticalCenter: parent.verticalCenter | ||
257 | 106 | height: units.dp(12) | ||
258 | 107 | width: units.dp(12) | ||
259 | 108 | name: "chevron" | ||
260 | 109 | color: UbuntuColors.orange | ||
261 | 110 | } | ||
262 | 111 | |||
263 | 112 | MouseArea { | ||
264 | 113 | anchors.fill: parent | ||
265 | 114 | anchors.margins: -units.gu(5) | ||
266 | 115 | onClicked: root.done(null) | ||
267 | 116 | } | ||
268 | 117 | } | ||
269 | 118 | |||
270 | 119 | Panel { | ||
271 | 120 | id: panel | ||
272 | 121 | anchors { | ||
273 | 122 | right: parent.right | ||
274 | 123 | left: parent.left | ||
275 | 124 | bottom: parent.bottom | ||
276 | 125 | } | ||
277 | 126 | |||
278 | 127 | locked: true | ||
279 | 128 | |||
280 | 129 | height: units.gu(8) | ||
281 | 130 | |||
282 | 131 | Rectangle { | ||
283 | 132 | color: Theme.palette.normal.overlay | ||
284 | 133 | anchors.fill: parent | ||
285 | 134 | Item { | ||
286 | 135 | height: units.gu(8) | ||
287 | 136 | width: units.gu(8) | ||
288 | 137 | |||
289 | 138 | anchors { | ||
290 | 139 | right: parent.right | ||
291 | 140 | bottom: parent.bottom | ||
292 | 141 | } | ||
293 | 142 | |||
294 | 143 | ToolbarButton { | ||
295 | 144 | action: Action { | ||
296 | 145 | text: i18n.tr("Add account") | ||
297 | 146 | iconSource: Qt.resolvedUrl("/usr/share/icons/ubuntu-mobile/actions/scalable/add.svg") | ||
298 | 147 | onTriggered: { | ||
299 | 148 | accountsModel.createNewAccount(); | ||
300 | 149 | } | ||
301 | 150 | } | ||
302 | 151 | } | ||
303 | 152 | |||
304 | 153 | signal clicked() | ||
305 | 154 | onClicked: { | ||
306 | 155 | accountsModel.createNewAccount(); | ||
307 | 156 | } | ||
308 | 157 | } | ||
309 | 158 | } | ||
310 | 159 | |||
311 | 160 | Component.onCompleted: panel.open() | ||
312 | 161 | } | ||
313 | 162 | |||
314 | 163 | } | ||
315 | 164 | } | ||
316 | 165 | |||
317 | 166 | Component { | ||
318 | 167 | id: accountsSelectionViewComponent | ||
319 | 168 | AccountsView { | ||
320 | 169 | id: accountsView | ||
321 | 170 | |||
322 | 171 | model: accountsModel.model | ||
323 | 172 | |||
324 | 173 | onAccountSelected: doLogin(accountServiceHandle) | ||
325 | 174 | } | ||
326 | 175 | } | ||
327 | 176 | |||
328 | 177 | function doLogin(accountHandle) { | ||
329 | 178 | var account = accountComponent.createObject(root, {objectHandle: accountHandle}); | ||
349 | 179 | 94 | ||
350 | 180 | function authenticatedCallback() { | 95 | function authenticatedCallback() { |
353 | 181 | account.authenticated.disconnect(authenticatedCallback); | 96 | console.log("Authenticated!") |
354 | 182 | done(account.authData.credentialsId); | 97 | account.authenticated.disconnect(authenticatedCallback) |
355 | 98 | root.done(true) | ||
356 | 183 | } | 99 | } |
358 | 184 | account.authenticated.connect(authenticatedCallback); | 100 | account.authenticated.connect(authenticatedCallback) |
359 | 185 | 101 | ||
360 | 186 | function errorCallback() { | 102 | function errorCallback() { |
372 | 187 | account.authenticationError.disconnect(errorCallback); | 103 | console.log("Authentication error!") |
373 | 188 | done(null); | 104 | account.authenticationError.disconnect(errorCallback) |
374 | 189 | } | 105 | root.done(false) |
375 | 190 | account.authenticationError.connect(errorCallback); | 106 | } |
376 | 191 | 107 | account.authenticationError.connect(errorCallback) | |
377 | 192 | account.authenticate(null); | 108 | |
378 | 193 | } | 109 | var params = {} |
379 | 194 | 110 | if (forceCookieRefresh) { | |
380 | 195 | Component { | 111 | params["UiPolicy"] = 1 // RequestPasswordPolicy |
381 | 196 | id: accountComponent | 112 | } |
382 | 197 | AccountService { } | 113 | |
383 | 114 | account.authenticate(params) | ||
384 | 198 | } | 115 | } |
385 | 199 | } | 116 | } |
386 | 200 | 117 | ||
387 | 201 | 118 | ||
388 | === removed file 'src/app/webcontainer/AccountsModel.qml' | |||
389 | --- src/app/webcontainer/AccountsModel.qml 2014-10-02 07:30:06 +0000 | |||
390 | +++ src/app/webcontainer/AccountsModel.qml 1970-01-01 00:00:00 +0000 | |||
391 | @@ -1,51 +0,0 @@ | |||
392 | 1 | /* | ||
393 | 2 | * Copyright 2013 Canonical Ltd. | ||
394 | 3 | * | ||
395 | 4 | * This file is part of webbrowser-app. | ||
396 | 5 | * | ||
397 | 6 | * webbrowser-app is free software; you can redistribute it and/or modify | ||
398 | 7 | * it under the terms of the GNU General Public License as published by | ||
399 | 8 | * the Free Software Foundation; version 3. | ||
400 | 9 | * | ||
401 | 10 | * webbrowser-app is distributed in the hope that it will be useful, | ||
402 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
403 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
404 | 13 | * GNU General Public License for more details. | ||
405 | 14 | * | ||
406 | 15 | * You should have received a copy of the GNU General Public License | ||
407 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
408 | 17 | */ | ||
409 | 18 | |||
410 | 19 | import QtQuick 2.0 | ||
411 | 20 | import Ubuntu.OnlineAccounts 0.1 | ||
412 | 21 | import Ubuntu.OnlineAccounts.Client 0.1 | ||
413 | 22 | |||
414 | 23 | Item { | ||
415 | 24 | id: root | ||
416 | 25 | property string accountProvider: "" | ||
417 | 26 | property string applicationName: "" | ||
418 | 27 | property alias count: accountsModel.count | ||
419 | 28 | |||
420 | 29 | signal finished | ||
421 | 30 | |||
422 | 31 | function createNewAccount() { | ||
423 | 32 | setup.exec(); | ||
424 | 33 | } | ||
425 | 34 | |||
426 | 35 | readonly property alias model: accountsModel | ||
427 | 36 | |||
428 | 37 | AccountServiceModel { | ||
429 | 38 | id: accountsModel | ||
430 | 39 | includeDisabled: false | ||
431 | 40 | serviceType: "webapps" | ||
432 | 41 | applicationId: root.applicationName | ||
433 | 42 | provider: root.accountProvider | ||
434 | 43 | } | ||
435 | 44 | |||
436 | 45 | Setup { | ||
437 | 46 | id: setup | ||
438 | 47 | applicationId: root.applicationName | ||
439 | 48 | providerId: root.accountProvider | ||
440 | 49 | onFinished: root.finished() | ||
441 | 50 | } | ||
442 | 51 | } | ||
443 | 52 | 0 | ||
444 | === modified file 'src/app/webcontainer/AccountsPage.qml' | |||
445 | --- src/app/webcontainer/AccountsPage.qml 2014-10-02 18:03:46 +0000 | |||
446 | +++ src/app/webcontainer/AccountsPage.qml 2015-04-16 14:53:15 +0000 | |||
447 | @@ -18,15 +18,33 @@ | |||
448 | 18 | 18 | ||
449 | 19 | import QtQuick 2.0 | 19 | import QtQuick 2.0 |
450 | 20 | import Ubuntu.Components 1.1 | 20 | import Ubuntu.Components 1.1 |
451 | 21 | import Ubuntu.Components.Popups 1.0 | ||
452 | 22 | import Ubuntu.OnlineAccounts 0.1 | ||
453 | 21 | import webcontainer.private 0.1 | 23 | import webcontainer.private 0.1 |
454 | 22 | 24 | ||
455 | 23 | Page { | 25 | Page { |
462 | 24 | id: accountsPage | 26 | id: root |
463 | 25 | 27 | ||
464 | 26 | property alias accountProvider: accountsLogin.accountProvider | 28 | property string providerId: "" |
465 | 27 | property alias applicationName: accountsLogin.applicationName | 29 | property string applicationId: "" |
466 | 28 | 30 | property string webappName: "" | |
467 | 29 | signal done(bool successful, var credentialsId) | 31 | property url webappIcon |
468 | 32 | property int credentialsId: -1 | ||
469 | 33 | property alias webview: detector.webview | ||
470 | 34 | property alias logoutUrlPattern: detector.logoutUrlPattern | ||
471 | 35 | property alias logoutSelectors: detector.logoutSelectors | ||
472 | 36 | |||
473 | 37 | signal accountSelected(var credentialsId) | ||
474 | 38 | signal done(bool successful) | ||
475 | 39 | |||
476 | 40 | property string __applicationName: webappName | ||
477 | 41 | property url __applicationIcon: webappIcon | ||
478 | 42 | property string __providerName: providerId | ||
479 | 43 | property var __account: null | ||
480 | 44 | property var __loggedOutAccounts: [] | ||
481 | 45 | property var __accountsModel: accountsModel | ||
482 | 46 | property bool __loggingIn: false | ||
483 | 47 | property bool __ignoreLogout: false | ||
484 | 30 | 48 | ||
485 | 31 | visible: true | 49 | visible: true |
486 | 32 | anchors.fill: parent | 50 | anchors.fill: parent |
487 | @@ -35,11 +53,156 @@ | |||
488 | 35 | id: accountsLogin | 53 | id: accountsLogin |
489 | 36 | 54 | ||
490 | 37 | anchors.fill: parent | 55 | anchors.fill: parent |
491 | 56 | accountsModel: root.__accountsModel | ||
492 | 38 | 57 | ||
493 | 58 | onAccountSelected: { | ||
494 | 59 | if (accountId < 0) { | ||
495 | 60 | showErrorSheet() | ||
496 | 61 | } else { | ||
497 | 62 | root.__setupAccount(accountId) | ||
498 | 63 | } | ||
499 | 64 | } | ||
500 | 39 | onDone: { | 65 | onDone: { |
505 | 40 | if (!accountsPage.visible) | 66 | __loggingIn = false |
506 | 41 | return | 67 | if (successful && __account) { |
507 | 42 | accountsPage.done(credentialsId != null, credentialsId) | 68 | root.credentialsId = root.__account.authData.credentialsId |
508 | 43 | } | 69 | } |
509 | 70 | root.done(successful) | ||
510 | 71 | } | ||
511 | 72 | } | ||
512 | 73 | |||
513 | 74 | LogoutErrorSheet { | ||
514 | 75 | id: errorSheet | ||
515 | 76 | |||
516 | 77 | visible: false | ||
517 | 78 | |||
518 | 79 | onAccountLoginClicked: { | ||
519 | 80 | root.credentialsId = -1 | ||
520 | 81 | __loggedOutAccounts.push(__account.accountId) | ||
521 | 82 | root.login() | ||
522 | 83 | } | ||
523 | 84 | |||
524 | 85 | onManualLoginClicked: { | ||
525 | 86 | root.__ignoreLogout = true | ||
526 | 87 | root.visible = false | ||
527 | 88 | visible = false | ||
528 | 89 | } | ||
529 | 90 | } | ||
530 | 91 | |||
531 | 92 | LoggingInSheet { | ||
532 | 93 | visible: root.__loggingIn | ||
533 | 94 | } | ||
534 | 95 | |||
535 | 96 | Component { | ||
536 | 97 | id: accountChooserComponent | ||
537 | 98 | AccountChooserDialog { | ||
538 | 99 | id: accountChooser | ||
539 | 100 | providerId: root.providerId | ||
540 | 101 | applicationId: root.applicationId | ||
541 | 102 | accountsModel: root.__accountsModel | ||
542 | 103 | onCancel: PopupUtils.close(accountChooser) | ||
543 | 104 | onAccountSelected: { | ||
544 | 105 | PopupUtils.close(accountChooser) | ||
545 | 106 | root.__setupAccount(accountId) | ||
546 | 107 | } | ||
547 | 108 | } | ||
548 | 109 | } | ||
549 | 110 | |||
550 | 111 | LogoutDetector { | ||
551 | 112 | id: detector | ||
552 | 113 | onLogoutDetected: { | ||
553 | 114 | console.log("Logout detected") | ||
554 | 115 | if (!__ignoreLogout) { | ||
555 | 116 | root.visible = true | ||
556 | 117 | root.showErrorSheet() | ||
557 | 118 | } | ||
558 | 119 | } | ||
559 | 120 | } | ||
560 | 121 | |||
561 | 122 | ApplicationModel { | ||
562 | 123 | id: applicationModel | ||
563 | 124 | service: root.applicationId | ||
564 | 125 | } | ||
565 | 126 | |||
566 | 127 | ProviderModel { | ||
567 | 128 | id: providerModel | ||
568 | 129 | applicationId: root.applicationId | ||
569 | 130 | } | ||
570 | 131 | |||
571 | 132 | AccountServiceModel { | ||
572 | 133 | id: accountsModel | ||
573 | 134 | provider: root.providerId | ||
574 | 135 | applicationId: root.applicationId | ||
575 | 136 | } | ||
576 | 137 | |||
577 | 138 | Component { | ||
578 | 139 | id: accountComponent | ||
579 | 140 | AccountService { } | ||
580 | 141 | } | ||
581 | 142 | |||
582 | 143 | function __setupApplicationData() { | ||
583 | 144 | for (var i = 0; i < applicationModel.count; i++) { | ||
584 | 145 | if (applicationModel.get(i, "applicationId") === root.applicationId) { | ||
585 | 146 | var name = applicationModel.get(i, "displayName") | ||
586 | 147 | if (name) root.__applicationName = name | ||
587 | 148 | var icon = applicationModel.get(i, "iconName") | ||
588 | 149 | if (icon) root.__applicationIcon = icon | ||
589 | 150 | break | ||
590 | 151 | } | ||
591 | 152 | } | ||
592 | 153 | } | ||
593 | 154 | |||
594 | 155 | function __setupProviderData() { | ||
595 | 156 | for (var i = 0; i < providerModel.count; i++) { | ||
596 | 157 | if (providerModel.get(i, "providerId") === root.providerId) { | ||
597 | 158 | root.__providerName = providerModel.get(i, "displayName") | ||
598 | 159 | break | ||
599 | 160 | } | ||
600 | 161 | } | ||
601 | 162 | } | ||
602 | 163 | |||
603 | 164 | Component.onCompleted: { | ||
604 | 165 | __setupApplicationData() | ||
605 | 166 | __setupProviderData() | ||
606 | 167 | } | ||
607 | 168 | |||
608 | 169 | function __setupAccount(accountId) { | ||
609 | 170 | console.log("Setup account " + accountId) | ||
610 | 171 | if (__account && accountId === __account.accountId) { | ||
611 | 172 | console.log("Same as current account") | ||
612 | 173 | return | ||
613 | 174 | } | ||
614 | 175 | __account = null | ||
615 | 176 | for (var i = 0; i < accountsModel.count; i++) { | ||
616 | 177 | if (accountsModel.get(i, "accountId") === accountId) { | ||
617 | 178 | var accountHandle = accountsModel.get(i, "accountServiceHandle") | ||
618 | 179 | __account = accountComponent.createObject(root, { | ||
619 | 180 | objectHandle: accountHandle | ||
620 | 181 | }) | ||
621 | 182 | break; | ||
622 | 183 | } | ||
623 | 184 | } | ||
624 | 185 | credentialsId = __account ? __account.authData.credentialsId : 0 | ||
625 | 186 | console.log("Credentials ID: " + credentialsId) | ||
626 | 187 | } | ||
627 | 188 | |||
628 | 189 | function login() { | ||
629 | 190 | console.log("Logging in to " + __account) | ||
630 | 191 | __loggingIn = true | ||
631 | 192 | var forceCookieRefresh = false | ||
632 | 193 | var index = __loggedOutAccounts.indexOf(__account.accountId) | ||
633 | 194 | if (index >= 0) { | ||
634 | 195 | forceCookieRefresh = true | ||
635 | 196 | __loggedOutAccounts.splice(index, 1) | ||
636 | 197 | } | ||
637 | 198 | accountsLogin.login(__account, forceCookieRefresh) | ||
638 | 199 | } | ||
639 | 200 | |||
640 | 201 | function showErrorSheet() { | ||
641 | 202 | errorSheet.visible = true | ||
642 | 203 | } | ||
643 | 204 | |||
644 | 205 | function chooseAccount() { | ||
645 | 206 | PopupUtils.open(accountChooserComponent) | ||
646 | 44 | } | 207 | } |
647 | 45 | } | 208 | } |
648 | 46 | 209 | ||
649 | === modified file 'src/app/webcontainer/CMakeLists.txt' | |||
650 | --- src/app/webcontainer/CMakeLists.txt 2015-01-26 14:53:18 +0000 | |||
651 | +++ src/app/webcontainer/CMakeLists.txt 2015-04-16 14:53:15 +0000 | |||
652 | @@ -30,7 +30,7 @@ | |||
653 | 30 | install(TARGETS ${WEBAPP_CONTAINER} | 30 | install(TARGETS ${WEBAPP_CONTAINER} |
654 | 31 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) | 31 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) |
655 | 32 | 32 | ||
657 | 33 | file(GLOB QML_FILES *.qml) | 33 | file(GLOB QML_FILES *.qml *.js) |
658 | 34 | install(FILES ${QML_FILES} DESTINATION ${CMAKE_INSTALL_DATADIR}/webbrowser-app/webcontainer) | 34 | install(FILES ${QML_FILES} DESTINATION ${CMAKE_INSTALL_DATADIR}/webbrowser-app/webcontainer) |
659 | 35 | install(DIRECTORY actions DESTINATION ${CMAKE_INSTALL_DATADIR}/webbrowser-app/webcontainer | 35 | install(DIRECTORY actions DESTINATION ${CMAKE_INSTALL_DATADIR}/webbrowser-app/webcontainer |
660 | 36 | FILES_MATCHING PATTERN *.qml) | 36 | FILES_MATCHING PATTERN *.qml) |
661 | 37 | 37 | ||
662 | === added file 'src/app/webcontainer/LoggingInSheet.qml' | |||
663 | --- src/app/webcontainer/LoggingInSheet.qml 1970-01-01 00:00:00 +0000 | |||
664 | +++ src/app/webcontainer/LoggingInSheet.qml 2015-04-16 14:53:15 +0000 | |||
665 | @@ -0,0 +1,39 @@ | |||
666 | 1 | /* | ||
667 | 2 | * Copyright 2015 Canonical Ltd. | ||
668 | 3 | * | ||
669 | 4 | * This file is part of webbrowser-app. | ||
670 | 5 | * | ||
671 | 6 | * webbrowser-app is free software; you can redistribute it and/or modify | ||
672 | 7 | * it under the terms of the GNU General Public License as published by | ||
673 | 8 | * the Free Software Foundation; version 3. | ||
674 | 9 | * | ||
675 | 10 | * webbrowser-app is distributed in the hope that it will be useful, | ||
676 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
677 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
678 | 13 | * GNU General Public License for more details. | ||
679 | 14 | * | ||
680 | 15 | * You should have received a copy of the GNU General Public License | ||
681 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
682 | 17 | */ | ||
683 | 18 | |||
684 | 19 | import QtQuick 2.0 | ||
685 | 20 | import Ubuntu.Components 1.1 | ||
686 | 21 | |||
687 | 22 | Rectangle { | ||
688 | 23 | anchors.fill: parent | ||
689 | 24 | |||
690 | 25 | ActivityIndicator { | ||
691 | 26 | id: spinner | ||
692 | 27 | anchors.centerIn: parent | ||
693 | 28 | running: true | ||
694 | 29 | } | ||
695 | 30 | |||
696 | 31 | Label { | ||
697 | 32 | anchors.left: parent.left | ||
698 | 33 | anchors.right: parent.right | ||
699 | 34 | anchors.top: spinner.bottom | ||
700 | 35 | anchors.margins: units.gu(3) | ||
701 | 36 | text: i18n.tr("Automatic login with Ubuntu in progress…").arg(url) | ||
702 | 37 | wrapMode: Text.Wrap | ||
703 | 38 | } | ||
704 | 39 | } | ||
705 | 0 | 40 | ||
706 | === added file 'src/app/webcontainer/LogoutDetector.qml' | |||
707 | --- src/app/webcontainer/LogoutDetector.qml 1970-01-01 00:00:00 +0000 | |||
708 | +++ src/app/webcontainer/LogoutDetector.qml 2015-04-16 14:53:15 +0000 | |||
709 | @@ -0,0 +1,78 @@ | |||
710 | 1 | /* | ||
711 | 2 | * Copyright 2015 Canonical Ltd. | ||
712 | 3 | * | ||
713 | 4 | * This file is part of webbrowser-app. | ||
714 | 5 | * | ||
715 | 6 | * webbrowser-app is free software; you can redistribute it and/or modify | ||
716 | 7 | * it under the terms of the GNU General Public License as published by | ||
717 | 8 | * the Free Software Foundation; version 3. | ||
718 | 9 | * | ||
719 | 10 | * webbrowser-app is distributed in the hope that it will be useful, | ||
720 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
721 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
722 | 13 | * GNU General Public License for more details. | ||
723 | 14 | * | ||
724 | 15 | * You should have received a copy of the GNU General Public License | ||
725 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
726 | 17 | */ | ||
727 | 18 | |||
728 | 19 | import QtQuick 2.0 | ||
729 | 20 | import com.canonical.Oxide 1.0 | ||
730 | 21 | |||
731 | 22 | QtObject { | ||
732 | 23 | id: root | ||
733 | 24 | |||
734 | 25 | property var webview: null | ||
735 | 26 | property string logoutUrlPattern: "" | ||
736 | 27 | property string logoutSelectors: "" | ||
737 | 28 | |||
738 | 29 | signal logoutDetected() | ||
739 | 30 | |||
740 | 31 | property var __scriptMessageHandlerComponent: Component { | ||
741 | 32 | ScriptMessageHandler { | ||
742 | 33 | msgId: "domChanged" | ||
743 | 34 | contexts: ["oxide://logoutDetector/"] | ||
744 | 35 | callback: function(msg, frame) { | ||
745 | 36 | console.log('Got a DOM changed message: ' + msg.args) | ||
746 | 37 | var request = webview.rootFrame.sendMessage( | ||
747 | 38 | "oxide://logoutDetector/", | ||
748 | 39 | "evaluateSelectors", | ||
749 | 40 | { selectors: root.logoutSelectors } | ||
750 | 41 | ) | ||
751 | 42 | |||
752 | 43 | // NOTE: does not handle error | ||
753 | 44 | request.onreply = function(response) { | ||
754 | 45 | console.log('Selector result: ' + response.result) | ||
755 | 46 | if (response.result) { | ||
756 | 47 | root.logoutDetected() | ||
757 | 48 | } | ||
758 | 49 | } | ||
759 | 50 | } | ||
760 | 51 | } | ||
761 | 52 | } | ||
762 | 53 | |||
763 | 54 | property var __connections: Connections { | ||
764 | 55 | target: webview | ||
765 | 56 | onLoadEvent: { | ||
766 | 57 | console.log("Load event: " + event.url) | ||
767 | 58 | if (logoutUrlPattern.length !== 0 && event.url.toString().match(logoutUrlPattern)) { | ||
768 | 59 | root.logoutDetected() | ||
769 | 60 | } | ||
770 | 61 | } | ||
771 | 62 | } | ||
772 | 63 | |||
773 | 64 | property var __userScript: UserScript { | ||
774 | 65 | context: "oxide://logoutDetector/" | ||
775 | 66 | url: Qt.resolvedUrl("logout-detector.js") | ||
776 | 67 | incognitoEnabled: true | ||
777 | 68 | matchAllFrames: true | ||
778 | 69 | } | ||
779 | 70 | |||
780 | 71 | onWebviewChanged: { | ||
781 | 72 | if (!webview) return | ||
782 | 73 | console.log("Webview changed, adding script") | ||
783 | 74 | var handler = __scriptMessageHandlerComponent.createObject(null, {}) | ||
784 | 75 | webview.addMessageHandler(handler) | ||
785 | 76 | webview.context.addUserScript(__userScript) | ||
786 | 77 | } | ||
787 | 78 | } | ||
788 | 0 | 79 | ||
789 | === added file 'src/app/webcontainer/LogoutErrorSheet.qml' | |||
790 | --- src/app/webcontainer/LogoutErrorSheet.qml 1970-01-01 00:00:00 +0000 | |||
791 | +++ src/app/webcontainer/LogoutErrorSheet.qml 2015-04-16 14:53:15 +0000 | |||
792 | @@ -0,0 +1,64 @@ | |||
793 | 1 | /* | ||
794 | 2 | * Copyright 2015 Canonical Ltd. | ||
795 | 3 | * | ||
796 | 4 | * This file is part of webbrowser-app. | ||
797 | 5 | * | ||
798 | 6 | * webbrowser-app is free software; you can redistribute it and/or modify | ||
799 | 7 | * it under the terms of the GNU General Public License as published by | ||
800 | 8 | * the Free Software Foundation; version 3. | ||
801 | 9 | * | ||
802 | 10 | * webbrowser-app is distributed in the hope that it will be useful, | ||
803 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
804 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
805 | 13 | * GNU General Public License for more details. | ||
806 | 14 | * | ||
807 | 15 | * You should have received a copy of the GNU General Public License | ||
808 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
809 | 17 | */ | ||
810 | 18 | |||
811 | 19 | import QtQuick 2.0 | ||
812 | 20 | import Ubuntu.Components 1.1 | ||
813 | 21 | |||
814 | 22 | Rectangle { | ||
815 | 23 | signal accountLoginClicked() | ||
816 | 24 | signal manualLoginClicked() | ||
817 | 25 | |||
818 | 26 | anchors.fill: parent | ||
819 | 27 | |||
820 | 28 | Column { | ||
821 | 29 | anchors.fill: parent | ||
822 | 30 | anchors.margins: units.gu(4) | ||
823 | 31 | |||
824 | 32 | spacing: units.gu(3) | ||
825 | 33 | |||
826 | 34 | Label { | ||
827 | 35 | width: parent.width | ||
828 | 36 | fontSize: "x-large" | ||
829 | 37 | text: i18n.tr("Logged out") | ||
830 | 38 | } | ||
831 | 39 | |||
832 | 40 | Label { | ||
833 | 41 | width: parent.width | ||
834 | 42 | text: i18n.tr("It appears that you have been logged out.").arg(url) | ||
835 | 43 | wrapMode: Text.Wrap | ||
836 | 44 | } | ||
837 | 45 | |||
838 | 46 | Label { | ||
839 | 47 | width: parent.width | ||
840 | 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.") | ||
841 | 49 | wrapMode: Text.Wrap | ||
842 | 50 | } | ||
843 | 51 | |||
844 | 52 | Button { | ||
845 | 53 | anchors.horizontalCenter: parent.horizontalCenter | ||
846 | 54 | text: i18n.tr("Login with Ubuntu") | ||
847 | 55 | onClicked: accountLoginClicked() | ||
848 | 56 | } | ||
849 | 57 | |||
850 | 58 | Button { | ||
851 | 59 | anchors.horizontalCenter: parent.horizontalCenter | ||
852 | 60 | text: i18n.tr("Continue anyway") | ||
853 | 61 | onClicked: manualLoginClicked() | ||
854 | 62 | } | ||
855 | 63 | } | ||
856 | 64 | } | ||
857 | 0 | 65 | ||
858 | === added file 'src/app/webcontainer/SplashScreen.qml' | |||
859 | --- src/app/webcontainer/SplashScreen.qml 1970-01-01 00:00:00 +0000 | |||
860 | +++ src/app/webcontainer/SplashScreen.qml 2015-04-16 14:53:15 +0000 | |||
861 | @@ -0,0 +1,105 @@ | |||
862 | 1 | /* | ||
863 | 2 | * Copyright 2013-2014 Canonical Ltd. | ||
864 | 3 | * | ||
865 | 4 | * This file is part of webbrowser-app. | ||
866 | 5 | * | ||
867 | 6 | * webbrowser-app is free software; you can redistribute it and/or modify | ||
868 | 7 | * it under the terms of the GNU General Public License as published by | ||
869 | 8 | * the Free Software Foundation; version 3. | ||
870 | 9 | * | ||
871 | 10 | * webbrowser-app is distributed in the hope that it will be useful, | ||
872 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
873 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
874 | 13 | * GNU General Public License for more details. | ||
875 | 14 | * | ||
876 | 15 | * You should have received a copy of the GNU General Public License | ||
877 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
878 | 17 | */ | ||
879 | 18 | |||
880 | 19 | import QtQuick 2.0 | ||
881 | 20 | import Ubuntu.Components 1.1 | ||
882 | 21 | import Ubuntu.OnlineAccounts 0.1 | ||
883 | 22 | |||
884 | 23 | Item { | ||
885 | 24 | id: root | ||
886 | 25 | |||
887 | 26 | property string providerName | ||
888 | 27 | property string applicationName | ||
889 | 28 | property alias iconSource: icon.source | ||
890 | 29 | property bool accountMandatory: true | ||
891 | 30 | |||
892 | 31 | signal chooseAccount() | ||
893 | 32 | signal skip() | ||
894 | 33 | |||
895 | 34 | anchors.fill: parent | ||
896 | 35 | |||
897 | 36 | Column { | ||
898 | 37 | anchors { | ||
899 | 38 | left: parent.left | ||
900 | 39 | right: parent.right | ||
901 | 40 | verticalCenter: parent.verticalCenter | ||
902 | 41 | } | ||
903 | 42 | spacing: units.gu(2) | ||
904 | 43 | |||
905 | 44 | Icon { | ||
906 | 45 | id: icon | ||
907 | 46 | anchors.horizontalCenter: parent.horizontalCenter | ||
908 | 47 | width: units.gu(10) | ||
909 | 48 | height: width | ||
910 | 49 | } | ||
911 | 50 | |||
912 | 51 | Label { | ||
913 | 52 | anchors.horizontalCenter: parent.horizontalCenter | ||
914 | 53 | fontSize: "x-large" | ||
915 | 54 | text: root.applicationName | ||
916 | 55 | } | ||
917 | 56 | |||
918 | 57 | Label { | ||
919 | 58 | anchors.left: parent.left | ||
920 | 59 | anchors.right: parent.right | ||
921 | 60 | horizontalAlignment: Text.AlignHCenter | ||
922 | 61 | wrapMode: Text.WordWrap | ||
923 | 62 | text: i18n.tr("<b>%1</b> needs to access your %2 online account.").arg(root.applicationName).arg(root.providerName) | ||
924 | 63 | visible: root.accountMandatory | ||
925 | 64 | } | ||
926 | 65 | |||
927 | 66 | Label { | ||
928 | 67 | anchors.left: parent.left | ||
929 | 68 | anchors.right: parent.right | ||
930 | 69 | horizontalAlignment: Text.AlignHCenter | ||
931 | 70 | wrapMode: Text.WordWrap | ||
932 | 71 | text: i18n.tr("<b>%1</b> would like to access your %2 online account.").arg(root.applicationName).arg(root.providerName) | ||
933 | 72 | visible: !root.accountMandatory | ||
934 | 73 | } | ||
935 | 74 | |||
936 | 75 | Label { | ||
937 | 76 | anchors.left: parent.left | ||
938 | 77 | anchors.right: parent.right | ||
939 | 78 | horizontalAlignment: Text.AlignHCenter | ||
940 | 79 | wrapMode: Text.WordWrap | ||
941 | 80 | text: i18n.tr("Choose an account now, or skip this step and choose an online account later.") | ||
942 | 81 | visible: !root.accountMandatory | ||
943 | 82 | } | ||
944 | 83 | |||
945 | 84 | Item { | ||
946 | 85 | anchors.left: parent.left | ||
947 | 86 | anchors.right: parent.right | ||
948 | 87 | anchors.margins: units.gu(1) | ||
949 | 88 | height: units.gu(6) | ||
950 | 89 | |||
951 | 90 | Button { | ||
952 | 91 | anchors.left: parent.left | ||
953 | 92 | width: parent.width / 2 - units.gu(1) | ||
954 | 93 | text: root.accountMandatory ? i18n.tr("Close the app") : i18n.tr("Skip") | ||
955 | 94 | onClicked: root.accountMandatory ? Qt.quit() : root.skip() | ||
956 | 95 | } | ||
957 | 96 | |||
958 | 97 | Button { | ||
959 | 98 | anchors.right: parent.right | ||
960 | 99 | width: parent.width / 2 - units.gu(1) | ||
961 | 100 | text: i18n.tr("Choose account") | ||
962 | 101 | onClicked: root.chooseAccount() | ||
963 | 102 | } | ||
964 | 103 | } | ||
965 | 104 | } | ||
966 | 105 | } | ||
967 | 0 | 106 | ||
968 | === modified file 'src/app/webcontainer/WebApp.qml' | |||
969 | --- src/app/webcontainer/WebApp.qml 2015-04-08 13:20:57 +0000 | |||
970 | +++ src/app/webcontainer/WebApp.qml 2015-04-16 14:53:15 +0000 | |||
971 | @@ -46,6 +46,8 @@ | |||
972 | 46 | property bool chromeVisible: false | 46 | property bool chromeVisible: false |
973 | 47 | readonly property bool chromeless: !chromeVisible && !backForwardButtonsVisible | 47 | readonly property bool chromeless: !chromeVisible && !backForwardButtonsVisible |
974 | 48 | 48 | ||
975 | 49 | signal chooseAccount() | ||
976 | 50 | |||
977 | 49 | actions: [ | 51 | actions: [ |
978 | 50 | Actions.Back { | 52 | Actions.Back { |
979 | 51 | enabled: webapp.backForwardButtonsVisible && webview.currentWebview && webview.currentWebview.canGoBack | 53 | enabled: webapp.backForwardButtonsVisible && webview.currentWebview && webview.currentWebview.canGoBack |
980 | 52 | 54 | ||
981 | === modified file 'src/app/webcontainer/cookie-store.cpp' | |||
982 | --- src/app/webcontainer/cookie-store.cpp 2014-10-08 14:16:14 +0000 | |||
983 | +++ src/app/webcontainer/cookie-store.cpp 2015-04-16 14:53:15 +0000 | |||
984 | @@ -51,6 +51,7 @@ | |||
985 | 51 | QObject(parent) | 51 | QObject(parent) |
986 | 52 | { | 52 | { |
987 | 53 | qRegisterMetaType<QNetworkCookie>(); | 53 | qRegisterMetaType<QNetworkCookie>(); |
988 | 54 | qRegisterMetaType<QList<QNetworkCookie> >("QList<QNetworkCookie>"); | ||
989 | 54 | qRegisterMetaType<Cookies>("Cookies"); | 55 | qRegisterMetaType<Cookies>("Cookies"); |
990 | 55 | } | 56 | } |
991 | 56 | 57 | ||
992 | 57 | 58 | ||
993 | === added file 'src/app/webcontainer/logout-detector.js' | |||
994 | --- src/app/webcontainer/logout-detector.js 1970-01-01 00:00:00 +0000 | |||
995 | +++ src/app/webcontainer/logout-detector.js 2015-04-16 14:53:15 +0000 | |||
996 | @@ -0,0 +1,41 @@ | |||
997 | 1 | /* | ||
998 | 2 | * Copyright 2015 Canonical Ltd. | ||
999 | 3 | * | ||
1000 | 4 | * This file is part of webbrowser-app. | ||
1001 | 5 | * | ||
1002 | 6 | * webbrowser-app is free software; you can redistribute it and/or modify | ||
1003 | 7 | * it under the terms of the GNU General Public License as published by | ||
1004 | 8 | * the Free Software Foundation; version 3. | ||
1005 | 9 | * | ||
1006 | 10 | * webbrowser-app is distributed in the hope that it will be useful, | ||
1007 | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1008 | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1009 | 13 | * GNU General Public License for more details. | ||
1010 | 14 | * | ||
1011 | 15 | * You should have received a copy of the GNU General Public License | ||
1012 | 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1013 | 17 | */ | ||
1014 | 18 | |||
1015 | 19 | oxide.sendMessage('domChanged', 'Some message'); | ||
1016 | 20 | |||
1017 | 21 | var MutationObserver = window.MutationObserver || window.WebKitMutationObserver; | ||
1018 | 22 | |||
1019 | 23 | var observer = new MutationObserver(function(mutations) { | ||
1020 | 24 | var addnodes = [] | ||
1021 | 25 | mutations.forEach(function(mutation) { | ||
1022 | 26 | for (var i in mutation.addedNodes) { | ||
1023 | 27 | addnodes.push(mutation.addedNodes[i].className) | ||
1024 | 28 | } | ||
1025 | 29 | }); | ||
1026 | 30 | |||
1027 | 31 | oxide.sendMessage('domChanged', JSON.stringify(addnodes)) | ||
1028 | 32 | }); | ||
1029 | 33 | observer.observe(document.body, {childList: true, subtree: true }); | ||
1030 | 34 | |||
1031 | 35 | |||
1032 | 36 | oxide.addMessageHandler("evaluateSelectors", function(msg) { | ||
1033 | 37 | var selectors = msg.args.selectors; | ||
1034 | 38 | console.log("Evaluating selectors: " + selectors); | ||
1035 | 39 | var match = document.querySelector(selectors); | ||
1036 | 40 | msg.reply({result: (match !== null)}); | ||
1037 | 41 | }); | ||
1038 | 0 | 42 | ||
1039 | === modified file 'src/app/webcontainer/webapp-container.cpp' | |||
1040 | --- src/app/webcontainer/webapp-container.cpp 2015-04-10 13:33:19 +0000 | |||
1041 | +++ src/app/webcontainer/webapp-container.cpp 2015-04-16 14:53:15 +0000 | |||
1042 | @@ -116,9 +116,17 @@ | |||
1043 | 116 | } | 116 | } |
1044 | 117 | 117 | ||
1045 | 118 | m_window->setProperty("webappName", m_webappName); | 118 | m_window->setProperty("webappName", m_webappName); |
1046 | 119 | QFileInfo iconInfo(m_webappIcon); | ||
1047 | 120 | QUrl iconUrl; | ||
1048 | 121 | if (iconInfo.isReadable()) { | ||
1049 | 122 | iconUrl = QUrl::fromLocalFile(iconInfo.absoluteFilePath()); | ||
1050 | 123 | } | ||
1051 | 124 | m_window->setProperty("webappIcon", iconUrl); | ||
1052 | 119 | m_window->setProperty("backForwardButtonsVisible", m_backForwardButtonsVisible); | 125 | m_window->setProperty("backForwardButtonsVisible", m_backForwardButtonsVisible); |
1053 | 120 | m_window->setProperty("chromeVisible", m_addressBarVisible); | 126 | m_window->setProperty("chromeVisible", m_addressBarVisible); |
1054 | 121 | m_window->setProperty("accountProvider", m_accountProvider); | 127 | m_window->setProperty("accountProvider", m_accountProvider); |
1055 | 128 | m_window->setProperty("logoutUrlPattern", m_logoutUrlPattern); | ||
1056 | 129 | m_window->setProperty("logoutSelectors", m_logoutSelectors); | ||
1057 | 122 | 130 | ||
1058 | 123 | m_window->setProperty("webappUrlPatterns", m_webappUrlPatterns); | 131 | m_window->setProperty("webappUrlPatterns", m_webappUrlPatterns); |
1059 | 124 | QQmlContext* context = m_engine->rootContext(); | 132 | QQmlContext* context = m_engine->rootContext(); |
1060 | @@ -251,9 +259,13 @@ | |||
1061 | 251 | " [--app-id=APP_ID]" | 259 | " [--app-id=APP_ID]" |
1062 | 252 | " [--homepage=URL]" | 260 | " [--homepage=URL]" |
1063 | 253 | " [--webapp=name]" | 261 | " [--webapp=name]" |
1064 | 262 | " [--name=NAME]" | ||
1065 | 263 | " [--icon=PATH]" | ||
1066 | 254 | " [--webappModelSearchPath=PATH]" | 264 | " [--webappModelSearchPath=PATH]" |
1067 | 255 | " [--webappUrlPatterns=URL_PATTERNS]" | 265 | " [--webappUrlPatterns=URL_PATTERNS]" |
1068 | 256 | " [--accountProvider=PROVIDER_NAME]" | 266 | " [--accountProvider=PROVIDER_NAME]" |
1069 | 267 | " [--logoutUrlPattern=URL_PATTERN]" | ||
1070 | 268 | " [--logoutSelectors=selector1,selector2,...]" | ||
1071 | 257 | " [--enable-back-forward]" | 269 | " [--enable-back-forward]" |
1072 | 258 | " [--enable-addressbar]" | 270 | " [--enable-addressbar]" |
1073 | 259 | " [--store-session-cookies]" | 271 | " [--store-session-cookies]" |
1074 | @@ -268,9 +280,13 @@ | |||
1075 | 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; |
1076 | 269 | out << " --homepage=URL override any URL passed as an argument" << endl; | 281 | out << " --homepage=URL override any URL passed as an argument" << endl; |
1077 | 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; |
1078 | 283 | out << " --name=NAME display name of the webapp, shown in the splash screen" << endl; | ||
1079 | 284 | out << " --icon=PATH Icon to be shown in the splash screen. PATH can be an absolute or path relative to CWD" << endl; | ||
1080 | 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; |
1081 | 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; |
1082 | 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; |
1083 | 288 | out << " --logoutUrlPattern=PATTERN Regexp pattern for detecting logout URLs." << endl; | ||
1084 | 289 | out << " --logoutSelectors=SELECTORS Comma separated list of CSS selectors to detect the logout situation." << endl; | ||
1085 | 274 | out << " --store-session-cookies store session cookies on disk" << endl; | 290 | out << " --store-session-cookies store session cookies on disk" << endl; |
1086 | 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; |
1087 | 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; |
1088 | @@ -298,6 +314,10 @@ | |||
1089 | 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…). |
1090 | 299 | QString name = argument.split("--webapp=")[1]; | 315 | QString name = argument.split("--webapp=")[1]; |
1091 | 300 | m_webappName = QByteArray::fromBase64(name.toUtf8()).trimmed(); | 316 | m_webappName = QByteArray::fromBase64(name.toUtf8()).trimmed(); |
1092 | 317 | } else if (argument.startsWith("--name=")) { | ||
1093 | 318 | m_webappName = argument.split("--name=")[1]; | ||
1094 | 319 | } else if (argument.startsWith("--icon=")) { | ||
1095 | 320 | m_webappIcon = argument.split("--icon=")[1]; | ||
1096 | 301 | } else if (argument.startsWith("--webappUrlPatterns=")) { | 321 | } else if (argument.startsWith("--webappUrlPatterns=")) { |
1097 | 302 | QString tail = argument.split("--webappUrlPatterns=")[1]; | 322 | QString tail = argument.split("--webappUrlPatterns=")[1]; |
1098 | 303 | if (!tail.isEmpty()) { | 323 | if (!tail.isEmpty()) { |
1099 | @@ -306,6 +326,10 @@ | |||
1100 | 306 | } | 326 | } |
1101 | 307 | } else if (argument.startsWith("--accountProvider=")) { | 327 | } else if (argument.startsWith("--accountProvider=")) { |
1102 | 308 | m_accountProvider = argument.split("--accountProvider=")[1]; | 328 | m_accountProvider = argument.split("--accountProvider=")[1]; |
1103 | 329 | } else if (argument.startsWith("--logoutUrlPattern=")) { | ||
1104 | 330 | m_logoutUrlPattern = argument.split("--logoutUrlPattern=")[1]; | ||
1105 | 331 | } else if (argument.startsWith("--logoutSelectors=")) { | ||
1106 | 332 | m_logoutSelectors = argument.split("--logoutSelectors=")[1]; | ||
1107 | 309 | } else if (argument == "--clear-cookies") { | 333 | } else if (argument == "--clear-cookies") { |
1108 | 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; |
1109 | 311 | clearCookiesHack(m_accountProvider); | 335 | clearCookiesHack(m_accountProvider); |
1110 | 312 | 336 | ||
1111 | === modified file 'src/app/webcontainer/webapp-container.h' | |||
1112 | --- src/app/webcontainer/webapp-container.h 2015-04-10 13:33:19 +0000 | |||
1113 | +++ src/app/webcontainer/webapp-container.h 2015-04-16 14:53:15 +0000 | |||
1114 | @@ -58,9 +58,12 @@ | |||
1115 | 58 | 58 | ||
1116 | 59 | private: | 59 | private: |
1117 | 60 | QString m_webappName; | 60 | QString m_webappName; |
1118 | 61 | QString m_webappIcon; | ||
1119 | 61 | QString m_webappModelSearchPath; | 62 | QString m_webappModelSearchPath; |
1120 | 62 | QStringList m_webappUrlPatterns; | 63 | QStringList m_webappUrlPatterns; |
1121 | 63 | QString m_accountProvider; | 64 | QString m_accountProvider; |
1122 | 65 | QString m_logoutUrlPattern; | ||
1123 | 66 | QString m_logoutSelectors; | ||
1124 | 64 | bool m_storeSessionCookies; | 67 | bool m_storeSessionCookies; |
1125 | 65 | bool m_backForwardButtonsVisible; | 68 | bool m_backForwardButtonsVisible; |
1126 | 66 | bool m_addressBarVisible; | 69 | bool m_addressBarVisible; |
1127 | 67 | 70 | ||
1128 | === modified file 'src/app/webcontainer/webapp-container.qml' | |||
1129 | --- src/app/webcontainer/webapp-container.qml 2015-04-07 14:30:52 +0000 | |||
1130 | +++ src/app/webcontainer/webapp-container.qml 2015-04-16 14:53:15 +0000 | |||
1131 | @@ -34,10 +34,13 @@ | |||
1132 | 34 | 34 | ||
1133 | 35 | property var intentFilterHandler | 35 | property var intentFilterHandler |
1134 | 36 | property string url: "" | 36 | property string url: "" |
1135 | 37 | property string webappIcon: "" | ||
1136 | 37 | property string webappName: "" | 38 | property string webappName: "" |
1137 | 38 | property string webappModelSearchPath: "" | 39 | property string webappModelSearchPath: "" |
1138 | 39 | property var webappUrlPatterns | 40 | property var webappUrlPatterns |
1139 | 40 | property string accountProvider: "" | 41 | property string accountProvider: "" |
1140 | 42 | property string logoutUrlPattern: "" | ||
1141 | 43 | property string logoutSelectors: "" | ||
1142 | 41 | property string popupRedirectionUrlPrefixPattern: "" | 44 | property string popupRedirectionUrlPrefixPattern: "" |
1143 | 42 | property url webviewOverrideFile: "" | 45 | property url webviewOverrideFile: "" |
1144 | 43 | property var __webappCookieStore: null | 46 | property var __webappCookieStore: null |
1145 | @@ -50,6 +53,10 @@ | |||
1146 | 50 | 53 | ||
1147 | 51 | title: getWindowTitle() | 54 | title: getWindowTitle() |
1148 | 52 | 55 | ||
1149 | 56 | onCurrentWebviewChanged: if (accountsPageComponentLoader.item) { | ||
1150 | 57 | accountsPageComponentLoader.item.webview = currentWebview | ||
1151 | 58 | } | ||
1152 | 59 | |||
1153 | 53 | // Used for testing | 60 | // Used for testing |
1154 | 54 | signal intentUriHandleResult(string uri) | 61 | signal intentUriHandleResult(string uri) |
1155 | 55 | 62 | ||
1156 | @@ -102,6 +109,8 @@ | |||
1157 | 102 | root.title = getWindowTitle(); | 109 | root.title = getWindowTitle(); |
1158 | 103 | } | 110 | } |
1159 | 104 | } | 111 | } |
1160 | 112 | |||
1161 | 113 | onChooseAccount: accountsPageComponentLoader.item.chooseAccount() | ||
1162 | 105 | } | 114 | } |
1163 | 106 | } | 115 | } |
1164 | 107 | 116 | ||
1165 | @@ -158,13 +167,15 @@ | |||
1166 | 158 | Loader { | 167 | Loader { |
1167 | 159 | id: accountsPageComponentLoader | 168 | id: accountsPageComponentLoader |
1168 | 160 | anchors.fill: parent | 169 | anchors.fill: parent |
1169 | 170 | z: -1 // This is needed to have the dialogs shown; see above comment about bug 1398046 | ||
1170 | 161 | onStatusChanged: { | 171 | onStatusChanged: { |
1171 | 162 | if (status == Loader.Error) { | 172 | if (status == Loader.Error) { |
1172 | 163 | // Happens on the desktop, if Ubuntu.OnlineAccounts.Client | 173 | // Happens on the desktop, if Ubuntu.OnlineAccounts.Client |
1173 | 164 | // can't be imported | 174 | // can't be imported |
1175 | 165 | loadWebAppView() | 175 | loadWebAppView(true) |
1176 | 166 | } else if (status == Loader.Ready) { | 176 | } else if (status == Loader.Ready) { |
1177 | 167 | item.visible = true | 177 | item.visible = true |
1178 | 178 | initializeForAccount(item.credentialsId) | ||
1179 | 168 | } | 179 | } |
1180 | 169 | } | 180 | } |
1181 | 170 | } | 181 | } |
1182 | @@ -175,48 +186,82 @@ | |||
1183 | 175 | } | 186 | } |
1184 | 176 | if (!result) { | 187 | if (!result) { |
1185 | 177 | console.log("Cookies were not moved") | 188 | console.log("Cookies were not moved") |
1186 | 189 | } else { | ||
1187 | 190 | console.log("cookies moved") | ||
1188 | 178 | } | 191 | } |
1189 | 179 | webappViewLoader.item.url = root.url | 192 | webappViewLoader.item.url = root.url |
1190 | 180 | } | 193 | } |
1191 | 181 | 194 | ||
1192 | 182 | function moveCookies(credentialsId) { | 195 | function moveCookies(credentialsId) { |
1193 | 196 | console.log("moving cookies for id " + credentialsId) | ||
1194 | 197 | var storeComponent = localCookieStoreDbPath.length !== 0 ? | ||
1195 | 198 | localCookieStoreComponent : onlineAccountStoreComponent | ||
1196 | 199 | |||
1197 | 200 | var instance = storeComponent.createObject(root, { "accountId": credentialsId }) | ||
1198 | 201 | __webappCookieStore.moved.connect(onCookiesMoved) | ||
1199 | 202 | __webappCookieStore.moveFrom(instance) | ||
1200 | 203 | } | ||
1201 | 204 | |||
1202 | 205 | function doLogin() { | ||
1203 | 183 | if (!__webappCookieStore) { | 206 | if (!__webappCookieStore) { |
1204 | 184 | var context = webappViewLoader.item.currentWebview.context | 207 | var context = webappViewLoader.item.currentWebview.context |
1206 | 185 | __webappCookieStore = oxideCookieStoreComponent.createObject(this, { | 208 | __webappCookieStore = oxideCookieStoreComponent.createObject(webappViewLoader.item, { |
1207 | 186 | "oxideStoreBackend": context.cookieManager, | 209 | "oxideStoreBackend": context.cookieManager, |
1208 | 187 | "dbPath": context.dataPath + "/cookies.sqlite" | 210 | "dbPath": context.dataPath + "/cookies.sqlite" |
1209 | 188 | }) | 211 | }) |
1210 | 189 | } | 212 | } |
1211 | 190 | 213 | ||
1218 | 191 | var storeComponent = localCookieStoreDbPath.length !== 0 ? | 214 | accountsPageComponentLoader.item.login() |
1219 | 192 | localCookieStoreComponent : onlineAccountStoreComponent | 215 | } |
1220 | 193 | 216 | ||
1221 | 194 | var instance = storeComponent.createObject(root, { "accountId": credentialsId }) | 217 | function initializeForAccount(credentialsId) { |
1222 | 195 | __webappCookieStore.moved.connect(onCookiesMoved) | 218 | console.log("Account selected, creds: " + credentialsId) |
1223 | 196 | __webappCookieStore.moveFrom(instance) | 219 | if (credentialsId < 0) { |
1224 | 220 | webappViewLoader.sourceComponent = null | ||
1225 | 221 | __webappCookieStore = null | ||
1226 | 222 | webappViewLoader.credentialsId = credentialsId | ||
1227 | 223 | return | ||
1228 | 224 | } | ||
1229 | 225 | |||
1230 | 226 | if (credentialsId > 0) { | ||
1231 | 227 | if (credentialsId == webappViewLoader.credentialsId) { | ||
1232 | 228 | doLogin() | ||
1233 | 229 | return | ||
1234 | 230 | } | ||
1235 | 231 | |||
1236 | 232 | webappViewLoader.sourceComponent = null | ||
1237 | 233 | __webappCookieStore = null | ||
1238 | 234 | webappViewLoader.loaded.connect(function onLoaded() { | ||
1239 | 235 | if (webappViewLoader.status == Loader.Ready) { | ||
1240 | 236 | webappViewLoader.loaded.disconnect(onLoaded) | ||
1241 | 237 | doLogin() | ||
1242 | 238 | } | ||
1243 | 239 | }); | ||
1244 | 240 | webappViewLoader.credentialsId = credentialsId | ||
1245 | 241 | // If we need to preserve session cookies, make sure that the | ||
1246 | 242 | // mode is "restored" and not "persistent", or the cookies | ||
1247 | 243 | // transferred from OA would be lost. | ||
1248 | 244 | // We check if the webContextSessionCookieMode is defined and, if so, | ||
1249 | 245 | // we override it in the webapp loader. | ||
1250 | 246 | if (typeof webContextSessionCookieMode === "string") { | ||
1251 | 247 | webappViewLoader.webContextSessionCookieMode = "restored" | ||
1252 | 248 | } | ||
1253 | 249 | } | ||
1254 | 250 | |||
1255 | 251 | loadWebAppView(credentialsId == 0) | ||
1256 | 197 | } | 252 | } |
1257 | 198 | 253 | ||
1258 | 199 | Connections { | 254 | Connections { |
1259 | 200 | target: accountsPageComponentLoader.item | 255 | target: accountsPageComponentLoader.item |
1260 | 256 | onCredentialsIdChanged: initializeForAccount(accountsPageComponentLoader.item.credentialsId) | ||
1261 | 257 | onVisibleChanged: webappViewLoader.item.visible = !accountsPageComponentLoader.item.visible | ||
1262 | 201 | onDone: { | 258 | onDone: { |
1263 | 259 | console.log("Authentication done, successful = " + successful) | ||
1264 | 202 | if (successful) { | 260 | if (successful) { |
1279 | 203 | webappViewLoader.loaded.connect(function () { | 261 | moveCookies(webappViewLoader.credentialsId) |
1280 | 204 | if (webappViewLoader.status == Loader.Ready) { | 262 | } else { |
1281 | 205 | moveCookies(webappViewLoader.credentialsId) | 263 | loadWebAppView(true) |
1268 | 206 | } | ||
1269 | 207 | }); | ||
1270 | 208 | webappViewLoader.credentialsId = credentialsId | ||
1271 | 209 | // If we need to preserve session cookies, make sure that the | ||
1272 | 210 | // mode is "restored" and not "persistent", or the cookies | ||
1273 | 211 | // transferred from OA would be lost. | ||
1274 | 212 | // We check if the webContextSessionCookieMode is defined and, if so, | ||
1275 | 213 | // we override it in the webapp loader. | ||
1276 | 214 | if (typeof webContextSessionCookieMode === "string") { | ||
1277 | 215 | webappViewLoader.webContextSessionCookieMode = "restored" | ||
1278 | 216 | } | ||
1282 | 217 | } | 264 | } |
1283 | 218 | |||
1284 | 219 | loadWebAppView() | ||
1285 | 220 | } | 265 | } |
1286 | 221 | } | 266 | } |
1287 | 222 | 267 | ||
1288 | @@ -241,7 +286,7 @@ | |||
1289 | 241 | if (accountProvider.length !== 0) { | 286 | if (accountProvider.length !== 0) { |
1290 | 242 | loadLoginView(); | 287 | loadLoginView(); |
1291 | 243 | } else { | 288 | } else { |
1293 | 244 | loadWebAppView(); | 289 | loadWebAppView(true); |
1294 | 245 | } | 290 | } |
1295 | 246 | } | 291 | } |
1296 | 247 | 292 | ||
1297 | @@ -252,27 +297,34 @@ | |||
1298 | 252 | 297 | ||
1299 | 253 | function loadLoginView() { | 298 | function loadLoginView() { |
1300 | 254 | accountsPageComponentLoader.setSource("AccountsPage.qml", { | 299 | accountsPageComponentLoader.setSource("AccountsPage.qml", { |
1303 | 255 | "accountProvider": accountProvider, | 300 | "providerId": accountProvider, |
1304 | 256 | "applicationName": unversionedAppId, | 301 | "applicationId": unversionedAppId, |
1305 | 302 | "webappName": getWebappName(), | ||
1306 | 303 | "webappIcon": webappIcon, | ||
1307 | 304 | "logoutUrlPattern": logoutUrlPattern, | ||
1308 | 305 | "logoutSelectors": logoutSelectors, | ||
1309 | 257 | }) | 306 | }) |
1310 | 258 | } | 307 | } |
1311 | 259 | 308 | ||
1313 | 260 | function loadWebAppView() { | 309 | function loadWebAppView(startBrowsing) { |
1314 | 261 | if (accountsPageComponentLoader.item) | 310 | if (accountsPageComponentLoader.item) |
1315 | 262 | accountsPageComponentLoader.item.visible = false | 311 | accountsPageComponentLoader.item.visible = false |
1316 | 263 | 312 | ||
1326 | 264 | webappViewLoader.loaded.connect(function () { | 313 | if (startBrowsing) { |
1327 | 265 | if (webappViewLoader.status === Loader.Ready) { | 314 | webappViewLoader.loaded.connect(function onLoaded() { |
1328 | 266 | // As we use StateSaver to restore the URL, we need to check first if | 315 | if (webappViewLoader.status === Loader.Ready) { |
1329 | 267 | // it has not been set previously before setting the URL to the default property | 316 | webappViewLoader.loaded.disconnect(onLoaded) |
1330 | 268 | // homepage. | 317 | // As we use StateSaver to restore the URL, we need to check first if |
1331 | 269 | var webView = webappViewLoader.item.currentWebview | 318 | // it has not been set previously before setting the URL to the default property |
1332 | 270 | var current_url = webView.url.toString(); | 319 | // homepage. |
1333 | 271 | if (!current_url || current_url.length === 0) { | 320 | var webView = webappViewLoader.item.currentWebview |
1334 | 272 | webView.url = root.url | 321 | var current_url = webView.url.toString(); |
1335 | 322 | if (!current_url || current_url.length === 0) { | ||
1336 | 323 | webView.url = root.url | ||
1337 | 324 | } | ||
1338 | 273 | } | 325 | } |
1341 | 274 | } | 326 | }); |
1342 | 275 | }); | 327 | } |
1343 | 276 | webappViewLoader.sourceComponent = webappViewComponent | 328 | webappViewLoader.sourceComponent = webappViewComponent |
1344 | 277 | } | 329 | } |
1345 | 278 | 330 |
FAILED: Continuous integration, rev:973 jenkins. qa.ubuntu. com/job/ webbrowser- app-ci/ 1632/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 2195 jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- amd64-ci/ 390 jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- armhf-ci/ 390 jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- armhf-ci/ 390/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- i386-ci/ 390 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- vivid-mako/ 1928 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 2193 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 2193/artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 19567
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/webbrowser- app-ci/ 1632/rebuild
http://