Merge lp:~osomon/webbrowser-app/save-restore-state into lp:webbrowser-app

Proposed by Olivier Tilloy on 2014-11-24
Status: Merged
Approved by: Olivier Tilloy on 2015-02-03
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
Reviewer Review Type Date Requested Status
Michael Vogt 2014-11-24 Approve on 2015-02-03
PS Jenkins bot continuous-integration Needs Fixing on 2015-02-03
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.

To post a comment you must log in.
826. By Olivier Tilloy on 2014-12-05

Merge the latest changes from trunk,
and resolve a conflict.

827. By Olivier Tilloy on 2014-12-16

Merge the latest changes from trunk,
and resolve a conflict.

828. By Olivier Tilloy on 2014-12-16

Remove a not very useful comment.

829. By Olivier Tilloy on 2014-12-16

Rename the 'blob' property to 'savedState', which is much more explicit.

830. By Olivier Tilloy on 2014-12-17

Merge the latest changes from trunk,
and resolve a couple of conflicts.

831. By Olivier Tilloy on 2014-12-17

Fix BrowserTab unit tests.

832. By Olivier Tilloy on 2014-12-17

Revert accidental change introduced when merging latest trunk.

833. By Olivier Tilloy on 2014-12-18

Merge the latest changes from trunk, and resolve a conflict.

834. By Olivier Tilloy on 2015-01-28

Bump the required oxide version in the build dependencies as well, since unit tests require oxide 1.4.

PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Michael Vogt (mvo) wrote :

+1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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 }

Subscribers

People subscribed via source and target branches

to status/vote changes: