Merge lp:~artmello/webbrowser-app/webbrowser-app-bookmarks_view into lp:webbrowser-app

Proposed by Arthur Mello
Status: Merged
Approved by: Olivier Tilloy
Approved revision: 1242
Merged at revision: 1237
Proposed branch: lp:~artmello/webbrowser-app/webbrowser-app-bookmarks_view
Merge into: lp:webbrowser-app
Diff against target: 2039 lines (+1145/-440)
19 files modified
src/app/webbrowser/BookmarksFoldersView.qml (+42/-10)
src/app/webbrowser/BookmarksFoldersViewWide.qml (+226/-0)
src/app/webbrowser/BookmarksModelUtils.js (+27/-0)
src/app/webbrowser/BookmarksView.qml (+132/-0)
src/app/webbrowser/BookmarksViewWide.qml (+130/-0)
src/app/webbrowser/Browser.qml (+82/-3)
src/app/webbrowser/HistoryView.qml (+70/-83)
src/app/webbrowser/HistoryViewWide.qml (+1/-0)
src/app/webbrowser/NewTabView.qml (+4/-1)
src/app/webbrowser/NewTabViewWide.qml (+35/-180)
src/app/webbrowser/UrlDelegate.qml (+6/-1)
src/app/webbrowser/UrlDelegateWide.qml (+3/-3)
tests/autopilot/webbrowser_app/emulators/browser.py (+13/-2)
tests/autopilot/webbrowser_app/tests/__init__.py (+9/-0)
tests/autopilot/webbrowser_app/tests/test_bookmark_options.py (+16/-12)
tests/autopilot/webbrowser_app/tests/test_keyboard.py (+45/-0)
tests/autopilot/webbrowser_app/tests/test_new_tab_view.py (+47/-15)
tests/unittests/qml/tst_BookmarksFoldersViewWide.qml (+257/-0)
tests/unittests/qml/tst_NewTabViewWide.qml (+0/-130)
To merge this branch: bzr merge lp:~artmello/webbrowser-app/webbrowser-app-bookmarks_view
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Olivier Tilloy Approve
Ugo Riboni (community) Approve
Review via email: mp+270613@code.launchpad.net

Commit message

Add bookmarks view to top level menu

Description of the change

Add bookmarks view to top level menu

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

- I can not get any favicon to load, even for sites that I just visited and have a favicon. The "globe" icon is always shown instead

- Open two browsers windows side by side and in one open the bookmarks view and in the other the history view:
  The styles of the two are not consistent with each other. If necessary speak with design about this, but I would change the following things:
  - In widescreen mode:
    - Use the same font as the history items for bookmark items
    - Use the same font as the dates in the history view for folders
    - The bookmarks view header should have a separator
    - The folder list items should have a separator
  - In non-widescreen mode:
    - The bookmarks view has an header, the history doesn't. I would add one to the history.
    - The folders in the bookmarks view should probably start all collapsed instead of all open, unless no folders exist.

review: Needs Fixing
Revision history for this message
Arthur Mello (artmello) wrote :

Thanks a lot for reviewing this. Comments bellow:

> - I can not get any favicon to load, even for sites that I just visited and
> have a favicon. The "globe" icon is always shown instead

I am not able to reproduce it, it seems to be working with old bookmarks and with new ones. How are you reproducing it? Some specific url domain?

> - Open two browsers windows side by side and in one open the bookmarks view
> and in the other the history view:
> The styles of the two are not consistent with each other. If necessary speak
> with design about this, but I would change the following things:
> - In widescreen mode:
> - Use the same font as the history items for bookmark items
> - Use the same font as the dates in the history view for folders

Fonts were the same, I set it to use the same fontSize. Let me know if it is better?

> - The bookmarks view header should have a separator
> - The folder list items should have a separator

Done

> - In non-widescreen mode:
> - The bookmarks view has an header, the history doesn't. I would add one
> to the history.

Since that would be a change on history view, what do you think of me doing this on a different MR?

> - The folders in the bookmarks view should probably start all collapsed
> instead of all open, unless no folders exist.

Done

Today we have URlDelegate and UrlDelegateWide with a lot of duplicate code, specially the one related with the url/title font. I didnt look further but would make sense to mix both those components on the same one? What do you think?

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ugo Riboni (uriboni) wrote :

> Thanks a lot for reviewing this. Comments bellow:
>
> > - I can not get any favicon to load, even for sites that I just visited and
> > have a favicon. The "globe" icon is always shown instead
>
> I am not able to reproduce it, it seems to be working with old bookmarks and
> with new ones. How are you reproducing it? Some specific url domain?

It must have been my fault. It seems to be working OK now

The style of fonts and other visuals in the bookmarks window is now matching the style of fonts in the new tab view. Thanks for fixing this.

> > - In non-widescreen mode:
> > - The bookmarks view has an header, the history doesn't. I would add one
> > to the history.
>
> Since that would be a change on history view, what do you think of me doing
> this on a different MR?

It is OK to do it here, since it is a change with very little impact other than visuals. But I am happy to have it done in another MR if you prefer (though I won't be around to review it next week).

> > - The folders in the bookmarks view should probably start all collapsed
> > instead of all open, unless no folders exist.
>
> Done

Please add unit tests to ensure this works properly, and make sure this change did not break any AP or unit test.

> Today we have URlDelegate and UrlDelegateWide with a lot of duplicate code,
> specially the one related with the url/title font. I didnt look further but
> would make sense to mix both those components on the same one? What do you
> think?

I am happy to wait and do this in a separate MR. There is enough in this one already.

Other than this, there are lots of AP tests failing, and they seem to be related to bookmarks, so I suspect they are caused by your changes. Please check and make sure everything is passing (the infrastructure is OK at the moment, because most other branches pass all AP tests, so all AP errors are most likely caused by your changes).

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ugo Riboni (uriboni) wrote :

Thanks for the fixes, but there is still a couple of issues that should be addressed:

1) Please make sure the header of the history and bookmarks pages is the same size. Check this screenshot to see the difference: http://i.imgur.com/2a5oeuu.png

2) The divider line in narrow screen mode for the bookmarks and history is in the wrong place (there is white space below the line), as you can see here: http://i.imgur.com/i38zcKK.png

3) Can you please make sure that you added unit tests for this feature: "The folders in the [narrow screen mode] bookmarks view should start all collapsed, instead of all open, unless no folders exist." ?

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ugo Riboni (uriboni) wrote :

All good now. Thanks for the fixes!

review: Approve
Revision history for this message
Olivier Tilloy (osomon) wrote :

A remark on the visuals: in wide mode, I’m seeing a slightly darker gray band on the right of the view.

review: Needs Fixing
Revision history for this message
Olivier Tilloy (osomon) wrote :

In BookmarksFoldersView.qml, is the onActiveFocusChanged handler really needed? Given that the top-level item is a focus scope, simply setting 'focus: true' on bookmarksFolderListView should achieve the same result I think.

The same applies to BookmarksView.qml and BookmarksViewWide.qml, which should be made FocusScopes.

In BookmarksFoldersViewWide.qml, in restoreLastFocusedColumn() there is one extraneous blank line, please remove it.

The bookmarkEntryRemoved signal, in both versions of the bookmarks view, doesn’t seem to be useful, as the view already has a reference to the bookmarks model, so it could do the removal itself, and then call done().

The headers in bookmarks and history views shouldn’t be plain white. See the visual spec at https://docs.google.com/presentation/d/1P6A7ZsI03sPfuI9vzPeC0VcUfIgugxnU4QyObH6UNTs/edit#slide=id.gde1819d92_0_109.

In wide mode, the "all bookmarks" section always contains the homepage, as a hardcoded entry. In narrow mode, it doesn’t. Can we make the two views consistent, by displaying the homepage entry on both?

review: Needs Fixing
1184. By Arthur Mello

Merge with trunk

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1185. By Arthur Mello

Remove darker gray band on the right of the view in wide mode.

1186. By Arthur Mello

Remove unnecessary onActiveFocusChanged handler

1187. By Arthur Mello

Make BookmarksView.qml and BookmarksViewWide.qml FocusScopes

1188. By Arthur Mello

Remove extraneous blank line

1189. By Arthur Mello

Simplify code when a Bookmark entry is removed in narrow mode

1190. By Arthur Mello

Simplify code when a Bookmark entry is removed in wide mode

1191. By Arthur Mello

Fix headers colors in bookmarks views

1192. By Arthur Mello

Fix headers colors in history views

1193. By Arthur Mello

Make the default homepage bookmark visible in all bookmarks views

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1194. By Arthur Mello

Fix AP tests

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1195. By Arthur Mello

Fix AP tests

1196. By Arthur Mello

Fix AP tests

Revision history for this message
Olivier Tilloy (osomon) wrote :

The changes to UrlsList.qml are meaningless when we’re not prepending a hardcoded entry to the list. And the names of the added properties ('defaultUrl' and 'defaultUrlTitle') are poorly chosen: this is not a default entry, it’s an additional one.

Anyway, you could achieve the same result by building a new model based on the bookmarks model + that additional entry (with a special flag to ensure it can’t be deleted).

Revision history for this message
Olivier Tilloy (osomon) wrote :

And what I’m suggesting above is actually what is already being done in BookmarksFoldersViewWide.qml (line 144).

1197. By Arthur Mello

Undo changes for Homepage default bookmark

1198. By Arthur Mello

Make the default homepage bookmark visible in all bookmarks views

1199. By Arthur Mello

Fix AP tests for new tab view

1200. By Arthur Mello

Fix AP tests for new tab view

1201. By Arthur Mello

Fix AP tests for bookmark options

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Olivier Tilloy (osomon) wrote :

If I press Ctrl+F while in the bookmarks view and then exit the view, the find-in-page mode has been activated in the current tab. This shortcut should be deactivated while in the bookmarks view. Hint: update the 'enabled' property of the corresponding KeyboardShortcut element.

Similarly, if I press Ctrl+L while in the bookmarks view, it looses focus and I can’t regain it. In general, please make sure that all the app’s keyboard shortcuts don’t have unintended effects while in the view.

A keyboard shortcut to open the view would be useful. Both chromium and firefox on desktop use Ctrl+Shift+O, so we could use that one too.

In UrlDelegate.qml, listActions doesn’t need to be a property of an internal QtObject, it can simply be defined as a child of the top-level item with an id, which you would refer to in the assignment of leadingActions.

In BookmarksView.qml, I don’t think we need to expose the entire settings object as a top-level property. Given that only the homepage setting is used (and in a read-only manner), can you expose just that one?

   property bool isHomeBookmark: folder === "" && index === 0
should reuse isAllBookmarksFolder instead of checking whether folder is empty again.

In general, please try and mark properties that won’t ever be written to with the 'readonly' keyword (such as isAllBookmarksFolder or isHomeBookmark.

And while we’re at it, in BookmarksFoldersView.qml the isHomeBookmark property is referenced only once, so its usefulness as a standalone property is questionable, you could simply transfer the condition to the assignment of 'removable'.

In test_set_bookmark_title, the need for an 'index' variable disappeared, you can simply hardcode the index in the assignment of the 'bookmark' variable.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1202. By Arthur Mello

Disable Ctrl+F when Bookmarks are visible

1203. By Arthur Mello

Disable reloading current tab when Bookmarks view is visible

1204. By Arthur Mello

Disable history navigation while Bookmarks view is visible

1205. By Arthur Mello

Disable toggle bookmarked state when bookmarks view is visible

1206. By Arthur Mello

Disable selecting the content in the address bar when Bookmarks is visible

1207. By Arthur Mello

Disable creating/closing tabs when bookmarks view is visible

1208. By Arthur Mello

Disable cycling through open tabs when bookmarks view is visible

1209. By Arthur Mello

Add Ctrl+Shift+O as a shortcut for Bookmarks

1210. By Arthur Mello

Simplify the way that listItemActions are defined on UrlDelegate

1211. By Arthur Mello

Do not expose the entire settings object to the bookmarks view

1212. By Arthur Mello

Reuse isAllBookmarksFolder to define isHomeBookmark property

1213. By Arthur Mello

Set properties as readonly

1214. By Arthur Mello

Simplify use of isHomeBookmark in BookmarksFoldersView

1215. By Arthur Mello

Remove unused variable in AP test

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Olivier Tilloy (osomon) wrote :

Instead of setting 'enabled' to 'chrome.visible && !bookmarksViewLoader.active' on most of the keyboard shortcuts, the visible property of the top-level FocusScope that contains tabContainer should be updated to be false when bookmarksViewLoader.active.
That way you wouldn’t have to update the enabled property of every single keyboard shortcut, and that would make for much easier maintenance.

Once done, please test all the keyboard shortcuts and ensure that they function only where intended. Please also add/update tests in tests/autopilot/webbrowser_app/tests/test_keyboard.py where relevant.

The Ctrl+T shortcut should be enabled while in the bookmarks view, to be consistent with the fact that the view has a "new tab" toolbar button. Of course opening a new tab should close the view.

review: Needs Fixing
1216. By Arthur Mello

Change the check to enable/disable keyboard shortcuts

1217. By Arthur Mello

Enable Ctrl+T to create a new tab when in bookmarks view

1218. By Arthur Mello

Fix wrong test to check if it is a removable bookmark

1219. By Arthur Mello

Add AP tests for bookmarks keyboard shortcuts

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Olivier Tilloy (osomon) wrote :

We’re getting there. Some additional comments:

In BookmarksFoldersView.qml and BookmarksFoldersViewWide.qml there is a very similar piece of code that builds a synthetic bookmarks model with a special entry prepended for the homepage. Can this please be factored out in a shared helper function?

In BookmarksView.qml and BookmarksViewWide.qml, it seems the import of webbrowserapp.private is unnecessary.

In Browser.qml, the signal handlers for the BookmarksView and the BookmarksViewWide instances are duplicated. Can you maybe use a Connections item to factor them out? I haven’t verified, would something like that work?
    Connections {
        target: bookmarksViewLoader.active ? bookmarksViewLoader.item : null
        onBookmarkEntryClicked: …
        onDone: …
    }

In the Ctrl+T KeyboardShortcut’s onTriggered, no need to check whether bookmarksViewLoader.active is true before setting it to false: if it was false already, this is a no-op.

While we’re at it, can you add support for the Ctrl+T shortcut in the history view, similarly to what you did for the bookmarks view?

In tests/autopilot/webbrowser_app/emulators/browser.py, there is no need for custom CPOs for BookmarksView and BookmarksViewWide if they don’t expose any custom methods/getters. In that case you can simply select by name with a string: in get_bookmarks_view, self.select_single("BookmarksView").

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1220. By Arthur Mello

Remove unused imports

1221. By Arthur Mello

Converge signal handlers for the BookmarksView to the same place

1222. By Arthur Mello

Change check for bookmarks view active on Ctrl+T shortcut
Make Ctrl+T shortcut work for History view and add an AP test

1223. By Arthur Mello

Remove custom CPOs for BookmarksView and BookmarksViewWide

1224. By Arthur Mello

Move code to add homepage to bookmarks model to a shared helper function

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Olivier Tilloy (osomon) wrote :

Comments on revision 1224:
 - In BookmarksModelUtils.js:
   * Is there really a use case for model==null? It looks like that check was in BookmarksFoldersViewWide.qml before, but it was not in BookmarksFoldersView.qml, so it doesn’t make sense to factor that bit out.
   * The docstring for the function isn’t correct, it’s not a temporary model (it would be temporary if it was instantiated, used and then deleted within the same scope). And there shouldn’t be a check for homeEntry==undefined. Calling that function with no home entry is useless and needlessly expensive, as it does a deep-copy of the already existing model.
   * Can we find a more expressive name for createUrlsListModel()? Maybe prependHomepageToBookmarks()?
 - As pointed out above, in BookmarksFoldersView.qml and BookmarksFoldersViewWide.qml, calling createUrlsListModel() without a homepage entry is useless, you should simply return the existing model.

review: Needs Fixing
Revision history for this message
Olivier Tilloy (osomon) wrote :

I’m seeing multiple autopilot failures when run locally on my desktop (at least 4 in test_bookmark_options, I haven’t run the entire test suite, please do).

review: Needs Fixing
1225. By Arthur Mello

Merge with trunk

1226. By Arthur Mello

Remove null model checkrom BookmarksModelUtils

1227. By Arthur Mello

Change docstring and function name for BookmarksModelUtils

1228. By Arthur Mello

Do not call utils function when not adding a homepage bookmark entry

1229. By Arthur Mello

Fix wrong remove

1230. By Arthur Mello

Fix AP tests

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Olivier Tilloy (osomon) wrote :

In BookmarksView.qml and BookmarksViewWide.qml, there are references to 'browser' (calls to browser.openUrlInNewTab). This breaks encapsulation. Please replace this with a signal emission that will be connected to in Browser.qml.

review: Needs Fixing
Revision history for this message
Olivier Tilloy (osomon) wrote :

In the Connections instance inside bookmarksViewLoader, the definition of 'target' doesn’t need to be conditional: if the loader is inactive, its item is null anyway.

Revision history for this message
Olivier Tilloy (osomon) wrote :

In the bookmarks view and in the new tab view in wide mode, pressing the right arrow key to move the focus to the right panel works when the first folder is currently highlighted, but not with other folders.

review: Needs Fixing
Revision history for this message
Olivier Tilloy (osomon) wrote :

(please add a test for the fix to the issue above)

1231. By Arthur Mello

Merge with trunk

1232. By Arthur Mello

Remove references to browser component from BookmarksView/BookmarksViewWide

1233. By Arthur Mello

Remove unnecesary check

1234. By Arthur Mello

Fix keyboard navigation

1235. By Arthur Mello

Expand unittest to BookmarksFoldersViewWide keyboa navigation

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1236. By Arthur Mello

Fix AP test issue

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Olivier Tilloy (osomon) wrote :

There are now conflicts when merging this branch into the latest trunk, can you please resolve them?

review: Needs Fixing
1237. By Arthur Mello

Merge with trunk

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Olivier Tilloy (osomon) wrote :

Please revert the changes to po/webbrowser-app.pot.

review: Needs Fixing
Revision history for this message
Olivier Tilloy (osomon) wrote :

Keyboard navigation appears to be broken in the bookmarks section of the wide new tab view.

review: Needs Fixing
1238. By Arthur Mello

Undo changes on po

1239. By Arthur Mello

Merge with trunk

1240. By Arthur Mello

Keep webbrowser-app.po from trunk

1241. By Arthur Mello

Fix NewTabViewWide keyboard navigation

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Olivier Tilloy (osomon) wrote :

In NewTabView.qml, there’s a modified line that has an extraneous trailing whitespace, can you please remove it?

1242. By Arthur Mello

Remove extraneous trailing whitespace

Revision history for this message
Olivier Tilloy (osomon) wrote :

Thanks, LGTM now.

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== renamed file 'src/app/webbrowser/BookmarksFolderListView.qml' => 'src/app/webbrowser/BookmarksFoldersView.qml'
--- src/app/webbrowser/BookmarksFolderListView.qml 2015-08-10 15:22:00 +0000
+++ src/app/webbrowser/BookmarksFoldersView.qml 2015-10-16 15:16:36 +0000
@@ -20,11 +20,14 @@
20import Ubuntu.Components 1.320import Ubuntu.Components 1.3
21import Ubuntu.Components.ListItems 1.3 as ListItem21import Ubuntu.Components.ListItems 1.3 as ListItem
22import webbrowserapp.private 0.122import webbrowserapp.private 0.1
23import "BookmarksModelUtils.js" as BookmarksModelUtils
2324
24Item {25FocusScope {
25 id: bookmarksFolderListViewItem26 id: bookmarksFoldersViewItem
2627
27 property alias model: bookmarksFolderListModel.sourceModel 28 property alias model: bookmarksFolderListModel.sourceModel
29 property alias interactive: bookmarksFolderListView.interactive
30 property url homeBookmarkUrl
2831
29 signal bookmarkClicked(url url)32 signal bookmarkClicked(url url)
30 signal bookmarkRemoved(url url)33 signal bookmarkRemoved(url url)
@@ -39,6 +42,7 @@
39 id: bookmarksFolderListView42 id: bookmarksFolderListView
40 anchors.fill: parent43 anchors.fill: parent
41 interactive: false44 interactive: false
45 focus: true
4246
43 model: bookmarksFolderListModel47 model: bookmarksFolderListModel
44 delegate: Loader {48 delegate: Loader {
@@ -65,7 +69,7 @@
65 Column {69 Column {
66 id: delegateColumn70 id: delegateColumn
6771
68 property bool expanded: true72 property bool expanded: folderName ? false : true
6973
70 anchors {74 anchors {
71 left: parent.left75 left: parent.left
@@ -138,16 +142,44 @@
138 right: parent.right142 right: parent.right
139 }143 }
140144
145 height: item ? item.contentHeight : 0
146
141 visible: status == Loader.Ready147 visible: status == Loader.Ready
142148
143 active: delegateColumn.expanded149 active: delegateColumn.expanded
144 sourceComponent: UrlsList {150 sourceComponent: ListView {
145 spacing: 0151 readonly property bool isAllBookmarksFolder: folder === ""
146152
147 model: entries153 interactive: false
148154
149 onUrlClicked: bookmarksFolderListViewItem.bookmarkClicked(url)155 model: {
150 onUrlRemoved: bookmarksFolderListViewItem.bookmarkRemoved(url)156 if (isAllBookmarksFolder) {
157 return BookmarksModelUtils.prependHomepageToBookmarks(entries, {
158 title: i18n.tr("Homepage"),
159 url: bookmarksFoldersViewItem.homeBookmarkUrl
160 })
161 }
162
163 return entries
164 }
165
166 delegate: UrlDelegate{
167 id: urlDelegate
168
169 property var entry: isAllBookmarksFolder ? modelData : model
170
171 width: parent.width
172 height: units.gu(5)
173
174 removable: !isAllBookmarksFolder || index !== 0
175
176 icon: entry.icon ? entry.icon : ""
177 title: entry.title ? entry.title : entry.url
178 url: entry.url
179
180 onClicked: bookmarksFoldersViewItem.bookmarkClicked(url)
181 onRemoved: bookmarksFoldersViewItem.bookmarkRemoved(url)
182 }
151 }183 }
152 }184 }
153 }185 }
154186
=== added file 'src/app/webbrowser/BookmarksFoldersViewWide.qml'
--- src/app/webbrowser/BookmarksFoldersViewWide.qml 1970-01-01 00:00:00 +0000
+++ src/app/webbrowser/BookmarksFoldersViewWide.qml 2015-10-16 15:16:36 +0000
@@ -0,0 +1,226 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This file is part of webbrowser-app.
5 *
6 * webbrowser-app is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * webbrowser-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19import QtQuick 2.4
20import Ubuntu.Components 1.3
21import webbrowserapp.private 0.1
22import "BookmarksModelUtils.js" as BookmarksModelUtils
23
24FocusScope {
25 id: bookmarksFoldersViewWideItem
26
27 property alias model: bookmarksFolderListModel.sourceModel
28 property url homeBookmarkUrl
29
30 signal bookmarkClicked(url url)
31 signal bookmarkRemoved(url url)
32 signal dragStarted()
33
34 function restoreLastFocusedColumn() {
35 if (internal.lastFocusedColumn &&
36 internal.lastFocusedColumn == bookmarksList &&
37 model.count > 0) {
38 bookmarksList.forceActiveFocus()
39 } else {
40 folders.forceActiveFocus()
41 }
42 }
43
44 onActiveFocusChanged: {
45 if (activeFocus) {
46 restoreLastFocusedColumn()
47 }
48 }
49
50 Rectangle {
51 anchors.fill: parent
52 color: "#fbfbfb"
53 }
54
55 ListView {
56 id: folders
57 objectName: "foldersList"
58
59 anchors {
60 top: parent.top
61 bottom: parent.bottom
62 left: parent.left
63 }
64
65 width: units.gu(25)
66
67 onActiveFocusChanged: {
68 if (activeFocus) {
69 internal.lastFocusedColumn = folders
70 }
71 }
72
73 model: BookmarksFolderListModel {
74 id: bookmarksFolderListModel
75 }
76 currentIndex: 0
77
78 Keys.onRightPressed: {
79 if (!folders.currentItem) {
80 return
81 }
82
83 if ((folders.currentItem.isAllBookmarksFolder && bookmarksList.model.length > 0) || bookmarksList.model.count > 0) {
84 bookmarksList.focus = true
85 }
86 }
87
88 delegate: ListItem {
89 id: folderItem
90 objectName: "folderItem"
91
92 property alias name: dropArea.folderName
93 property var model: entries
94 readonly property bool isActiveFolder: ListView.isCurrentItem
95 readonly property bool isAllBookmarksFolder: folder.length === 0
96 readonly property bool isCurrentDropTarget: dropArea.containsDrag && dropArea.drag.source.folder !== folder
97
98 color: isCurrentDropTarget ? "green" :
99 ((folders.activeFocus && isActiveFolder) ? Qt.rgba(0, 0, 0, 0.05) : "transparent")
100
101 Label {
102 anchors {
103 verticalCenter: parent.verticalCenter
104 left: parent.left
105 right: parent.right
106 leftMargin: units.gu(2)
107 rightMargin: units.gu(2)
108 }
109
110 fontSize: "small"
111 text: isAllBookmarksFolder ? i18n.tr("All Bookmarks") : folderItem.name
112 color: isActiveFolder ? UbuntuColors.orange : UbuntuColors.darkGrey
113 }
114
115 onClicked: folders.currentIndex = index
116
117 DropArea {
118 id: dropArea
119
120 property string folderName: folder
121 anchors.fill: parent
122 }
123 }
124 }
125
126 Scrollbar {
127 flickableItem: folders
128 }
129
130 ListView {
131 id: bookmarksList
132 objectName: "bookmarksList"
133
134 anchors {
135 top: parent.top
136 bottom: parent.bottom
137 left: folders.right
138 right: parent.right
139 }
140
141 onActiveFocusChanged: {
142 if (activeFocus) {
143 internal.lastFocusedColumn = bookmarksList
144 }
145 }
146
147 model: {
148 if (!folders.currentItem || !folders.currentItem.model) {
149 return null
150 }
151
152 if (folders.currentItem.isAllBookmarksFolder) {
153 return BookmarksModelUtils.prependHomepageToBookmarks(folders.currentItem.model, {
154 title: i18n.tr("Homepage"),
155 url: bookmarksFoldersViewWideItem.homeBookmarkUrl,
156 folder: ""
157 })
158 }
159
160 return folders.currentItem.model
161 }
162
163 currentIndex: 0
164
165 delegate: DraggableUrlDelegateWide {
166 objectName: "bookmarkItem"
167
168 property var entry: folders.currentItem.isAllBookmarksFolder ? modelData : model
169 property string folder: entry.folder
170 readonly property bool isHomeBookmark: folder === "" && index === 0
171
172 clip: true
173 title: entry.title
174 icon: entry.icon ? entry.icon : ""
175 url: entry.url
176
177 removable: !isHomeBookmark
178 draggable: !isHomeBookmark && contentItem.x === 0
179 highlighted: bookmarksList.activeFocus && ListView.isCurrentItem
180
181 onClicked: bookmarksFoldersViewWideItem.bookmarkClicked(url)
182 onRemoved: bookmarksFoldersViewWideItem.bookmarkRemoved(url)
183
184 // Larger margin to prevent interference from Scrollbar hovering area
185 gripMargin: units.gu(4)
186 onDragStarted: {
187 // Remove interactivity to prevent the list from scrolling
188 // while dragging near its margins. This ensures we can correctly
189 // return the item to its original position on a failed drop.
190 bookmarksList.interactive = false
191
192 bookmarksFoldersViewWideItem.dragStarted()
193 }
194 onDragEnded: {
195 bookmarksList.interactive = true
196
197 if (dragAndDrop.target && dragAndDrop.target.folderName !== folder) {
198 bookmarksFoldersViewWideItem.model.update(entry.url, entry.title,
199 dragAndDrop.target.folderName)
200 dragAndDrop.success = true
201 }
202 }
203 }
204
205 Keys.onReturnPressed: bookmarksFoldersViewWideItem.bookmarkClicked(currentItem.url)
206 Keys.onDeletePressed: {
207 if (currentItem.removable) {
208 bookmarksFoldersViewWideItem.bookmarkRemoved(currentItem.url)
209 if (bookmarksList.model.length === 0) {
210 folders.focus = true
211 }
212 }
213 }
214 Keys.onLeftPressed: folders.focus = true
215 }
216
217 Scrollbar {
218 flickableItem: bookmarksList
219 }
220
221 QtObject {
222 id: internal
223
224 property var lastFocusedColumn: folders
225 }
226}
0227
=== added file 'src/app/webbrowser/BookmarksModelUtils.js'
--- src/app/webbrowser/BookmarksModelUtils.js 1970-01-01 00:00:00 +0000
+++ src/app/webbrowser/BookmarksModelUtils.js 2015-10-16 15:16:36 +0000
@@ -0,0 +1,27 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This file is part of webbrowser-app.
5 *
6 * webbrowser-app is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * webbrowser-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/* Prepend the homepage bookmark item to bookmarks model */
20function prependHomepageToBookmarks(model, homeEntry) {
21 var items = []
22 items.push(homeEntry)
23 for (var i = 0; i < model.count; i++) {
24 items.push(model.get(i))
25 }
26 return items
27}
028
=== added file 'src/app/webbrowser/BookmarksView.qml'
--- src/app/webbrowser/BookmarksView.qml 1970-01-01 00:00:00 +0000
+++ src/app/webbrowser/BookmarksView.qml 2015-10-16 15:16:36 +0000
@@ -0,0 +1,132 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This file is part of webbrowser-app.
5 *
6 * webbrowser-app is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * webbrowser-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19import QtQuick 2.4
20import Ubuntu.Components 1.3
21import Ubuntu.Components.ListItems 1.3 as ListItems
22
23FocusScope {
24 id: bookmarksView
25
26 property alias bookmarksModel: bookmarksFoldersView.model
27 property alias homepageUrl: bookmarksFoldersView.homeBookmarkUrl
28
29 signal bookmarkEntryClicked(url url)
30 signal done()
31 signal newTabClicked()
32
33 Rectangle {
34 anchors.fill: parent
35 color: "#f6f6f6"
36 }
37
38 BookmarksFoldersView {
39 id: bookmarksFoldersView
40
41 anchors {
42 top: topBar.bottom
43 left: parent.left
44 right: parent.right
45 bottom: toolbar.top
46 rightMargin: units.gu(2)
47 }
48
49 interactive: true
50 focus: true
51
52 onBookmarkClicked: bookmarksView.bookmarkEntryClicked(url)
53 onBookmarkRemoved: {
54 if (bookmarksModel.count == 1) {
55 done()
56 }
57 bookmarksModel.remove(url)
58 }
59 }
60
61 Toolbar {
62 id: topBar
63
64 height: units.gu(7)
65 color: "#f7f7f7"
66
67 anchors {
68 left: parent.left
69 right: parent.right
70 top: parent.top
71 }
72
73 Label {
74 anchors {
75 top: parent.top
76 left: parent.left
77 topMargin: units.gu(2)
78 leftMargin: units.gu(2)
79 }
80
81 text: i18n.tr("Bookmarks")
82 }
83
84 ListItems.ThinDivider {
85 anchors {
86 left: parent.left
87 right: parent.right
88 bottom: parent.bottom
89 }
90 }
91 }
92
93 Toolbar {
94 id: toolbar
95 height: units.gu(7)
96
97 anchors {
98 left: parent.left
99 right: parent.right
100 bottom: parent.bottom
101 }
102
103 Button {
104 objectName: "doneButton"
105 anchors {
106 left: parent.left
107 leftMargin: units.gu(2)
108 verticalCenter: parent.verticalCenter
109 }
110
111 strokeColor: UbuntuColors.darkGrey
112
113 text: i18n.tr("Done")
114
115 onClicked: bookmarksView.done()
116 }
117
118 ToolbarAction {
119 anchors {
120 right: parent.right
121 rightMargin: units.gu(2)
122 verticalCenter: parent.verticalCenter
123 }
124 height: parent.height - units.gu(2)
125
126 text: i18n.tr("New tab")
127 iconName: "tab-new"
128
129 onClicked: bookmarksView.newTabClicked()
130 }
131 }
132}
0133
=== added file 'src/app/webbrowser/BookmarksViewWide.qml'
--- src/app/webbrowser/BookmarksViewWide.qml 1970-01-01 00:00:00 +0000
+++ src/app/webbrowser/BookmarksViewWide.qml 2015-10-16 15:16:36 +0000
@@ -0,0 +1,130 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This file is part of webbrowser-app.
5 *
6 * webbrowser-app is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * webbrowser-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19import QtQuick 2.4
20import Ubuntu.Components 1.3
21import Ubuntu.Components.ListItems 1.3 as ListItems
22
23FocusScope {
24 id: bookmarksViewWide
25
26 property alias bookmarksModel: bookmarksFoldersViewWide.model
27 property alias homepageUrl: bookmarksFoldersViewWide.homeBookmarkUrl
28
29 signal bookmarkEntryClicked(url url)
30 signal done()
31 signal newTabClicked()
32
33 Rectangle {
34 anchors.fill: parent
35 color: "#f6f6f6"
36 }
37
38 BookmarksFoldersViewWide {
39 id: bookmarksFoldersViewWide
40
41 anchors {
42 top: topBar.bottom
43 left: parent.left
44 right: parent.right
45 bottom: toolbar.top
46 }
47
48 focus: true
49
50 onBookmarkClicked: bookmarksViewWide.bookmarkEntryClicked(url)
51 onBookmarkRemoved: {
52 if (bookmarksModel.count == 1) {
53 done()
54 }
55 bookmarksModel.remove(url)
56 }
57 }
58
59 Toolbar {
60 id: topBar
61
62 height: units.gu(7)
63 color: "#f7f7f7"
64
65 anchors {
66 left: parent.left
67 right: parent.right
68 top: parent.top
69 }
70
71 Label {
72 anchors {
73 top: parent.top
74 left: parent.left
75 topMargin: units.gu(2)
76 leftMargin: units.gu(2)
77 }
78
79 text: i18n.tr("Bookmarks")
80 }
81
82 ListItems.ThinDivider {
83 anchors {
84 left: parent.left
85 right: parent.right
86 bottom: parent.bottom
87 }
88 }
89 }
90
91 Toolbar {
92 id: toolbar
93 height: units.gu(7)
94
95 anchors {
96 left: parent.left
97 right: parent.right
98 bottom: parent.bottom
99 }
100
101 Button {
102 objectName: "doneButton"
103 anchors {
104 left: parent.left
105 leftMargin: units.gu(2)
106 verticalCenter: parent.verticalCenter
107 }
108
109 strokeColor: UbuntuColors.darkGrey
110
111 text: i18n.tr("Done")
112
113 onClicked: bookmarksViewWide.done()
114 }
115
116 ToolbarAction {
117 anchors {
118 right: parent.right
119 rightMargin: units.gu(2)
120 verticalCenter: parent.verticalCenter
121 }
122 height: parent.height - units.gu(2)
123
124 text: i18n.tr("New tab")
125 iconName: "tab-new"
126
127 onClicked: bookmarksViewWide.newTabClicked()
128 }
129 }
130}
0131
=== modified file 'src/app/webbrowser/Browser.qml'
--- src/app/webbrowser/Browser.qml 2015-10-13 12:57:33 +0000
+++ src/app/webbrowser/Browser.qml 2015-10-16 15:16:36 +0000
@@ -140,7 +140,7 @@
140140
141 FocusScope {141 FocusScope {
142 anchors.fill: parent142 anchors.fill: parent
143 visible: !settingsContainer.visible && !historyViewLoader.active143 visible: !settingsContainer.visible && !historyViewLoader.active && !bookmarksViewLoader.active
144144
145 TabChrome {145 TabChrome {
146 id: invisibleTabChrome146 id: invisibleTabChrome
@@ -368,6 +368,13 @@
368 onTriggered: internal.shareLink(browser.currentWebview.url, browser.currentWebview.title)368 onTriggered: internal.shareLink(browser.currentWebview.url, browser.currentWebview.title)
369 },369 },
370 Action {370 Action {
371 objectName: "bookmarks"
372 text: i18n.tr("Bookmarks")
373 iconName: "bookmark"
374 enabled: browser.bookmarksModel
375 onTriggered: bookmarksViewLoader.active = true
376 },
377 Action {
371 objectName: "history"378 objectName: "history"
372 text: i18n.tr("History")379 text: i18n.tr("History")
373 iconName: "history"380 iconName: "history"
@@ -759,6 +766,67 @@
759 }766 }
760767
761 Loader {768 Loader {
769 id: bookmarksViewLoader
770
771 anchors.fill: parent
772 active: false
773 sourceComponent: browser.wide ? bookmarksViewWideComponent : bookmarksViewComponent
774
775 onStatusChanged: {
776 if (status == Loader.Ready) {
777 bookmarksViewTimer.restart()
778 bookmarksViewLoader.item.forceActiveFocus()
779 } else {
780 internal.resetFocus()
781 }
782 }
783
784 Keys.onEscapePressed: bookmarksViewLoader.active = false
785
786 Connections {
787 target: bookmarksViewLoader.item
788
789 onBookmarkEntryClicked: {
790 browser.openUrlInNewTab(url, true)
791 bookmarksViewLoader.active = false
792 }
793 onDone: bookmarksViewLoader.active = false
794 onNewTabClicked: {
795 browser.openUrlInNewTab("", true)
796 bookmarksViewLoader.active = false
797 }
798 }
799
800 Timer {
801 id: bookmarksViewTimer
802 // Set the model asynchronously to ensure
803 // the view is displayed as early as possible.
804 interval: 1
805 onTriggered: bookmarksViewLoader.item.bookmarksModel = browser.bookmarksModel
806 }
807
808 Component {
809 id: bookmarksViewComponent
810
811 BookmarksView {
812 anchors.fill: parent
813
814 homepageUrl: settings.homepage
815 }
816 }
817
818 Component {
819 id: bookmarksViewWideComponent
820
821 BookmarksViewWide {
822 anchors.fill: parent
823
824 homepageUrl: settings.homepage
825 }
826 }
827 }
828
829 Loader {
762 id: historyViewLoader830 id: historyViewLoader
763831
764 anchors.fill: parent832 anchors.fill: parent
@@ -1653,10 +1721,13 @@
1653 KeyboardShortcut {1721 KeyboardShortcut {
1654 modifiers: Qt.ControlModifier1722 modifiers: Qt.ControlModifier
1655 key: Qt.Key_T1723 key: Qt.Key_T
1656 enabled: chrome.visible || recentView.visible1724 enabled: chrome.visible || recentView.visible || bookmarksViewLoader.active || historyViewLoader.active
1657 onTriggered: {1725 onTriggered: {
1658 openUrlInNewTab("", true)1726 openUrlInNewTab("", true)
1659 if (recentView.visible) recentView.reset()1727 if (recentView.visible) recentView.reset()
1728
1729 bookmarksViewLoader.active = false
1730 historyViewLoader.active = false
1660 }1731 }
1661 }1732 }
16621733
@@ -1703,6 +1774,14 @@
1703 onTriggered: historyViewLoader.active = true1774 onTriggered: historyViewLoader.active = true
1704 }1775 }
17051776
1777 // Ctrl+Shift+O: Show Bookmarks
1778 KeyboardShortcut {
1779 modifiers: Qt.ControlModifier | Qt.ShiftModifier
1780 key: Qt.Key_O
1781 enabled: chrome.visible
1782 onTriggered: bookmarksViewLoader.active = true
1783 }
1784
1706 // Alt+← or Backspace: Goes to the previous page in history1785 // Alt+← or Backspace: Goes to the previous page in history
1707 KeyboardShortcut {1786 KeyboardShortcut {
1708 modifiers: Qt.AltModifier1787 modifiers: Qt.AltModifier
@@ -1747,7 +1826,7 @@
1747 KeyboardShortcut {1826 KeyboardShortcut {
1748 modifiers: Qt.ControlModifier1827 modifiers: Qt.ControlModifier
1749 key: Qt.Key_F1828 key: Qt.Key_F
1750 enabled: !newTabViewLoader.active1829 enabled: !newTabViewLoader.active && !bookmarksViewLoader.active
1751 onTriggered: {1830 onTriggered: {
1752 chrome.findInPageMode = true1831 chrome.findInPageMode = true
1753 chrome.focus = true1832 chrome.focus = true
17541833
=== modified file 'src/app/webbrowser/HistoryView.qml'
--- src/app/webbrowser/HistoryView.qml 2015-08-31 12:50:16 +0000
+++ src/app/webbrowser/HistoryView.qml 2015-10-16 15:16:36 +0000
@@ -18,6 +18,7 @@
1818
19import QtQuick 2.419import QtQuick 2.4
20import Ubuntu.Components 1.320import Ubuntu.Components 1.3
21import Ubuntu.Components.ListItems 1.3 as ListItems
21import webbrowserapp.private 0.122import webbrowserapp.private 0.1
2223
23Item {24Item {
@@ -136,11 +137,12 @@
136 }137 }
137 }138 }
138139
139 Item {140 Toolbar {
140 id: topBar141 id: topBar
141142
142 visible: domainsListView.ViewItems.selectMode143 visible: domainsListView.ViewItems.selectMode
143 height: visible ? units.gu(5) : 0144 height: visible ? units.gu(7) : 0
145 color: "#f7f7f7"
144146
145 Behavior on height {147 Behavior on height {
146 UbuntuNumberAnimation {}148 UbuntuNumberAnimation {}
@@ -152,91 +154,76 @@
152 top: parent.top154 top: parent.top
153 }155 }
154156
155 Rectangle {157 ToolbarAction {
156 width: parent.width158 iconName: "close"
157 height: parent.height + units.gu(1.5)159 text: i18n.tr("Cancel")
158 color: "white"160
159 }161 onClicked: domainsListView.ViewItems.selectMode = false
160162
161 Item {
162 anchors {163 anchors {
163 top: parent.top
164 left: parent.left164 left: parent.left
165 leftMargin: units.gu(2)165 leftMargin: units.gu(2)
166 }
167
168 height: parent.height - units.gu(2)
169 }
170
171 ToolbarAction {
172 iconName: "select"
173 text: i18n.tr("Select all")
174
175 onClicked: {
176 if (domainsListView.ViewItems.selectedIndices.length === domainsListView.count) {
177 domainsListView.ViewItems.selectedIndices = []
178 } else {
179 var indices = []
180 for (var i = 0; i < domainsListView.count; ++i) {
181 indices.push(i)
182 }
183 domainsListView.ViewItems.selectedIndices = indices
184 }
185 }
186
187 anchors {
188 right: deleteButton.left
189 rightMargin: units.gu(2)
190 }
191
192 height: parent.height - units.gu(2)
193 }
194
195 ToolbarAction {
196 id: deleteButton
197
198 iconName: "delete"
199 text: i18n.tr("Delete")
200 enabled: domainsListView.ViewItems.selectedIndices.length > 0
201
202 onClicked: {
203 var indices = domainsListView.ViewItems.selectedIndices
204 var domains = []
205 for (var i in indices) {
206 domains.push(domainsListView.model.get(indices[i]))
207 }
208 domainsListView.ViewItems.selectMode = false
209 for (var j in domains) {
210 HistoryModel.removeEntriesByDomain(domains[j])
211 }
212 }
213
214 anchors {
215 right: parent.right
216 rightMargin: units.gu(2)
217 }
218
219 height: parent.height - units.gu(2)
220 }
221
222 ListItems.ThinDivider {
223 anchors {
224 left: parent.left
225 right: parent.right
166 bottom: parent.bottom226 bottom: parent.bottom
167 right: parent.right
168 rightMargin: units.gu(2)
169 }
170
171 ToolbarAction {
172 iconName: "close"
173 text: i18n.tr("Cancel")
174
175 MouseArea {
176 anchors.fill: parent
177 onClicked: domainsListView.ViewItems.selectMode = false
178 }
179
180 anchors.left: parent.left
181
182 height: parent.height
183 width: height
184 }
185
186 ToolbarAction {
187 iconName: "select"
188 text: i18n.tr("Select all")
189
190 MouseArea {
191 anchors.fill: parent
192 onClicked: {
193 if (domainsListView.ViewItems.selectedIndices.length === domainsListView.count) {
194 domainsListView.ViewItems.selectedIndices = []
195 } else {
196 var indices = []
197 for (var i = 0; i < domainsListView.count; ++i) {
198 indices.push(i)
199 }
200 domainsListView.ViewItems.selectedIndices = indices
201 }
202 }
203 }
204
205 anchors {
206 right: deleteButton.left
207 rightMargin: units.gu(2)
208 }
209
210 height: parent.height
211 width: height
212 }
213
214 ToolbarAction {
215 id: deleteButton
216
217 iconName: "delete"
218 text: i18n.tr("Delete")
219 enabled: domainsListView.ViewItems.selectedIndices.length > 0
220
221 MouseArea {
222 anchors.fill: parent
223 onClicked: {
224 var indices = domainsListView.ViewItems.selectedIndices
225 var domains = []
226 for (var i in indices) {
227 domains.push(domainsListView.model.get(indices[i]))
228 }
229 domainsListView.ViewItems.selectMode = false
230 for (var j in domains) {
231 HistoryModel.removeEntriesByDomain(domains[j])
232 }
233 }
234 }
235
236 anchors.right: parent.right
237
238 height: parent.height
239 width: height
240 }227 }
241 }228 }
242 }229 }
243230
=== modified file 'src/app/webbrowser/HistoryViewWide.qml'
--- src/app/webbrowser/HistoryViewWide.qml 2015-10-08 08:50:59 +0000
+++ src/app/webbrowser/HistoryViewWide.qml 2015-10-16 15:16:36 +0000
@@ -346,6 +346,7 @@
346 id: topBar346 id: topBar
347347
348 height: units.gu(7)348 height: units.gu(7)
349 color: "#f7f7f7"
349350
350 anchors {351 anchors {
351 left: parent.left352 left: parent.left
352353
=== modified file 'src/app/webbrowser/NewTabView.qml'
--- src/app/webbrowser/NewTabView.qml 2015-10-12 12:00:35 +0000
+++ src/app/webbrowser/NewTabView.qml 2015-10-16 15:16:36 +0000
@@ -148,9 +148,12 @@
148 height: status == Loader.Ready ? item.height : 0148 height: status == Loader.Ready ? item.height : 0
149149
150 active: internal.seeMoreBookmarksView150 active: internal.seeMoreBookmarksView
151 sourceComponent: BookmarksFolderListView {151
152 sourceComponent: BookmarksFoldersView {
152 model: newTabView.bookmarksModel153 model: newTabView.bookmarksModel
153154
155 homeBookmarkUrl: newTabView.settingsObject.homepage
156
154 onBookmarkClicked: newTabView.bookmarkClicked(url)157 onBookmarkClicked: newTabView.bookmarkClicked(url)
155 onBookmarkRemoved: newTabView.bookmarkRemoved(url)158 onBookmarkRemoved: newTabView.bookmarkRemoved(url)
156 }159 }
157160
=== modified file 'src/app/webbrowser/NewTabViewWide.qml'
--- src/app/webbrowser/NewTabViewWide.qml 2015-10-05 10:10:29 +0000
+++ src/app/webbrowser/NewTabViewWide.qml 2015-10-16 15:16:36 +0000
@@ -26,7 +26,7 @@
26FocusScope {26FocusScope {
27 id: newTabViewWide27 id: newTabViewWide
2828
29 property QtObject bookmarksModel29 property alias bookmarksModel: bookmarksFoldersViewWide.model
30 property QtObject settingsObject30 property QtObject settingsObject
31 property alias selectedIndex: sections.selectedIndex31 property alias selectedIndex: sections.selectedIndex
32 readonly property bool inBookmarksView: newTabViewWide.selectedIndex === 132 readonly property bool inBookmarksView: newTabViewWide.selectedIndex === 1
@@ -41,13 +41,10 @@
41 onActiveFocusChanged: {41 onActiveFocusChanged: {
42 if (activeFocus) {42 if (activeFocus) {
43 if (inBookmarksView) {43 if (inBookmarksView) {
44 if (sections.lastFocusedBookmarksColumn === bookmarksList &&44 bookmarksFoldersViewWide.restoreLastFocusedColumn()
45 bookmarksList.model.length === 0) {45 } else {
46 sections.lastFocusedBookmarksColumn = folders46 topSitesList.focus = true
47 }
48 sections.lastFocusedBookmarksColumn.focus = true
49 }47 }
50 else topSitesList.focus = true
51 }48 }
52 }49 }
5350
@@ -62,178 +59,38 @@
62 }59 }
63 }60 }
6461
62 BookmarksFoldersViewWide {
63 id: bookmarksFoldersViewWide
64
65 Keys.onUpPressed: newTabViewWide.releasingKeyboardFocus()
66 onBookmarkClicked: newTabViewWide.bookmarkClicked(url)
67 onBookmarkRemoved: newTabViewWide.bookmarkRemoved(url)
68
69 // Relinquish focus as the presses and releases that compose the
70 // drag will move the keyboard focus in a location unexpected
71 // for the user. This way it will go back to the address bar and
72 // the user can predictably resume keyboard interaction from there.
73 onDragStarted: newTabViewWide.releasingKeyboardFocus()
74
75 anchors {
76 top: sectionsGroup.bottom
77 left: parent.left
78 right: parent.right
79 bottom: parent.bottom
80 topMargin: units.gu(2)
81 rightMargin: units.gu(2)
82 }
83
84 visible: inBookmarksView
85 homeBookmarkUrl: newTabViewWide.settingsObject.homepage
86 }
87
65 Rectangle {88 Rectangle {
66 anchors.fill: parent89 anchors.fill: parent
90 visible: !inBookmarksView
67 color: "#fbfbfb"91 color: "#fbfbfb"
68 }92 }
6993
70 ListView {
71 id: folders
72 objectName: "foldersList"
73 visible: inBookmarksView
74
75 Keys.onRightPressed: if (bookmarksList.model.length > 0) bookmarksList.focus = true
76 Keys.onDownPressed: currentIndex = Math.min(currentIndex + 1, folders.model.count - 1)
77 Keys.onUpPressed: {
78 if (currentIndex > 0) currentIndex = Math.max(currentIndex - 1, 0)
79 else newTabViewWide.releasingKeyboardFocus()
80 }
81 onActiveFocusChanged: {
82 if (activeFocus) {
83 sections.lastFocusedBookmarksColumn = folders
84 if (currentIndex < 0) currentIndex = 0
85 }
86 }
87
88 anchors {
89 top: sectionsGroup.bottom
90 bottom: parent.bottom
91 left: parent.left
92 topMargin: units.gu(2)
93 }
94 width: units.gu(25)
95
96 currentIndex: 0
97 model: BookmarksFolderListModel {
98 sourceModel: newTabViewWide.bookmarksModel
99 }
100
101 delegate: ListItem {
102 id: folderItem
103 objectName: "folderItem"
104 property var model: entries
105 property bool isActiveFolder: ListView.isCurrentItem
106 property bool isCurrentItem: ListView.isCurrentItem
107 property bool isAllBookmarksFolder: folder.length === 0
108 property alias name: dropArea.folderName
109 divider.visible: false
110
111 property bool isCurrentDropTarget: dropArea.containsDrag && dropArea.drag.source.folder !== folder
112 color: isCurrentDropTarget ? "green" :
113 ((folders.activeFocus && isActiveFolder) ? Qt.rgba(0, 0, 0, 0.05) : "transparent")
114
115 Label {
116 anchors.verticalCenter: parent.verticalCenter
117 anchors.left: parent.left
118 anchors.right: parent.right
119 anchors.leftMargin: units.gu(2)
120 anchors.rightMargin: units.gu(2)
121
122 fontSize: isAllBookmarksFolder ? "medium" : "small"
123 text: isAllBookmarksFolder ? i18n.tr("All Bookmarks") : folderItem.name
124 color: isActiveFolder ? UbuntuColors.orange : UbuntuColors.darkGrey
125 }
126
127 onClicked: folders.currentIndex = index
128
129 DropArea {
130 id: dropArea
131 anchors.fill: parent
132 property string folderName: folder
133 }
134 }
135 }
136
137 Scrollbar {
138 flickableItem: folders
139 }
140
141 ListView {
142 id: bookmarksList
143 objectName: "bookmarksList"
144 anchors {
145 top: sectionsGroup.bottom
146 bottom: parent.bottom
147 left: folders.right
148 right: parent.right
149 topMargin: units.gu(2)
150 }
151 visible: inBookmarksView
152 onActiveFocusChanged: if (activeFocus) sections.lastFocusedBookmarksColumn = bookmarksList
153
154 // Build a temporary model for the bookmarks list that includes, when
155 // necessary, the homepage bookmark as a fixed first item in the list
156 model: {
157 if (!folders.currentItem) return null
158
159 var items = []
160 if (folders.currentItem.isAllBookmarksFolder) items.push({
161 title: i18n.tr("Homepage"),
162 url: newTabViewWide.settingsObject.homepage,
163 folder: ""
164 })
165
166 if (!folders.currentItem.model) return null
167 for (var i = 0; i < folders.currentItem.model.count; i++) {
168 items.push(folders.currentItem.model.get(i))
169 }
170 return items
171 }
172
173 currentIndex: 0
174
175 delegate: DraggableUrlDelegateWide {
176 objectName: "bookmarkItem"
177 clip: true
178
179 title: modelData.title
180 icon: modelData.icon ? modelData.icon : ""
181 url: modelData.url
182
183 property string folder: modelData.folder
184 property bool isHomeBookmark: folder === "" && index === 0
185
186 removable: !isHomeBookmark
187 draggable: !isHomeBookmark && contentItem.x === 0
188 highlighted: bookmarksList.activeFocus && ListView.isCurrentItem
189
190 onClicked: newTabViewWide.bookmarkClicked(url)
191 onRemoved: newTabViewWide.bookmarkRemoved(url)
192
193 // Larger margin to prevent interference from Scrollbar hovering area
194 gripMargin: units.gu(4)
195 onDragStarted: {
196 // Remove interactivity to prevent the list from scrolling
197 // while dragging near its margins. This ensures we can correctly
198 // return the item to its original position on a failed drop.
199 bookmarksList.interactive = false
200
201 // Relinquish focus as the presses and releases that compose the
202 // drag will move the keyboard focus in a location unexpected
203 // for the user. This way it will go back to the address bar and
204 // the user can predictably resume keyboard interaction from there.
205 newTabViewWide.releasingKeyboardFocus()
206 }
207 onDragEnded: {
208 bookmarksList.interactive = true
209
210 if (dragAndDrop.target && dragAndDrop.target.folderName !== folder) {
211 bookmarksModel.update(modelData.url, modelData.title,
212 dragAndDrop.target.folderName)
213 dragAndDrop.success = true
214 }
215 }
216 }
217
218 Keys.onReturnPressed: newTabViewWide.bookmarkClicked(currentItem.url)
219 Keys.onDeletePressed: {
220 if (currentItem.removable) {
221 newTabViewWide.bookmarkRemoved(currentItem.url)
222 if (bookmarksList.model.length === 0) folders.focus = true
223 }
224 }
225 Keys.onLeftPressed: folders.focus = true
226 Keys.onDownPressed: currentIndex = Math.min(currentIndex + 1, model.length - 1)
227 Keys.onUpPressed: {
228 if (currentIndex > 0) currentIndex = Math.max(currentIndex - 1, 0)
229 else newTabViewWide.releasingKeyboardFocus()
230 }
231 }
232
233 Scrollbar {
234 flickableItem: bookmarksList
235 }
236
237 UrlPreviewGrid {94 UrlPreviewGrid {
238 id: topSitesList95 id: topSitesList
239 objectName: "topSitesList"96 objectName: "topSitesList"
@@ -286,14 +143,12 @@
286 selectedIndex: settingsObject.newTabDefaultSection143 selectedIndex: settingsObject.newTabDefaultSection
287 onSelectedIndexChanged: {144 onSelectedIndexChanged: {
288 settingsObject.newTabDefaultSection = selectedIndex145 settingsObject.newTabDefaultSection = selectedIndex
289 if (selectedIndex === 0) topSitesList.focus = true146 if (selectedIndex === 0) {
290 else {147 topSitesList.focus = true
291 if (lastFocusedBookmarksColumn) lastFocusedBookmarksColumn.focus = true148 } else {
292 else folders.focus = true149 bookmarksFoldersViewWide.restoreLastFocusedColumn()
293 }150 }
294
295 }151 }
296 property var lastFocusedBookmarksColumn: folders
297152
298 actions: [153 actions: [
299 Action { text: i18n.tr("Top sites") },154 Action { text: i18n.tr("Top sites") },
300155
=== modified file 'src/app/webbrowser/UrlDelegate.qml'
--- src/app/webbrowser/UrlDelegate.qml 2015-08-11 21:35:55 +0000
+++ src/app/webbrowser/UrlDelegate.qml 2015-10-16 15:16:36 +0000
@@ -29,6 +29,8 @@
2929
30 property alias headerComponent: headerComponentLoader.sourceComponent30 property alias headerComponent: headerComponentLoader.sourceComponent
3131
32 property bool removable: true
33
32 divider.visible: false34 divider.visible: false
3335
34 signal removed()36 signal removed()
@@ -83,7 +85,8 @@
83 }85 }
84 }86 }
8587
86 leadingActions: ListItemActions {88 ListItemActions {
89 id: listItemActions
87 actions: [90 actions: [
88 Action {91 Action {
89 objectName: "leadingAction.delete"92 objectName: "leadingAction.delete"
@@ -92,4 +95,6 @@
92 }95 }
93 ]96 ]
94 }97 }
98
99 leadingActions: removable ? listItemActions : null
95}100}
96101
=== modified file 'src/app/webbrowser/UrlDelegateWide.qml'
--- src/app/webbrowser/UrlDelegateWide.qml 2015-08-05 16:10:09 +0000
+++ src/app/webbrowser/UrlDelegateWide.qml 2015-10-16 15:16:36 +0000
@@ -32,7 +32,7 @@
32 color: highlighted ? Qt.rgba(0, 0, 0, 0.05) : "transparent"32 color: highlighted ? Qt.rgba(0, 0, 0, 0.05) : "transparent"
3333
34 divider.visible: false34 divider.visible: false
35 height: units.gu(7)35 height: units.gu(5)
3636
37 signal removed()37 signal removed()
3838
@@ -56,7 +56,7 @@
56 Label {56 Label {
57 id: title57 id: title
5858
59 fontSize: "small"59 fontSize: "x-small"
60 color: highlighted ? UbuntuColors.orange : UbuntuColors.darkGrey60 color: highlighted ? UbuntuColors.orange : UbuntuColors.darkGrey
61 wrapMode: Text.Wrap61 wrapMode: Text.Wrap
62 elide: Text.ElideRight62 elide: Text.ElideRight
@@ -66,7 +66,7 @@
66 Label {66 Label {
67 id: url67 id: url
6868
69 fontSize: "small"69 fontSize: "xx-small"
70 color: highlighted ? UbuntuColors.orange : UbuntuColors.darkGrey70 color: highlighted ? UbuntuColors.orange : UbuntuColors.darkGrey
71 wrapMode: Text.Wrap71 wrapMode: Text.Wrap
72 elide: Text.ElideRight72 elide: Text.ElideRight
7373
=== modified file 'tests/autopilot/webbrowser_app/emulators/browser.py'
--- tests/autopilot/webbrowser_app/emulators/browser.py 2015-10-08 15:26:18 +0000
+++ tests/autopilot/webbrowser_app/emulators/browser.py 2015-10-16 15:16:36 +0000
@@ -162,6 +162,17 @@
162 return self.wait_select_single("Dialog",162 return self.wait_select_single("Dialog",
163 objectName="newFolderDialog")163 objectName="newFolderDialog")
164164
165 # The bookmarks view is dynamically created, so it might or might not be
166 # available
167 def get_bookmarks_view(self):
168 try:
169 if self.wide:
170 return self.select_single("BookmarksViewWide")
171 else:
172 return self.select_single("BookmarksView")
173 except exceptions.StateNotFoundError:
174 return None
175
165 # The history view is dynamically created, so it might or might not be176 # The history view is dynamically created, so it might or might not be
166 # available177 # available
167 def get_history_view(self):178 def get_history_view(self):
@@ -540,7 +551,7 @@
540 return self.get_top_sites_list().get_delegates()551 return self.get_top_sites_list().get_delegates()
541552
542 def get_bookmarks_folder_list_view(self):553 def get_bookmarks_folder_list_view(self):
543 return self.select_single(BookmarksFolderListView)554 return self.wait_select_single(BookmarksFoldersView)
544555
545 def get_bookmarks(self, folder_name):556 def get_bookmarks(self, folder_name):
546 # assumes that the "more" button has been clicked557 # assumes that the "more" button has been clicked
@@ -667,7 +678,7 @@
667 self.pointing_device.click_object(button)678 self.pointing_device.click_object(button)
668679
669680
670class BookmarksFolderListView(uitk.UbuntuUIToolkitCustomProxyObjectBase):681class BookmarksFoldersView(uitk.UbuntuUIToolkitCustomProxyObjectBase):
671682
672 def get_delegates(self):683 def get_delegates(self):
673 return sorted(self.select_many("QQuickItem",684 return sorted(self.select_many("QQuickItem",
674685
=== modified file 'tests/autopilot/webbrowser_app/tests/__init__.py'
--- tests/autopilot/webbrowser_app/tests/__init__.py 2015-10-08 09:34:48 +0000
+++ tests/autopilot/webbrowser_app/tests/__init__.py 2015-10-16 15:16:36 +0000
@@ -195,6 +195,15 @@
195 self.pointing_device.click_object(settings_action)195 self.pointing_device.click_object(settings_action)
196 return self.main_window.get_settings_page()196 return self.main_window.get_settings_page()
197197
198 def open_bookmarks(self):
199 chrome = self.main_window.chrome
200 drawer_button = chrome.get_drawer_button()
201 self.pointing_device.click_object(drawer_button)
202 chrome.get_drawer()
203 bookmarks_action = chrome.get_drawer_action("bookmarks")
204 self.pointing_device.click_object(bookmarks_action)
205 return self.main_window.get_bookmarks_view()
206
198 def open_history(self):207 def open_history(self):
199 chrome = self.main_window.chrome208 chrome = self.main_window.chrome
200 drawer_button = chrome.get_drawer_button()209 drawer_button = chrome.get_drawer_button()
201210
=== modified file 'tests/autopilot/webbrowser_app/tests/test_bookmark_options.py'
--- tests/autopilot/webbrowser_app/tests/test_bookmark_options.py 2015-09-06 08:16:40 +0000
+++ tests/autopilot/webbrowser_app/tests/test_bookmark_options.py 2015-10-16 15:16:36 +0000
@@ -92,17 +92,18 @@
92 return self.main_window.get_bookmark_options()92 return self.main_window.get_bookmark_options()
9393
94 def _assert_bookmark_count_in_folder(self, tab, folder_name, count):94 def _assert_bookmark_count_in_folder(self, tab, folder_name, count):
95 # in wide mode the list of urls in the default folder has the homepage
96 # bookmark in it, but it does not in narrow mode
97 if self.main_window.wide and folder_name == "":
98 count += 1
99
100 urls = tab.get_bookmarks(folder_name)95 urls = tab.get_bookmarks(folder_name)
101 self.assertThat(lambda: len(urls), Eventually(Equals(count)))96 self.assertThat(lambda: len(urls), Eventually(Equals(count)))
10297
98 def _toggle_bookmark_folder(self, tab, folder_name):
99 folders = tab.get_bookmarks_folder_list_view()
100 folder_delegate = folders.get_folder_delegate(folder_name)
101 self.pointing_device.click_object(
102 folders.get_header_from_folder(folder_delegate))
103
103 def test_save_bookmarked_url_in_default_folder(self):104 def test_save_bookmarked_url_in_default_folder(self):
104 new_tab = self.open_new_tab(open_tabs_view=True, expand_view=True)105 new_tab = self.open_new_tab(open_tabs_view=True, expand_view=True)
105 self._assert_bookmark_count_in_folder(new_tab, "", 4)106 self._assert_bookmark_count_in_folder(new_tab, "", 5)
106107
107 url = self.base_url + "/test2"108 url = self.base_url + "/test2"
108 self.main_window.go_to_url(url)109 self.main_window.go_to_url(url)
@@ -118,12 +119,14 @@
118 self.assertThat(chrome.bookmarked, Eventually(Equals(True)))119 self.assertThat(chrome.bookmarked, Eventually(Equals(True)))
119120
120 new_tab = self.open_new_tab(open_tabs_view=True, expand_view=True)121 new_tab = self.open_new_tab(open_tabs_view=True, expand_view=True)
121 self._assert_bookmark_count_in_folder(new_tab, "", 5)122 self._assert_bookmark_count_in_folder(new_tab, "", 6)
122123
123 def test_save_bookmarked_url_in_existing_folder(self):124 def test_save_bookmarked_url_in_existing_folder(self):
124 new_tab = self.open_new_tab(open_tabs_view=True, expand_view=True)125 new_tab = self.open_new_tab(open_tabs_view=True, expand_view=True)
125 self.assertThat(lambda: len(new_tab.get_folder_names()),126 self.assertThat(lambda: len(new_tab.get_folder_names()),
126 Eventually(Equals(3)))127 Eventually(Equals(3)))
128 if not self.main_window.wide:
129 self._toggle_bookmark_folder(new_tab, "Actinide")
127 self._assert_bookmark_count_in_folder(new_tab, "Actinide", 1)130 self._assert_bookmark_count_in_folder(new_tab, "Actinide", 1)
128131
129 url = self.base_url + "/test2"132 url = self.base_url + "/test2"
@@ -154,6 +157,8 @@
154 new_tab = self.open_new_tab(open_tabs_view=True, expand_view=True)157 new_tab = self.open_new_tab(open_tabs_view=True, expand_view=True)
155 self.assertThat(lambda: len(new_tab.get_folder_names()),158 self.assertThat(lambda: len(new_tab.get_folder_names()),
156 Eventually(Equals(3)))159 Eventually(Equals(3)))
160 if not self.main_window.wide:
161 self._toggle_bookmark_folder(new_tab, "Actinide")
157 self._assert_bookmark_count_in_folder(new_tab, "Actinide", 2)162 self._assert_bookmark_count_in_folder(new_tab, "Actinide", 2)
158163
159 def test_save_bookmarked_url_in_new_folder(self):164 def test_save_bookmarked_url_in_new_folder(self):
@@ -198,6 +203,8 @@
198 new_tab = self.open_new_tab(open_tabs_view=True, expand_view=True)203 new_tab = self.open_new_tab(open_tabs_view=True, expand_view=True)
199 self.assertThat(lambda: len(new_tab.get_folder_names()),204 self.assertThat(lambda: len(new_tab.get_folder_names()),
200 Eventually(Equals(4)))205 Eventually(Equals(4)))
206 if not self.main_window.wide:
207 self._toggle_bookmark_folder(new_tab, "NewFolder")
201 self._assert_bookmark_count_in_folder(new_tab, "NewFolder", 1)208 self._assert_bookmark_count_in_folder(new_tab, "NewFolder", 1)
202209
203 def test_set_bookmark_title(self):210 def test_set_bookmark_title(self):
@@ -223,12 +230,9 @@
223 self.assertThat(chrome.bookmarked, Eventually(Equals(True)))230 self.assertThat(chrome.bookmarked, Eventually(Equals(True)))
224231
225 new_tab = self.open_new_tab(open_tabs_view=True, expand_view=True)232 new_tab = self.open_new_tab(open_tabs_view=True, expand_view=True)
226 self._assert_bookmark_count_in_folder(new_tab, "", 5)233 self._assert_bookmark_count_in_folder(new_tab, "", 6)
227234
228 index = 0235 bookmark = new_tab.get_bookmarks("")[1]
229 if self.main_window.wide:
230 index += 1
231 bookmark = new_tab.get_bookmarks("")[index]
232 self.assertThat(bookmark.title, Equals("NewTitle"))236 self.assertThat(bookmark.title, Equals("NewTitle"))
233237
234 def test_bookmark_options_from_contextual_menu(self):238 def test_bookmark_options_from_contextual_menu(self):
235239
=== modified file 'tests/autopilot/webbrowser_app/tests/test_keyboard.py'
--- tests/autopilot/webbrowser_app/tests/test_keyboard.py 2015-09-29 13:15:01 +0000
+++ tests/autopilot/webbrowser_app/tests/test_keyboard.py 2015-10-16 15:16:36 +0000
@@ -273,6 +273,39 @@
273 self.assertThat(lambda: self.main_window.get_current_webview().url,273 self.assertThat(lambda: self.main_window.get_current_webview().url,
274 Eventually(Equals(url)))274 Eventually(Equals(url)))
275275
276 def test_toggle_bookmarks(self):
277 self.assertThat(self.main_window.get_bookmarks_view(), Equals(None))
278 self.main_window.press_key('Ctrl+Shift+O')
279 self.assertThat(lambda: self.main_window.get_bookmarks_view(),
280 Eventually(NotEquals(None)))
281 bookmarks_view = self.main_window.get_bookmarks_view()
282
283 self.main_window.press_key('Escape')
284 bookmarks_view.wait_until_destroyed()
285 webview = self.main_window.get_current_webview()
286 self.assertThat(webview.activeFocus, Eventually(Equals(True)))
287
288 def test_toggle_bookmarks_from_menu(self):
289 self.assertThat(self.main_window.get_bookmarks_view(), Equals(None))
290 self.open_bookmarks()
291 bookmarks_view = self.main_window.get_bookmarks_view()
292 self.assertThat(bookmarks_view.activeFocus, Eventually(Equals(True)))
293
294 self.main_window.press_key('Escape')
295 bookmarks_view.wait_until_destroyed()
296
297 def test_new_tab_from_bookmarks_view(self):
298 self.assertThat(self.main_window.get_bookmarks_view(), Equals(None))
299 self.open_bookmarks()
300 bookmarks_view = self.main_window.get_bookmarks_view()
301 self.assertThat(bookmarks_view.activeFocus, Eventually(Equals(True)))
302
303 self.main_window.press_key('Ctrl+T')
304 bookmarks_view.wait_until_destroyed()
305
306 new_tab_view = self.main_window.get_new_tab_view()
307 self.assertThat(new_tab_view.visible, Eventually(Equals(True)))
308
276 def test_toggle_history(self):309 def test_toggle_history(self):
277 self.assertThat(self.main_window.get_history_view(), Equals(None))310 self.assertThat(self.main_window.get_history_view(), Equals(None))
278 self.main_window.press_key('Ctrl+H')311 self.main_window.press_key('Ctrl+H')
@@ -294,6 +327,18 @@
294 self.main_window.press_key('Escape')327 self.main_window.press_key('Escape')
295 history_view.wait_until_destroyed()328 history_view.wait_until_destroyed()
296329
330 def test_new_tab_from_history_view(self):
331 self.assertThat(self.main_window.get_history_view(), Equals(None))
332 self.open_history()
333 history_view = self.main_window.get_history_view()
334 self.assertThat(history_view.activeFocus, Eventually(Equals(True)))
335
336 self.main_window.press_key('Ctrl+T')
337 history_view.wait_until_destroyed()
338
339 new_tab_view = self.main_window.get_new_tab_view()
340 self.assertThat(new_tab_view.visible, Eventually(Equals(True)))
341
297 def test_escape_settings(self):342 def test_escape_settings(self):
298 settings = self.open_settings()343 settings = self.open_settings()
299 self.main_window.press_key('Escape')344 self.main_window.press_key('Escape')
300345
=== modified file 'tests/autopilot/webbrowser_app/tests/test_new_tab_view.py'
--- tests/autopilot/webbrowser_app/tests/test_new_tab_view.py 2015-10-13 11:21:01 +0000
+++ tests/autopilot/webbrowser_app/tests/test_new_tab_view.py 2015-10-16 15:16:36 +0000
@@ -255,7 +255,7 @@
255 folder_delegate = folders.get_folder_delegate("")255 folder_delegate = folders.get_folder_delegate("")
256 self.assertThat(lambda: len(folders.get_urls_from_folder(256 self.assertThat(lambda: len(folders.get_urls_from_folder(
257 folder_delegate)),257 folder_delegate)),
258 Eventually(Equals(4)))258 Eventually(Equals(5)))
259 bookmark = folders.get_urls_from_folder(folder_delegate)[0]259 bookmark = folders.get_urls_from_folder(folder_delegate)[0]
260 url = bookmark.url260 url = bookmark.url
261 self.pointing_device.click_object(bookmark)261 self.pointing_device.click_object(bookmark)
@@ -277,7 +277,7 @@
277 folder_delegate = folders.get_folder_delegate("")277 folder_delegate = folders.get_folder_delegate("")
278 self.assertThat(lambda: len(folders.get_urls_from_folder(278 self.assertThat(lambda: len(folders.get_urls_from_folder(
279 folder_delegate)),279 folder_delegate)),
280 Eventually(Equals(4)))280 Eventually(Equals(5)))
281 self.assertThat(top_sites.visible, Eventually(Equals(False)))281 self.assertThat(top_sites.visible, Eventually(Equals(False)))
282 # Collapse again282 # Collapse again
283 self.assertThat(more_button.visible, Equals(True))283 self.assertThat(more_button.visible, Equals(True))
@@ -308,6 +308,12 @@
308 lambda: folders.get_urls_from_folder(folder_delegate)[0],308 lambda: folders.get_urls_from_folder(folder_delegate)[0],
309 Eventually(NotEquals(url)))309 Eventually(NotEquals(url)))
310310
311 def _toggle_bookmark_folder(self, folder):
312 folders = self.new_tab_view.get_bookmarks_folder_list_view()
313 folder_delegate = folders.get_folder_delegate(folder)
314 self.pointing_device.click_object(
315 folders.get_header_from_folder(folder_delegate))
316
311 def test_remove_bookmarks_when_collapsed(self):317 def test_remove_bookmarks_when_collapsed(self):
312 bookmarks = self.new_tab_view.get_bookmarks_list()318 bookmarks = self.new_tab_view.get_bookmarks_list()
313 self.assertThat(lambda: len(bookmarks.get_delegates()),319 self.assertThat(lambda: len(bookmarks.get_delegates()),
@@ -327,10 +333,12 @@
327 folder_delegate = folders.get_folder_delegate("")333 folder_delegate = folders.get_folder_delegate("")
328 self.assertThat(lambda: len(folders.get_urls_from_folder(334 self.assertThat(lambda: len(folders.get_urls_from_folder(
329 folder_delegate)),335 folder_delegate)),
330 Eventually(Equals(4)))336 Eventually(Equals(5)))
331 more_button = self.new_tab_view.get_bookmarks_more_button()337 more_button = self.new_tab_view.get_bookmarks_more_button()
332 top_sites = self.new_tab_view.get_top_sites_list()338 top_sites = self.new_tab_view.get_top_sites_list()
339 self._toggle_bookmark_folder("Actinide")
333 self._remove_first_bookmark_from_folder("Actinide")340 self._remove_first_bookmark_from_folder("Actinide")
341 self._toggle_bookmark_folder("NobleGas")
334 self._remove_first_bookmark_from_folder("NobleGas")342 self._remove_first_bookmark_from_folder("NobleGas")
335 self.assertThat(more_button.visible, Eventually(Equals(False)))343 self.assertThat(more_button.visible, Eventually(Equals(False)))
336 self.assertThat(top_sites.visible, Eventually(Equals(True)))344 self.assertThat(top_sites.visible, Eventually(Equals(True)))
@@ -345,15 +353,37 @@
345 folder_delegate = folders.get_folder_delegate("")353 folder_delegate = folders.get_folder_delegate("")
346 self.assertThat(lambda: len(folders.get_urls_from_folder(354 self.assertThat(lambda: len(folders.get_urls_from_folder(
347 folder_delegate)),355 folder_delegate)),
348 Eventually(Equals(4)))356 Eventually(Equals(5)))
349 folder_delegate = folders.get_folder_delegate("Actinide")357 self._toggle_bookmark_folder("Actinide")
350 self.assertThat(lambda: len(folders.get_urls_from_folder(358 folder_delegate = folders.get_folder_delegate("Actinide")
351 folder_delegate)),359 self.assertThat(lambda: len(folders.get_urls_from_folder(
352 Eventually(Equals(1)))360 folder_delegate)),
353 folder_delegate = folders.get_folder_delegate("NobleGas")361 Eventually(Equals(1)))
354 self.assertThat(lambda: len(folders.get_urls_from_folder(362 self._toggle_bookmark_folder("NobleGas")
355 folder_delegate)),363 folder_delegate = folders.get_folder_delegate("NobleGas")
356 Eventually(Equals(1)))364 self.assertThat(lambda: len(folders.get_urls_from_folder(
365 folder_delegate)),
366 Eventually(Equals(1)))
367
368 def test_collapsed_bookmarks_folders_when_expanded(self):
369 more_button = self.new_tab_view.get_bookmarks_more_button()
370 self.assertThat(more_button.visible, Equals(True))
371 self.pointing_device.click_object(more_button)
372 folders = self.new_tab_view.get_bookmarks_folder_list_view()
373 self.assertThat(lambda: len(folders.get_delegates()),
374 Eventually(Equals(3)))
375 folder_delegate = folders.get_folder_delegate("")
376 self.assertThat(lambda: len(folders.get_urls_from_folder(
377 folder_delegate)),
378 Eventually(Equals(5)))
379 folder_delegate = folders.get_folder_delegate("Actinide")
380 self.assertThat(lambda: len(folders.get_urls_from_folder(
381 folder_delegate)),
382 Eventually(Equals(0)))
383 folder_delegate = folders.get_folder_delegate("NobleGas")
384 self.assertThat(lambda: len(folders.get_urls_from_folder(
385 folder_delegate)),
386 Eventually(Equals(0)))
357387
358 def test_hide_empty_bookmarks_folders_when_expanded(self):388 def test_hide_empty_bookmarks_folders_when_expanded(self):
359 more_button = self.new_tab_view.get_bookmarks_more_button()389 more_button = self.new_tab_view.get_bookmarks_more_button()
@@ -362,6 +392,7 @@
362 folders = self.new_tab_view.get_bookmarks_folder_list_view()392 folders = self.new_tab_view.get_bookmarks_folder_list_view()
363 self.assertThat(lambda: len(folders.get_delegates()),393 self.assertThat(lambda: len(folders.get_delegates()),
364 Eventually(Equals(3)))394 Eventually(Equals(3)))
395 self._toggle_bookmark_folder("Actinide")
365 folder_delegate = folders.get_folder_delegate("Actinide")396 folder_delegate = folders.get_folder_delegate("Actinide")
366 self.assertThat(lambda: len(folders.get_urls_from_folder(397 self.assertThat(lambda: len(folders.get_urls_from_folder(
367 folder_delegate)),398 folder_delegate)),
@@ -372,7 +403,8 @@
372 folder_delegate = folders.get_folder_delegate("")403 folder_delegate = folders.get_folder_delegate("")
373 self.assertThat(lambda: len(folders.get_urls_from_folder(404 self.assertThat(lambda: len(folders.get_urls_from_folder(
374 folder_delegate)),405 folder_delegate)),
375 Eventually(Equals(4)))406 Eventually(Equals(5)))
407 self._toggle_bookmark_folder("NobleGas")
376 folder_delegate = folders.get_folder_delegate("NobleGas")408 folder_delegate = folders.get_folder_delegate("NobleGas")
377 self.assertThat(lambda: len(folders.get_urls_from_folder(409 self.assertThat(lambda: len(folders.get_urls_from_folder(
378 folder_delegate)),410 folder_delegate)),
@@ -388,7 +420,7 @@
388 folder_delegate = folders.get_folder_delegate("")420 folder_delegate = folders.get_folder_delegate("")
389 self.assertThat(lambda: len(folders.get_urls_from_folder(421 self.assertThat(lambda: len(folders.get_urls_from_folder(
390 folder_delegate)),422 folder_delegate)),
391 Eventually(Equals(4)))423 Eventually(Equals(5)))
392 self.pointing_device.click_object(424 self.pointing_device.click_object(
393 folders.get_header_from_folder(folder_delegate))425 folders.get_header_from_folder(folder_delegate))
394 self.assertThat(lambda: len(folders.get_urls_from_folder(426 self.assertThat(lambda: len(folders.get_urls_from_folder(
@@ -398,7 +430,7 @@
398 folders.get_header_from_folder(folder_delegate))430 folders.get_header_from_folder(folder_delegate))
399 self.assertThat(lambda: len(folders.get_urls_from_folder(431 self.assertThat(lambda: len(folders.get_urls_from_folder(
400 folder_delegate)),432 folder_delegate)),
401 Eventually(Equals(4)))433 Eventually(Equals(5)))
402434
403 def test_remove_top_sites(self):435 def test_remove_top_sites(self):
404 top_sites = self.new_tab_view.get_top_sites_list()436 top_sites = self.new_tab_view.get_top_sites_list()
405437
=== added file 'tests/unittests/qml/tst_BookmarksFoldersViewWide.qml'
--- tests/unittests/qml/tst_BookmarksFoldersViewWide.qml 1970-01-01 00:00:00 +0000
+++ tests/unittests/qml/tst_BookmarksFoldersViewWide.qml 2015-10-16 15:16:36 +0000
@@ -0,0 +1,257 @@
1/*
2 * Copyright 2015 Canonical Ltd.
3 *
4 * This file is part of webbrowser-app.
5 *
6 * webbrowser-app is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * webbrowser-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19import QtQuick 2.4
20import QtTest 1.0
21import Ubuntu.Test 1.0
22import "../../../src/app/webbrowser"
23import webbrowserapp.private 0.1
24
25Item {
26 id: root
27
28 width: 800
29 height: 600
30
31 Component {
32 id: bookmarksModel
33 BookmarksModel {
34 databasePath: ":memory:"
35 }
36 }
37
38 property BookmarksFoldersViewWide view
39 property var bookmarks
40 property string homepage: "http://example.com/homepage"
41
42 Component {
43 id: viewComponent
44 BookmarksFoldersViewWide {
45 anchors.fill: parent
46 homeBookmarkUrl: homepage
47 model: bookmarks
48 }
49 }
50
51 SignalSpy {
52 id: bookmarkClickedSpy
53 signalName: "bookmarkClicked"
54 }
55
56 SignalSpy {
57 id: bookmarkRemovedSpy
58 signalName: "bookmarkRemoved"
59 }
60
61 UbuntuTestCase {
62 name: "BookmarksFoldersViewWide"
63 when: windowShown
64
65 function init() {
66 bookmarks = bookmarksModel.createObject()
67 view = viewComponent.createObject(root)
68 populate()
69
70 view.focus = true
71
72 bookmarkClickedSpy.target = view
73 bookmarkClickedSpy.clear()
74 bookmarkRemovedSpy.target = view
75 bookmarkRemovedSpy.clear()
76 }
77
78 function populate() {
79 bookmarks.add("http://example.com", "Example Com", "", "")
80 bookmarks.add("http://example.org/bar", "Example Org Bar", "", "Folder B")
81 bookmarks.add("http://example.org/foo", "Example Org Foo", "", "Folder B")
82 bookmarks.add("http://example.net/a", "Example Net A", "", "Folder A")
83 bookmarks.add("http://example.net/b", "Example Net B", "", "Folder A")
84 }
85
86 function cleanup() {
87 bookmarks.destroy()
88 bookmarks = null
89
90 view.destroy()
91 view = null
92 }
93
94 function clickItem(item) {
95 var center = centerOf(item)
96 mouseClick(item, center.x, center.y)
97 }
98
99 function getListItems(name, itemName) {
100 var list = findChild(view, name)
101 var items = []
102 if (list) {
103 // ensure all the delegates are created
104 list.cacheBuffer = list.count * 1000
105
106 // In some cases the ListView might add other children to the
107 // contentItem, so we filter the list of children to include
108 // only actual delegates
109 var children = list.contentItem.children
110 for (var i = 0; i < children.length; i++) {
111 if (children[i].objectName === itemName) {
112 items.push(children[i])
113 }
114 }
115 }
116 return items
117 }
118
119 function test_folder_list() {
120 var items = getListItems("foldersList", "folderItem")
121 compare(items.length, 3)
122 verify(items[0].isAllBookmarksFolder)
123 compare(items[0].model.folder, "")
124 // named folder items should appear alphabetically sorted
125 compare(items[1].model.folder, "Folder A")
126 compare(items[2].model.folder, "Folder B")
127 }
128
129 function test_all_bookmarks_list() {
130 var items = getListItems("bookmarksList", "bookmarkItem")
131 compare(items.length, 2)
132 compare(items[0].url, homepage)
133 compare(items[1].title, "Example Com")
134 }
135
136 function test_navigate_folders_by_keyboard() {
137 var foldersList = getListItems(view, "foldersList")
138 var folders = getListItems("foldersList", "folderItem")
139 verify(folders[0].isActiveFolder)
140
141 keyClick(Qt.Key_Down)
142 verify(!folders[0].isActiveFolder)
143 verify(folders[1].isActiveFolder)
144
145 // bookmarks within a folder are sorted with the first bookmarked appearing last
146 var items = getListItems("bookmarksList", "bookmarkItem")
147 compare(items[0].title, "Example Net B")
148 compare(items[1].title, "Example Net A")
149 compare(items.length, 2)
150
151 keyClick(Qt.Key_Down)
152 verify(folders[2].isActiveFolder)
153 items = getListItems("bookmarksList", "bookmarkItem")
154 compare(items[0].title, "Example Org Foo")
155 compare(items[1].title, "Example Org Bar")
156 compare(items.length, 2)
157
158 // verify scrolling beyond bottom of list is not allowed
159 keyClick(Qt.Key_Down)
160 verify(folders[2].isActiveFolder)
161
162 keyClick(Qt.Key_Up)
163 verify(folders[1].isActiveFolder)
164 keyClick(Qt.Key_Up)
165 verify(folders[0].isActiveFolder)
166
167 keyClick(Qt.Key_Up)
168 }
169
170 function test_switch_between_folder_and_bookmarks_by_keyboard() {
171 var foldersList = findChild(view, "foldersList")
172 var bookmarks = findChild(view, "bookmarksList")
173 var folders = getListItems("foldersList", "folderItem")
174
175 verify(folders[0].isActiveFolder)
176
177 keyClick(Qt.Key_Right)
178 verify(bookmarks.activeFocus)
179 keyClick(Qt.Key_Right)
180 verify(bookmarks.activeFocus) // verify no circular scrolling
181
182 keyClick(Qt.Key_Left)
183 verify(foldersList.activeFocus)
184 keyClick(Qt.Key_Left)
185 verify(foldersList.activeFocus) // verify no circular scrolling
186
187 keyClick(Qt.Key_Down)
188 verify(!folders[0].isActiveFolder)
189 verify(folders[1].isActiveFolder)
190
191 keyClick(Qt.Key_Right)
192 verify(bookmarks.activeFocus)
193 keyClick(Qt.Key_Right)
194 verify(bookmarks.activeFocus) // verify no circular scrolling
195
196 keyClick(Qt.Key_Left)
197 verify(foldersList.activeFocus)
198 keyClick(Qt.Key_Left)
199 verify(foldersList.activeFocus) // verify no circular scrolling
200 }
201
202 function test_activate_bookmarks_by_keyboard() {
203 keyClick(Qt.Key_Right)
204
205 var items = getListItems("bookmarksList", "bookmarkItem")
206 keyClick(Qt.Key_Return)
207 compare(bookmarkClickedSpy.count, 1)
208 compare(bookmarkClickedSpy.signalArguments[0][0], homepage)
209
210 keyClick(Qt.Key_Down)
211 keyClick(Qt.Key_Return)
212 compare(bookmarkClickedSpy.count, 2)
213 compare(bookmarkClickedSpy.signalArguments[1][0], "http://example.com")
214 }
215
216 function test_activate_bookmarks_by_mouse() {
217 var items = getListItems("bookmarksList", "bookmarkItem")
218 clickItem(items[0])
219 compare(bookmarkClickedSpy.count, 1)
220 compare(bookmarkClickedSpy.signalArguments[0][0], homepage)
221
222 clickItem(items[1])
223 compare(bookmarkClickedSpy.count, 2)
224 compare(bookmarkClickedSpy.signalArguments[1][0], "http://example.com")
225 }
226
227 function test_switch_folders_by_mouse() {
228 var folders = getListItems("foldersList", "folderItem")
229
230 clickItem(folders[1])
231 var items = getListItems("bookmarksList", "bookmarkItem")
232 compare(items[0].title, "Example Net B")
233 compare(items[1].title, "Example Net A")
234 compare(items.length, 2)
235
236 clickItem(folders[0])
237 items = getListItems("bookmarksList", "bookmarkItem")
238 compare(items[0].url, homepage)
239 compare(items[1].title, "Example Com")
240 compare(items.length, 2)
241 }
242
243 function test_remove_bookmarks_by_keyboard() {
244 keyClick(Qt.Key_Right)
245 var items = getListItems("bookmarksList", "bookmarkItem")
246
247 // verify that trying to delete the homepage bookmark does not work
248 keyClick(Qt.Key_Delete)
249 compare(bookmarkRemovedSpy.count, 0)
250
251 keyClick(Qt.Key_Down)
252 keyClick(Qt.Key_Delete)
253 compare(bookmarkRemovedSpy.count, 1)
254 compare(bookmarkRemovedSpy.signalArguments[0][0], items[1].url)
255 }
256 }
257}
0258
=== modified file 'tests/unittests/qml/tst_NewTabViewWide.qml'
--- tests/unittests/qml/tst_NewTabViewWide.qml 2015-09-10 11:29:53 +0000
+++ tests/unittests/qml/tst_NewTabViewWide.qml 2015-10-16 15:16:36 +0000
@@ -161,23 +161,6 @@
161 }161 }
162 }162 }
163163
164 function test_folder_list() {
165 var items = getListItems("foldersList", "folderItem")
166 compare(items.length, 3)
167 verify(items[0].isAllBookmarksFolder)
168 compare(items[0].model.folder, "")
169 // named folder items should appear alphabetically sorted
170 compare(items[1].model.folder, "Folder A")
171 compare(items[2].model.folder, "Folder B")
172 }
173
174 function test_all_bookmarks_list() {
175 var items = getListItems("bookmarksList", "bookmarkItem")
176 compare(items.length, 2)
177 compare(items[0].url, homepage)
178 compare(items[1].title, "Example Com")
179 }
180
181 function test_switch_sections_by_keyboard() {164 function test_switch_sections_by_keyboard() {
182 skip("Would fail due to UITK bug: http://pad.lv/1481233")165 skip("Would fail due to UITK bug: http://pad.lv/1481233")
183 var sections = findChild(view, "sections")166 var sections = findChild(view, "sections")
@@ -232,75 +215,6 @@
232 compare(historyEntryClickedSpy.signalArguments[1][0], "http://example.org")215 compare(historyEntryClickedSpy.signalArguments[1][0], "http://example.org")
233 }216 }
234217
235 function test_navigate_folders_by_keyboard() {
236 goToBookmarks()
237
238 var foldersList = getListItems(view, "foldersList")
239 var folders = getListItems("foldersList", "folderItem")
240 verify(folders[0].isActiveFolder)
241
242 keyClick(Qt.Key_Down)
243 verify(!folders[0].isActiveFolder)
244 verify(folders[1].isActiveFolder)
245
246 // bookmarks within a folder are sorted with the first bookmarked appearing last
247 var items = getListItems("bookmarksList", "bookmarkItem")
248 compare(items[0].title, "Example Net B")
249 compare(items[1].title, "Example Net A")
250 compare(items.length, 2)
251
252 keyClick(Qt.Key_Down)
253 verify(folders[2].isActiveFolder)
254 items = getListItems("bookmarksList", "bookmarkItem")
255 compare(items[0].title, "Example Org Foo")
256 compare(items[1].title, "Example Org Bar")
257 compare(items.length, 2)
258
259 // verify scrolling beyond bottom of list is not allowed
260 keyClick(Qt.Key_Down)
261 verify(folders[2].isActiveFolder)
262
263 keyClick(Qt.Key_Up)
264 verify(folders[1].isActiveFolder)
265 keyClick(Qt.Key_Up)
266 verify(folders[0].isActiveFolder)
267
268 keyClick(Qt.Key_Up)
269 compare(releasingKeyboardFocusSpy.count, 1)
270 }
271
272 function test_switch_between_folder_and_bookmarks_by_keyboard() {
273 goToBookmarks()
274
275 var folders = findChild(view, "foldersList")
276 var bookmarks = findChild(view, "bookmarksList")
277
278 keyClick(Qt.Key_Right)
279 verify(bookmarks.activeFocus)
280 keyClick(Qt.Key_Right)
281 verify(bookmarks.activeFocus) // verify no circular scrolling
282
283 keyClick(Qt.Key_Left)
284 verify(folders.activeFocus)
285 keyClick(Qt.Key_Left)
286 verify(folders.activeFocus) // verify no circular scrolling
287 }
288
289 function test_activate_bookmarks_by_keyboard() {
290 goToBookmarks()
291 keyClick(Qt.Key_Right)
292
293 var items = getListItems("bookmarksList", "bookmarkItem")
294 keyClick(Qt.Key_Return)
295 compare(bookmarkClickedSpy.count, 1)
296 compare(bookmarkClickedSpy.signalArguments[0][0], homepage)
297
298 keyClick(Qt.Key_Down)
299 keyClick(Qt.Key_Return)
300 compare(bookmarkClickedSpy.count, 2)
301 compare(bookmarkClickedSpy.signalArguments[1][0], "http://example.com")
302 }
303
304 function test_activate_topsites_by_mouse() {218 function test_activate_topsites_by_mouse() {
305 var items = getListItems("topSitesList", "topSiteItem")219 var items = getListItems("topSitesList", "topSiteItem")
306 clickItem(items[0])220 clickItem(items[0])
@@ -313,50 +227,6 @@
313227
314 }228 }
315229
316 function test_activate_bookmarks_by_mouse() {
317 goToBookmarks()
318 var items = getListItems("bookmarksList", "bookmarkItem")
319 clickItem(items[0])
320 compare(bookmarkClickedSpy.count, 1)
321 compare(bookmarkClickedSpy.signalArguments[0][0], homepage)
322
323 clickItem(items[1])
324 compare(bookmarkClickedSpy.count, 2)
325 compare(bookmarkClickedSpy.signalArguments[1][0], "http://example.com")
326 }
327
328 function test_switch_folders_by_mouse() {
329 goToBookmarks()
330 var folders = getListItems("foldersList", "folderItem")
331
332 clickItem(folders[1])
333 var items = getListItems("bookmarksList", "bookmarkItem")
334 compare(items[0].title, "Example Net B")
335 compare(items[1].title, "Example Net A")
336 compare(items.length, 2)
337
338 clickItem(folders[0])
339 items = getListItems("bookmarksList", "bookmarkItem")
340 compare(items[0].url, homepage)
341 compare(items[1].title, "Example Com")
342 compare(items.length, 2)
343 }
344
345 function test_remove_bookmarks_by_keyboard() {
346 goToBookmarks()
347 keyClick(Qt.Key_Right)
348 var items = getListItems("bookmarksList", "bookmarkItem")
349
350 // verify that trying to delete the homepage bookmark does not work
351 keyClick(Qt.Key_Delete)
352 compare(bookmarkRemovedSpy.count, 0)
353
354 keyClick(Qt.Key_Down)
355 keyClick(Qt.Key_Delete)
356 compare(bookmarkRemovedSpy.count, 1)
357 compare(bookmarkRemovedSpy.signalArguments[0][0], items[1].url)
358 }
359
360 function test_remove_top_sites_by_keyboard() {230 function test_remove_top_sites_by_keyboard() {
361 var previous = getListItems("topSitesList", "topSiteItem")231 var previous = getListItems("topSitesList", "topSiteItem")
362 keyClick(Qt.Key_Delete)232 keyClick(Qt.Key_Delete)

Subscribers

People subscribed via source and target branches

to status/vote changes: