Merge lp:~osomon/webbrowser-app/save-restore-state into lp:webbrowser-app
- save-restore-state
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Olivier Tilloy | ||||
Approved revision: | 834 | ||||
Merged at revision: | 886 | ||||
Proposed branch: | lp:~osomon/webbrowser-app/save-restore-state | ||||
Merge into: | lp:webbrowser-app | ||||
Diff against target: |
242 lines (+45/-70) 5 files modified
debian/control (+2/-2) src/app/webbrowser/Browser.qml (+27/-16) src/app/webbrowser/BrowserTab.qml (+13/-1) tests/autopilot/webbrowser_app/tests/test_session_save_restore.py (+0/-51) tests/unittests/qml/tst_BrowserTab.qml (+3/-0) |
||||
To merge this branch: | bzr merge lp:~osomon/webbrowser-app/save-restore-state | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Vogt (community) | Approve | ||
PS Jenkins bot | continuous-integration | Needs Fixing | |
Review via email: mp+242678@code.launchpad.net |
Commit message
Use the new restoreState API in oxide 1.4 to properly save and restore navigation state across sessions.
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
- 826. By Olivier Tilloy
-
Merge the latest changes from trunk,
and resolve a conflict.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:826
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 827. By Olivier Tilloy
-
Merge the latest changes from trunk,
and resolve a conflict. - 828. By Olivier Tilloy
-
Remove a not very useful comment.
- 829. By Olivier Tilloy
-
Rename the 'blob' property to 'savedState', which is much more explicit.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:829
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 830. By Olivier Tilloy
-
Merge the latest changes from trunk,
and resolve a couple of conflicts. - 831. By Olivier Tilloy
-
Fix BrowserTab unit tests.
- 832. By Olivier Tilloy
-
Revert accidental change introduced when merging latest trunk.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:832
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 833. By Olivier Tilloy
-
Merge the latest changes from trunk, and resolve a conflict.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:833
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:833
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 834. By Olivier Tilloy
-
Bump the required oxide version in the build dependencies as well, since unit tests require oxide 1.4.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:834
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:834
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'debian/control' |
2 | --- debian/control 2015-01-19 10:45:25 +0000 |
3 | +++ debian/control 2015-01-28 14:25:23 +0000 |
4 | @@ -6,7 +6,7 @@ |
5 | debhelper (>= 9), |
6 | dh-translations, |
7 | hardening-wrapper, |
8 | - liboxideqt-qmlplugin (>= 1.3), |
9 | + liboxideqt-qmlplugin (>= 1.4), |
10 | libqt5sql5-sqlite, |
11 | python-flake8, |
12 | python3-all, |
13 | @@ -34,7 +34,7 @@ |
14 | Depends: ${misc:Depends}, |
15 | ${shlibs:Depends}, |
16 | fonts-liberation, |
17 | - liboxideqt-qmlplugin (>= 1.1), |
18 | + liboxideqt-qmlplugin (>= 1.4), |
19 | libqt5sql5-sqlite, |
20 | qml-module-qtquick2 | qtdeclarative5-qtquick2-plugin, |
21 | qml-module-qtquick-dialogs | qtdeclarative5-dialogs-plugin, |
22 | |
23 | === modified file 'src/app/webbrowser/Browser.qml' |
24 | --- src/app/webbrowser/Browser.qml 2014-12-17 09:22:40 +0000 |
25 | +++ src/app/webbrowser/Browser.qml 2015-01-28 14:25:23 +0000 |
26 | @@ -17,7 +17,7 @@ |
27 | */ |
28 | |
29 | import QtQuick 2.0 |
30 | -import com.canonical.Oxide 1.0 as Oxide |
31 | +import com.canonical.Oxide 1.4 as Oxide |
32 | import Ubuntu.Components 1.1 |
33 | import webbrowserapp.private 0.1 |
34 | import webbrowsercommon.private 0.1 |
35 | @@ -415,7 +415,18 @@ |
36 | id: newTabViewLoader |
37 | anchors.fill: parent |
38 | |
39 | - sourceComponent: !parent.url.toString() ? newTabViewComponent : undefined |
40 | + // Avoid loading the new tab view if the webview is about to load |
41 | + // content. Since WebView.restoreState is not a notifyable property, |
42 | + // this can’t be achieved with a simple property binding. |
43 | + Component.onCompleted: { |
44 | + if (!parent.url.toString() && !parent.restoreState) { |
45 | + sourceComponent = newTabViewComponent |
46 | + } |
47 | + } |
48 | + Connections { |
49 | + target: newTabViewLoader.parent |
50 | + onUrlChanged: newTabViewLoader.sourceComponent = null |
51 | + } |
52 | |
53 | Component { |
54 | id: newTabViewComponent |
55 | @@ -542,39 +553,39 @@ |
56 | } |
57 | |
58 | // Those two functions are used to save/restore the current state of a tab. |
59 | - // The current implementation is naive, it only saves/restores the current URL. |
60 | - // In the future, we’ll want to rely on oxide to save and restore a full state |
61 | - // of the corresponding webview as a binary blob, which includes navigation |
62 | - // history, current scroll offset and form data. See http://pad.lv/1353143. |
63 | function serializeTabState(tab) { |
64 | var state = {} |
65 | state.uniqueId = tab.uniqueId |
66 | state.url = tab.url.toString() |
67 | state.title = tab.title |
68 | state.preview = tab.preview.toString() |
69 | + state.savedState = tab.webview ? tab.webview.currentState : tab.restoreState |
70 | return state |
71 | } |
72 | |
73 | function createTabFromState(state) { |
74 | - var properties = {"initialUrl": state.url, "initialTitle": state.title} |
75 | + var properties = {'initialUrl': state.url, 'initialTitle': state.title} |
76 | if ('uniqueId' in state) { |
77 | properties["uniqueId"] = state.uniqueId |
78 | } |
79 | if ('preview' in state) { |
80 | properties["preview"] = state.preview |
81 | } |
82 | + if ('savedState' in state) { |
83 | + properties['restoreState'] = state.savedState |
84 | + properties['restoreType'] = Oxide.WebView.RestoreLastSessionExitedCleanly |
85 | + } |
86 | return tabComponent.createObject(tabContainer, properties) |
87 | } |
88 | } |
89 | Connections { |
90 | - target: tabsModel |
91 | - onCurrentTabChanged: session.save() |
92 | - onCountChanged: session.save() |
93 | - } |
94 | - Connections { |
95 | - target: browser.currentWebview |
96 | - onUrlChanged: session.save() |
97 | - onTitleChanged: session.save() |
98 | + target: Qt.application |
99 | + onStateChanged: { |
100 | + if (Qt.application.state != Qt.ApplicationActive) { |
101 | + session.save() |
102 | + } |
103 | + } |
104 | + onAboutToQuit: session.save() |
105 | } |
106 | |
107 | // Delay instantiation of the first webview by 1 msec to allow initial |
108 | @@ -596,7 +607,7 @@ |
109 | browser.openUrlInNewTab(browser.homepage, true, false) |
110 | } |
111 | tabsModel.currentTab.load() |
112 | - if (!tabsModel.currentTab.url.toString() && (formFactor == "desktop")) { |
113 | + if (!tabsModel.currentTab.url.toString() && !tabsModel.currentTab.restoreState && (formFactor == "desktop")) { |
114 | internal.focusAddressBar() |
115 | } |
116 | } |
117 | |
118 | === modified file 'src/app/webbrowser/BrowserTab.qml' |
119 | --- src/app/webbrowser/BrowserTab.qml 2014-12-16 16:25:58 +0000 |
120 | +++ src/app/webbrowser/BrowserTab.qml 2015-01-28 14:25:23 +0000 |
121 | @@ -17,12 +17,15 @@ |
122 | */ |
123 | |
124 | import QtQuick 2.0 |
125 | +import com.canonical.Oxide 1.4 as Oxide |
126 | import webbrowserapp.private 0.1 |
127 | |
128 | FocusScope { |
129 | property string uniqueId: this.toString() + "-" + Date.now() |
130 | property url initialUrl |
131 | property string initialTitle |
132 | + property string restoreState |
133 | + property int restoreType |
134 | property var request |
135 | property Component webviewComponent |
136 | readonly property var webview: (children.length == 1) ? children[0] : null |
137 | @@ -33,7 +36,14 @@ |
138 | |
139 | function load() { |
140 | if (!webview) { |
141 | - webviewComponent.incubateObject(this, {"url": initialUrl}) |
142 | + var properties = {} |
143 | + if (restoreState) { |
144 | + properties['restoreState'] = restoreState |
145 | + properties['restoreType'] = restoreType |
146 | + } else { |
147 | + properties['url'] = initialUrl |
148 | + } |
149 | + webviewComponent.incubateObject(this, properties) |
150 | } |
151 | } |
152 | |
153 | @@ -41,6 +51,8 @@ |
154 | if (webview) { |
155 | initialUrl = webview.url |
156 | initialTitle = webview.title |
157 | + restoreState = webview.currentState |
158 | + restoreType = Oxide.WebView.RestoreCurrentSession |
159 | webview.destroy() |
160 | } |
161 | } |
162 | |
163 | === removed file 'tests/autopilot/webbrowser_app/tests/test_session_save_restore.py' |
164 | --- tests/autopilot/webbrowser_app/tests/test_session_save_restore.py 2014-12-18 18:39:47 +0000 |
165 | +++ tests/autopilot/webbrowser_app/tests/test_session_save_restore.py 1970-01-01 00:00:00 +0000 |
166 | @@ -1,51 +0,0 @@ |
167 | -# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
168 | -# |
169 | -# Copyright 2014 Canonical |
170 | -# |
171 | -# This program is free software: you can redistribute it and/or modify it |
172 | -# under the terms of the GNU General Public License version 3, as published |
173 | -# by the Free Software Foundation. |
174 | -# |
175 | -# This program is distributed in the hope that it will be useful, |
176 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
177 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
178 | -# GNU General Public License for more details. |
179 | -# |
180 | -# You should have received a copy of the GNU General Public License |
181 | -# along with this program. If not, see <http://www.gnu.org/licenses/>. |
182 | - |
183 | -from autopilot.matchers import Eventually |
184 | -from testtools.matchers import Equals |
185 | - |
186 | -from webbrowser_app.tests import StartOpenRemotePageTestCaseBase |
187 | - |
188 | - |
189 | -class TestSessionSaveRestore(StartOpenRemotePageTestCaseBase): |
190 | - |
191 | - def create_new_tab(self, url): |
192 | - self.open_tabs_view() |
193 | - self.open_new_tab() |
194 | - new_tab_view = self.main_window.get_new_tab_view() |
195 | - self.main_window.go_to_url(url) |
196 | - new_tab_view.wait_until_destroyed() |
197 | - |
198 | - def test_session_is_saved_and_restored(self): |
199 | - paths = ["/test1", "/test2", "/wait/0"] |
200 | - for path in paths[1:]: |
201 | - self.create_new_tab(self.base_url + path) |
202 | - self.open_tabs_view() |
203 | - tabs_view = self.main_window.get_tabs_view() |
204 | - self.assertThat(tabs_view.count, Eventually(Equals(len(paths)))) |
205 | - process = self.app.process |
206 | - process.kill() |
207 | - process.wait(10) |
208 | - self.ARGS = [] |
209 | - self.app = self.launch_app() |
210 | - self.open_tabs_view() |
211 | - tabs_view = self.main_window.get_tabs_view() |
212 | - self.assertThat(tabs_view.count, Eventually(Equals(len(paths)))) |
213 | - previews = tabs_view.get_ordered_previews() |
214 | - for i in range(len(paths)): |
215 | - self.assertThat(previews[len(paths) - 1 - i].url, |
216 | - Eventually(Equals(self.base_url + paths[i]))) |
217 | - self.assert_number_webviews_eventually(1) |
218 | |
219 | === modified file 'tests/unittests/qml/tst_BrowserTab.qml' |
220 | --- tests/unittests/qml/tst_BrowserTab.qml 2014-12-16 17:24:32 +0000 |
221 | +++ tests/unittests/qml/tst_BrowserTab.qml 2015-01-28 14:25:23 +0000 |
222 | @@ -35,6 +35,7 @@ |
223 | property string title |
224 | property url icon |
225 | property var request |
226 | + property string currentState |
227 | } |
228 | readonly property bool webviewPresent: webview |
229 | readonly property bool captureTakerPresent: captureTaker != undefined |
230 | @@ -66,10 +67,12 @@ |
231 | |
232 | tab.webview.url = "http://ubuntu.com" |
233 | tab.webview.title = "Ubuntu" |
234 | + tab.webview.currentState = "foobar" |
235 | tab.unload() |
236 | tryCompare(tab, 'webviewPresent', false) |
237 | compare(tab.initialUrl, "http://ubuntu.com") |
238 | compare(tab.initialTitle, "Ubuntu") |
239 | + compare(tab.restoreState, "foobar") |
240 | |
241 | tab.destroy() |
242 | } |
FAILED: Continuous integration, rev:825 jenkins. qa.ubuntu. com/job/ webbrowser- app-ci/ 1304/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 334/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- vivid/220/ console jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- amd64-ci/ 62/console jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- armhf-ci/ 62 jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- armhf-ci/ 62/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ webbrowser- app-vivid- i386-ci/ 62 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- vivid-mako/ 305/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 334 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 334/artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 16179 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-amd64/ 224/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/webbrowser- app-ci/ 1304/rebuild
http://