Bug 669905 - Searching in Downloads folder should limit the search to downloads.

r=dietrich
This commit is contained in:
Marco Bonardo 2011-08-19 15:01:21 +02:00
Родитель 824f5b5821
Коммит a0e2a6b3a1
4 изменённых файлов: 163 добавлений и 93 удалений

Просмотреть файл

@ -277,17 +277,30 @@ var PlacesOrganizer = {
* the node to set up scope from * the node to set up scope from
*/ */
_setSearchScopeForNode: function PO__setScopeForNode(aNode) { _setSearchScopeForNode: function PO__setScopeForNode(aNode) {
var itemId = aNode.itemId; let itemId = aNode.itemId;
// Set default buttons status.
let bookmarksButton = document.getElementById("scopeBarAll");
bookmarksButton.hidden = false;
let downloadsButton = document.getElementById("scopeBarDownloads");
downloadsButton.hidden = true;
if (PlacesUtils.nodeIsHistoryContainer(aNode) || if (PlacesUtils.nodeIsHistoryContainer(aNode) ||
itemId == PlacesUIUtils.leftPaneQueries["History"]) { itemId == PlacesUIUtils.leftPaneQueries["History"]) {
PlacesQueryBuilder.setScope("history"); PlacesQueryBuilder.setScope("history");
} }
// Default to All Bookmarks for all other nodes, per bug 469437. else if (itemId == PlacesUIUtils.leftPaneQueries["Downloads"]) {
else downloadsButton.hidden = false;
bookmarksButton.hidden = true;
PlacesQueryBuilder.setScope("downloads");
}
else {
// Default to All Bookmarks for all other nodes, per bug 469437.
PlacesQueryBuilder.setScope("bookmarks"); PlacesQueryBuilder.setScope("bookmarks");
}
// Enable or disable the folder scope button. // Enable or disable the folder scope button.
var folderButton = document.getElementById("scopeBarFolder"); let folderButton = document.getElementById("scopeBarFolder");
folderButton.hidden = !PlacesUtils.nodeIsFolder(aNode) || folderButton.hidden = !PlacesUtils.nodeIsFolder(aNode) ||
itemId == PlacesUIUtils.allBookmarksFolderId; itemId == PlacesUIUtils.allBookmarksFolderId;
}, },
@ -901,9 +914,21 @@ var PlacesSearchBox = {
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY; options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY;
content.load([query], options); content.load([query], options);
} }
else else {
content.applyFilter(filterString); content.applyFilter(filterString);
}
break; break;
case "downloads": {
let query = PlacesUtils.history.getNewQuery();
query.searchTerms = filterString;
query.setTransitions([Ci.nsINavHistoryService.TRANSITION_DOWNLOAD], 1);
let options = currentOptions.clone();
// Make sure we're getting uri results.
options.resultType = currentOptions.RESULT_TYPE_URI;
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY;
content.load([query], options);
break;
}
default: default:
throw "Invalid filterCollection on search"; throw "Invalid filterCollection on search";
break; break;
@ -933,17 +958,28 @@ var PlacesSearchBox = {
/** /**
* Updates the display with the title of the current collection. * Updates the display with the title of the current collection.
* @param title * @param aTitle
* The title of the current collection. * The title of the current collection.
*/ */
updateCollectionTitle: function PSB_updateCollectionTitle(title) { updateCollectionTitle: function PSB_updateCollectionTitle(aTitle) {
if (title) let title = "";
this.searchFilter.placeholder = if (aTitle) {
PlacesUIUtils.getFormattedString("searchCurrentDefault", [title]); title = PlacesUIUtils.getFormattedString("searchCurrentDefault",
else [aTitle]);
this.searchFilter.placeholder = this.filterCollection == "history" ? }
PlacesUIUtils.getString("searchHistory") : else {
PlacesUIUtils.getString("searchBookmarks"); switch(this.filterCollection) {
case "history":
title = PlacesUIUtils.getString("searchHistory");
break;
case "downloads":
title = PlacesUIUtils.getString("searchDownloads");
break;
default:
title = PlacesUIUtils.getString("searchBookmarks");
}
}
this.searchFilter.placeholder = title;
}, },
/** /**
@ -1025,6 +1061,9 @@ var PlacesQueryBuilder = {
case "scopeBarFolder": case "scopeBarFolder":
this.setScope("collection"); this.setScope("collection");
break; break;
case "scopeBarDownloads":
this.setScope("downloads");
break;
case "scopeBarAll": case "scopeBarAll":
this.setScope("bookmarks"); this.setScope("bookmarks");
break; break;
@ -1040,7 +1079,8 @@ var PlacesQueryBuilder = {
* PSB_search()). If there is an active search, it's performed again to * PSB_search()). If there is an active search, it's performed again to
* update the content tree. * update the content tree.
* @param aScope * @param aScope
* the search scope, "bookmarks", "collection", or "history" * The search scope: "bookmarks", "collection", "downloads" or
* "history".
*/ */
setScope: function PQB_setScope(aScope) { setScope: function PQB_setScope(aScope) {
// Determine filterCollection, folders, and scopeButtonId based on aScope. // Determine filterCollection, folders, and scopeButtonId based on aScope.
@ -1072,6 +1112,10 @@ var PlacesQueryBuilder = {
PlacesUtils.toolbarFolderId, PlacesUtils.toolbarFolderId,
PlacesUtils.unfiledBookmarksFolderId); PlacesUtils.unfiledBookmarksFolderId);
break; break;
case "downloads":
filterCollection = "downloads";
scopeButtonId = "scopeBarDownloads";
break;
default: default:
throw "Invalid search scope"; throw "Invalid search scope";
break; break;

Просмотреть файл

@ -412,18 +412,16 @@
oncommand="PlacesQueryBuilder.onScopeSelected(this);" oncommand="PlacesQueryBuilder.onScopeSelected(this);"
label="&search.scopeBookmarks.label;" label="&search.scopeBookmarks.label;"
accesskey="&search.scopeBookmarks.accesskey;"/> accesskey="&search.scopeBookmarks.accesskey;"/>
<!--
<toolbarbutton id="scopeBarDownloads" class="small-margin"
type="radio" group="scopeBar"
oncommand="PlacesQueryBuilder.onScopeSelected(this);"
label="&search.scopeDownloads.label;"
accesskey="&search.scopeDownloads.accesskey;"/>
-->
<toolbarbutton id="scopeBarHistory" class="small-margin" <toolbarbutton id="scopeBarHistory" class="small-margin"
type="radio" group="scopeBar" type="radio" group="scopeBar"
oncommand="PlacesQueryBuilder.onScopeSelected(this);" oncommand="PlacesQueryBuilder.onScopeSelected(this);"
label="&search.scopeHistory.label;" label="&search.scopeHistory.label;"
accesskey="&search.scopeHistory.accesskey;"/> accesskey="&search.scopeHistory.accesskey;"/>
<toolbarbutton id="scopeBarDownloads" class="small-margin"
type="radio" group="scopeBar"
oncommand="PlacesQueryBuilder.onScopeSelected(this);"
label="&search.scopeDownloads.label;"
accesskey="&search.scopeDownloads.accesskey;"/>
<toolbarbutton id="scopeBarFolder" class="small-margin" <toolbarbutton id="scopeBarFolder" class="small-margin"
type="radio" group="scopeBar" type="radio" group="scopeBar"
oncommand="PlacesQueryBuilder.onScopeSelected(this);" oncommand="PlacesQueryBuilder.onScopeSelected(this);"

Просмотреть файл

@ -61,67 +61,74 @@
*/ */
const TEST_URL = "http://dummy.mozilla.org/"; const TEST_URL = "http://dummy.mozilla.org/";
const TEST_DOWNLOAD_URL = "http://dummy.mozilla.org/dummy.pdf";
// Add your tests here. Each is a function that's called by testHelper(). let gLibrary;
var testCases = [
// All Bookmarks let testCases = [
function () { function allBookmarksScope() {
var defScope = getDefaultScope(PlacesUIUtils.allBookmarksFolderId); let defScope = getDefaultScope(PlacesUIUtils.allBookmarksFolderId);
search(PlacesUIUtils.allBookmarksFolderId, "dummy", defScope); search(PlacesUIUtils.allBookmarksFolderId, "dummy", defScope);
is(selectScope("scopeBarFolder"), false, ok(!selectScope("scopeBarFolder"),
"Folder scope should be disabled for All Bookmarks"); "Folder scope should be disabled for All Bookmarks");
resetSearch(defScope); ok(selectScope("scopeBarAll"),
"Bookmarks scope should be enabled for All Bookmarks");
resetSearch("scopeBarAll");
}, },
// History function historyScope() {
function () { let defScope = getDefaultScope(PlacesUIUtils.leftPaneQueries["History"]);
var defScope = getDefaultScope(PlacesUIUtils.leftPaneQueries["History"]);
search(PlacesUIUtils.leftPaneQueries["History"], "dummy", defScope); search(PlacesUIUtils.leftPaneQueries["History"], "dummy", defScope);
is(selectScope("scopeBarFolder"), false, ok(!selectScope("scopeBarFolder"),
"Folder scope should be disabled for History"); "Folder scope should be disabled for History");
ok(selectScope("scopeBarAll"),
"Bookmarks scope should be enabled for History");
resetSearch("scopeBarAll");
},
function downloadsScope() {
let defScope = getDefaultScope(PlacesUIUtils.leftPaneQueries["Downloads"]);
search(PlacesUIUtils.leftPaneQueries["Downloads"], "dummy", defScope);
ok(!selectScope("scopeBarFolder"),
"Folder scope should be disabled for Downloads");
ok(!selectScope("scopeBarAll"),
"Bookmarks scope should be disabled for Downloads");
resetSearch(defScope); resetSearch(defScope);
}, },
// Toolbar folder function toolbarFolderScope() {
function () { let defScope = getDefaultScope(PlacesUtils.toolbarFolderId);
var defScope = getDefaultScope(bmsvc.toolbarFolder); search(PlacesUtils.toolbarFolderId, "dummy", defScope);
search(bmsvc.toolbarFolder, "dummy", defScope); ok(selectScope("scopeBarAll"),
is(selectScope("scopeBarFolder"), true, "Bookmarks scope should be enabled for toolbar folder");
ok(selectScope("scopeBarFolder"),
"Folder scope should be enabled for toolbar folder"); "Folder scope should be enabled for toolbar folder");
// Ensure that folder scope is still selected after resetting and searching // Ensure that folder scope is still selected after resetting and searching
// again. // again.
resetSearch("scopeBarFolder"); resetSearch("scopeBarFolder");
search(bmsvc.toolbarFolder, "dummy", "scopeBarFolder"); search(PlacesUtils.toolbarFolderId, "dummy", "scopeBarFolder");
}, },
// A regular non-root subfolder function subFolderScope() {
function () { let folderId = PlacesUtils.bookmarks.createFolder(PlacesUtils.toolbarFolderId,
var folderId = bmsvc.createFolder(bmsvc.toolbarFolder, "dummy folder",
"dummy folder", PlacesUtils.bookmarks.DEFAULT_INDEX);
bmsvc.DEFAULT_INDEX); let defScope = getDefaultScope(folderId);
var defScope = getDefaultScope(folderId);
search(folderId, "dummy", defScope); search(folderId, "dummy", defScope);
is(selectScope("scopeBarFolder"), true, ok(selectScope("scopeBarAll"),
"Bookmarks scope should be enabled for regularfolder");
ok(selectScope("scopeBarFolder"),
"Folder scope should be enabled for regular subfolder"); "Folder scope should be enabled for regular subfolder");
// Ensure that folder scope is still selected after resetting and searching // Ensure that folder scope is still selected after resetting and searching
// again. // again.
resetSearch("scopeBarFolder"); resetSearch("scopeBarFolder");
search(folderId, "dummy", "scopeBarFolder"); search(folderId, "dummy", "scopeBarFolder");
bmsvc.removeItem(folderId); PlacesUtils.bookmarks.removeItem(folderId);
}, },
]; ];
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
getService(Ci.nsINavBookmarksService);
var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsINavHistoryService);
var libraryWin;
///////////////////////////////////////////////////////////////////////////////
/** /**
* Returns the default search scope for a given folder. * Returns the default search scope for a given folder.
* *
@ -130,9 +137,14 @@ var libraryWin;
* @return the default scope when the folder is newly selected * @return the default scope when the folder is newly selected
*/ */
function getDefaultScope(aFolderId) { function getDefaultScope(aFolderId) {
return aFolderId === PlacesUIUtils.leftPaneQueries["History"] ? switch (aFolderId) {
"scopeBarHistory" : case PlacesUIUtils.leftPaneQueries["History"]:
"scopeBarAll"; return "scopeBarHistory"
case PlacesUIUtils.leftPaneQueries["Downloads"]:
return "scopeBarDownloads";
default:
return "scopeBarAll";
}
} }
/** /**
@ -141,8 +153,8 @@ function getDefaultScope(aFolderId) {
* @return the ID of the selected scope folder button * @return the ID of the selected scope folder button
*/ */
function getSelectedScopeButtonId() { function getSelectedScopeButtonId() {
var doc = libraryWin.document; let doc = gLibrary.document;
var scopeButtons = doc.getElementById("organizerScopeBar").childNodes; let scopeButtons = doc.getElementById("organizerScopeBar").childNodes;
for (let i = 0; i < scopeButtons.length; i++) { for (let i = 0; i < scopeButtons.length; i++) {
if (scopeButtons[i].checked) if (scopeButtons[i].checked)
return scopeButtons[i].id; return scopeButtons[i].id;
@ -158,8 +170,8 @@ function getSelectedScopeButtonId() {
* @return an nsINavHistoryQuery object * @return an nsINavHistoryQuery object
*/ */
function queryStringToQuery(aPlaceURI) { function queryStringToQuery(aPlaceURI) {
var queries = {}; let queries = {};
histsvc.queryStringToQueries(aPlaceURI, queries, {}, {}); PlacesUtils.history.queryStringToQueries(aPlaceURI, queries, {}, {});
return queries.value[0]; return queries.value[0];
} }
@ -188,9 +200,9 @@ function resetSearch(aExpectedScopeButtonId) {
* after searching the selected scope button should be this * after searching the selected scope button should be this
*/ */
function search(aFolderId, aSearchStr, aExpectedScopeButtonId) { function search(aFolderId, aSearchStr, aExpectedScopeButtonId) {
var doc = libraryWin.document; let doc = gLibrary.document;
var folderTree = doc.getElementById("placesList"); let folderTree = doc.getElementById("placesList");
var contentTree = doc.getElementById("placeContent"); let contentTree = doc.getElementById("placeContent");
// First, ensure that selecting the folder in the left pane updates the // First, ensure that selecting the folder in the left pane updates the
// content tree properly. // content tree properly.
@ -201,10 +213,11 @@ function search(aFolderId, aSearchStr, aExpectedScopeButtonId) {
// getFolders() on a History query returns an empty array, so no use // getFolders() on a History query returns an empty array, so no use
// comparing against aFolderId in that case. // comparing against aFolderId in that case.
if (aFolderId !== PlacesUIUtils.leftPaneQueries["History"]) { if (aFolderId !== PlacesUIUtils.leftPaneQueries["History"] &&
aFolderId !== PlacesUIUtils.leftPaneQueries["Downloads"]) {
// contentTree.place should be equal to contentTree.result.root.uri, // contentTree.place should be equal to contentTree.result.root.uri,
// but it's not until bug 476952 is fixed. // but it's not until bug 476952 is fixed.
var query = queryStringToQuery(contentTree.result.root.uri); let query = queryStringToQuery(contentTree.result.root.uri);
is(query.getFolders()[0], aFolderId, is(query.getFolders()[0], aFolderId,
"Content tree's folder should be what was selected in the left pane"); "Content tree's folder should be what was selected in the left pane");
} }
@ -212,27 +225,41 @@ function search(aFolderId, aSearchStr, aExpectedScopeButtonId) {
// Second, ensure that searching updates the content tree and search UI // Second, ensure that searching updates the content tree and search UI
// properly. // properly.
var searchBox = doc.getElementById("searchFilter"); let searchBox = doc.getElementById("searchFilter");
searchBox.value = aSearchStr; searchBox.value = aSearchStr;
libraryWin.PlacesSearchBox.search(searchBox.value); gLibrary.PlacesSearchBox.search(searchBox.value);
query = queryStringToQuery(contentTree.result.root.uri); let query = queryStringToQuery(contentTree.result.root.uri);
if (aSearchStr) { if (aSearchStr) {
is(query.searchTerms, aSearchStr, is(query.searchTerms, aSearchStr,
"Content tree's searchTerms should be text in search box"); "Content tree's searchTerms should be text in search box");
is(doc.getElementById("searchModifiers").hidden, false, is(doc.getElementById("searchModifiers").hidden, false,
"Scope bar should not be hidden after searching"); "Scope bar should not be hidden after searching");
if (getSelectedScopeButtonId() == "scopeBarHistory" ||
getSelectedScopeButtonId() == "scopeBarAll" || let scopeButtonId = getSelectedScopeButtonId();
aFolderId == PlacesUtils.bookmarks.unfiledBookmarksFolder) { if (scopeButtonId == "scopeBarDownloads" ||
scopeButtonId == "scopeBarHistory" ||
scopeButtonId == "scopeBarAll" ||
aFolderId == PlacesUtils.unfiledBookmarksFolderId) {
// Check that the target node exists in the tree's search results. // Check that the target node exists in the tree's search results.
var node = null; let url, count;
for (var i = 0; i < contentTree.view.rowCount; i++) { if (scopeButtonId == "scopeBarDownloads") {
url = TEST_DOWNLOAD_URL;
count = 1;
}
else {
url = TEST_URL;
count = scopeButtonId == "scopeBarHistory" ? 2 : 1;
}
is(contentTree.view.rowCount, count, "Found correct number of results");
let node = null;
for (let i = 0; i < contentTree.view.rowCount; i++) {
node = contentTree.view.nodeForTreeIndex(i); node = contentTree.view.nodeForTreeIndex(i);
if (node.uri === TEST_URL) if (node.uri === url)
break; break;
} }
isnot(node, null, "At least the target node should be in the tree"); isnot(node, null, "At least the target node should be in the tree");
is(node.uri, TEST_URL, "URI of node should match target URL"); is(node.uri, url, "URI of node should match target URL");
} }
} }
else { else {
@ -253,10 +280,10 @@ function search(aFolderId, aSearchStr, aExpectedScopeButtonId) {
* @return true if the button is enabled, false otherwise * @return true if the button is enabled, false otherwise
*/ */
function selectScope(aScopeButtonId) { function selectScope(aScopeButtonId) {
var doc = libraryWin.document; let doc = gLibrary.document;
var button = doc.getElementById(aScopeButtonId); let button = doc.getElementById(aScopeButtonId);
isnot(button, null, isnot(button, null,
"Sanity check: scope button with ID " + aScopeButtonId + "should exist"); "Sanity check: scope button with ID " + aScopeButtonId + " should exist");
// Bug 469436 may hide an inappropriate scope button instead of disabling it. // Bug 469436 may hide an inappropriate scope button instead of disabling it.
if (button.disabled || button.hidden) if (button.disabled || button.hidden)
return false; return false;
@ -267,21 +294,17 @@ function selectScope(aScopeButtonId) {
/** /**
* test() contains window-launching boilerplate that calls this to really kick * test() contains window-launching boilerplate that calls this to really kick
* things off. Add functions to the testCases array, and this will call them. * things off. Add functions to the testCases array, and this will call them.
*
* @param aLibraryWin
* the Places Library window
*/ */
function testHelper(aLibraryWin) { function onLibraryAvailable() {
libraryWin = aLibraryWin;
testCases.forEach(function (aTest) aTest()); testCases.forEach(function (aTest) aTest());
aLibraryWin.close();
gLibrary.close();
gLibrary = null;
// Cleanup. // Cleanup.
PlacesUtils.tagging.untagURI(PlacesUtils._uri(TEST_URL), ["dummyTag"]); PlacesUtils.tagging.untagURI(PlacesUtils._uri(TEST_URL), ["dummyTag"]);
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.bookmarks.unfiledBookmarksFolder); PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory).removeAllPages(); waitForClearHistory(finish);
finish();
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -291,15 +314,19 @@ function test() {
// Sanity: // Sanity:
ok(PlacesUtils, "PlacesUtils in context"); ok(PlacesUtils, "PlacesUtils in context");
// Add a visit, a bookmark and a tag.
// Add visits, a bookmark and a tag.
PlacesUtils.history.addVisit(PlacesUtils._uri(TEST_URL), PlacesUtils.history.addVisit(PlacesUtils._uri(TEST_URL),
Date.now() * 1000, null, Date.now() * 1000, null,
PlacesUtils.history.TRANSITION_TYPED, false, 0); PlacesUtils.history.TRANSITION_TYPED, false, 0);
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.bookmarks.unfiledBookmarksFolder, PlacesUtils.history.addVisit(PlacesUtils._uri(TEST_DOWNLOAD_URL),
Date.now() * 1000, null,
PlacesUtils.history.TRANSITION_DOWNLOAD, false, 0);
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
PlacesUtils._uri(TEST_URL), PlacesUtils._uri(TEST_URL),
PlacesUtils.bookmarks.DEFAULT_INDEX, PlacesUtils.bookmarks.DEFAULT_INDEX,
"dummy"); "dummy");
PlacesUtils.tagging.tagURI(PlacesUtils._uri(TEST_URL), ["dummyTag"]); PlacesUtils.tagging.tagURI(PlacesUtils._uri(TEST_URL), ["dummyTag"]);
openLibrary(testHelper); gLibrary = openLibrary(onLibraryAvailable);
} }

Просмотреть файл

@ -42,6 +42,7 @@ view.sortBy.tags.accesskey=T
searchBookmarks=Search Bookmarks searchBookmarks=Search Bookmarks
searchHistory=Search History searchHistory=Search History
searchDownloads=Search Downloads
searchCurrentDefault=Search in '%S' searchCurrentDefault=Search in '%S'
findInPrefix=Find in '%S'… findInPrefix=Find in '%S'…