Bug 581084: List of search results doesn't visually differentiate between installed add-ons and available add-ons. r=Unfocused, a=blocking-beta5

This commit is contained in:
Dave Townsend 2010-08-24 11:23:46 -07:00
parent 52a3204c2d
commit 7216f3fd17
8 changed files with 136 additions and 78 deletions

View File

@ -97,9 +97,11 @@
<!ENTITY sort.rating.label "Rating">
<!ENTITY sort.rating.tooltip "Sort by average rating">
<!ENTITY search.filter.label "Show:">
<!ENTITY search.filter.installed.label "Your installed add-ons">
<!ENTITY search.filter.available.label "Available add-ons">
<!ENTITY search.filter2.label "Search:">
<!ENTITY search.filter2.installed.label "My Add-ons">
<!ENTITY search.filter2.installed.tooltip "Show installed add-ons">
<!ENTITY search.filter2.available.label "Available Add-ons">
<!ENTITY search.filter2.available.tooltip "Show add-ons available to install">
<!ENTITY addon.homepage "Homepage">
<!ENTITY addon.details.label "More">

View File

@ -1089,8 +1089,7 @@ var gCachedAddons = {};
var gSearchView = {
node: null,
_localFilter: null,
_remoteFilter: null,
_filter: null,
_sorters: null,
_listBox: null,
_emptyNotice: null,
@ -1099,8 +1098,7 @@ var gSearchView = {
initialize: function() {
this.node = document.getElementById("search-view");
this._localFilter = document.getElementById("search-filter-local");
this._remoteFilter = document.getElementById("search-filter-remote");
this._filter = document.getElementById("search-filter-radiogroup");
this._sorters = document.getElementById("search-sorters");
this._sorters.handler = this;
this._listBox = document.getElementById("search-list");
@ -1116,15 +1114,10 @@ var gSearchView = {
}
}, false);
this._localFilter.addEventListener("command", function() self.updateView(), false);
this._remoteFilter.addEventListener("command", function() self.updateView(), false);
this._filter.addEventListener("command", function() self.updateView(), false);
},
shutdown: function() {
// Force persist of checked state. See bug 15232
this._localFilter.setAttribute("checked", !!this._localFilter.checked);
this._remoteFilter.setAttribute("checked", !!this._remoteFilter.checked);
if (AddonRepository.isSearching)
AddonRepository.cancelSearch();
},
@ -1230,10 +1223,9 @@ var gSearchView = {
},
updateView: function() {
var showLocal = this._localFilter.checked;
var showRemote = this._remoteFilter.checked;
var showLocal = this._filter.value == "local";
this._listBox.setAttribute("local", showLocal);
this._listBox.setAttribute("remote", showRemote);
this._listBox.setAttribute("remote", !showLocal);
gHeader.isSearching = this.isSearching;
if (!this.isSearching) {
@ -1241,7 +1233,7 @@ var gSearchView = {
var results = this._listBox.getElementsByTagName("richlistitem");
for (let i = 0; i < results.length; i++) {
var isRemote = (results[i].getAttribute("remote") == "true");
if ((isRemote && showRemote) || (!isRemote && showLocal)) {
if ((isRemote && !showLocal) || (!isRemote && showLocal)) {
isEmpty = false;
break;
}

View File

@ -202,29 +202,30 @@
<!-- search view -->
<vbox id="search-view" flex="1" class="view-pane">
<hbox id="search-filter" align="center">
<label id="search-filter-label" value="&search.filter2.label;"/>
<radiogroup id="search-filter-radiogroup" orient="horizontal"
align="center" persist="value" value="local">
<radio id="search-filter-local" class="search-filter-radio"
label="&search.filter2.installed.label;" value="local"
tooltiptext="&search.filter2.installed.tooltip;"/>
<radio id="search-filter-remote" class="search-filter-radio"
label="&search.filter2.available.label;" value="remote"
tooltiptext="&search.filter2.available.tooltip;"/>
</radiogroup>
</hbox>
<hbox class="view-header" pack="end">
<hbox id="search-sorters" class="sort-controls" sortby="name"
ascending="true"/>
</hbox>
<richlistbox id="search-list" class="list" flex="1">
<vbox>
<hbox class="search-filter">
<label value="&search.filter.label;"/>
<checkbox id="search-filter-local"
persist="checked" checked="true"
label="&search.filter.installed.label;"/>
<checkbox id="search-filter-remote"
persist="checked" checked="true"
label="&search.filter.available.label;"/>
</hbox>
<vbox id="search-list-empty" class="empty-list-notice"
flex="1" hidden="true">
<spacer flex="1"/>
<label value="&listEmpty.search.label;"/>
<button label="&listEmpty.button.label;" class="addon-control"
command="cmd_goToDiscoverPane"/>
<spacer flex="3"/>
</vbox>
<vbox id="search-list-empty" class="empty-list-notice"
flex="1" hidden="true">
<spacer flex="1"/>
<label value="&listEmpty.search.label;"/>
<button label="&listEmpty.button.label;" class="addon-control"
command="cmd_goToDiscoverPane"/>
<spacer flex="3"/>
</vbox>
</richlistbox>
</vbox>

View File

@ -208,12 +208,10 @@ function get_actual_results() {
* How the results are sorted (e.g. "name")
* @param aLocalExpected
* Boolean representing if local results are expected
* @param aRemoteExpected
* Boolean representing if remote results are expected
* @return A pair: [array of results with an expected order,
* array of results with unknown order]
*/
function get_expected_results(aSortBy, aLocalExpected, aRemoteExpected) {
function get_expected_results(aSortBy, aLocalExpected) {
var expectedOrder = null, unknownOrder = null;
switch (aSortBy) {
case "relevancescore":
@ -246,7 +244,7 @@ function get_expected_results(aSortBy, aLocalExpected, aRemoteExpected) {
if (aId.indexOf("addon") == 0 || aId.indexOf("install") == 0)
return aLocalExpected;
if (aId.indexOf("remote") == 0)
return aRemoteExpected;
return !aLocalExpected;
return false;
}
@ -265,21 +263,19 @@ function get_expected_results(aSortBy, aLocalExpected, aRemoteExpected) {
* How the results are sorted (e.g. "name")
* @param aReverseOrder
* Boolean representing if the results are in reverse default order
* @param aFilterLocal
* Boolean representing if local results should be filtered out or not
* @param aFilterRemote
* Boolean representing if remote results should be filtered out or not
* @param aShowLocal
* Boolean representing if local results are being shown
*/
function check_results(aQuery, aSortBy, aReverseOrder, aFilterLocal, aFilterRemote) {
var localFilterChecked = gManagerWindow.document.getElementById("search-filter-local").checked;
var remoteFilterChecked = gManagerWindow.document.getElementById("search-filter-remote").checked;
is(localFilterChecked, !aFilterLocal, "Local filter should be checked if showing local items");
is(remoteFilterChecked, !aFilterRemote, "Remote filter should be checked if showing remote items");
function check_results(aQuery, aSortBy, aReverseOrder, aShowLocal) {
var localFilterSelected = gManagerWindow.document.getElementById("search-filter-local").selected;
var remoteFilterSelected = gManagerWindow.document.getElementById("search-filter-remote").selected;
is(localFilterSelected, aShowLocal, "Local filter should be selected if showing local items");
is(remoteFilterSelected, !aShowLocal, "Remote filter should be selected if showing remote items");
// Get expected order assuming default order
var expectedOrder = [], unknownOrder = [];
if (aQuery == QUERY)
[expectedOrder, unknownOrder] = get_expected_results(aSortBy, !aFilterLocal, !aFilterRemote);
[expectedOrder, unknownOrder] = get_expected_results(aSortBy, aShowLocal);
// Get actual order of results
var actualResults = get_actual_results();
@ -330,23 +326,13 @@ function check_filtered_results(aQuery, aSortBy, aReverseOrder) {
var list = gManagerWindow.document.getElementById("search-list");
list.ensureElementIsVisible(localFilter);
// Check with no filtering
check_results(aQuery, aSortBy, aReverseOrder, false, false);
// Check with filtering out local add-ons
// Check with showing local add-ons
EventUtils.synthesizeMouse(localFilter, 2, 2, { }, gManagerWindow);
check_results(aQuery, aSortBy, aReverseOrder, true, false);
check_results(aQuery, aSortBy, aReverseOrder, true);
// Check with filtering out both local and remote add-ons
EventUtils.synthesizeMouse(remoteFilter, 2, 2, { }, gManagerWindow);
check_results(aQuery, aSortBy, aReverseOrder, true, true);
// Check with filtering out remote add-ons
EventUtils.synthesizeMouse(localFilter, 2, 2, { }, gManagerWindow);
check_results(aQuery, aSortBy, aReverseOrder, false, true);
// Set back to no filtering
// Check with showing remote add-ons
EventUtils.synthesizeMouse(remoteFilter, 2, 2, { }, gManagerWindow);
check_results(aQuery, aSortBy, aReverseOrder, false);
}
/*
@ -417,7 +403,7 @@ add_test(function() {
// only remote items have install buttons showing
add_test(function() {
search(QUERY, false, function() {
check_results(QUERY, "relevancescore", false);
check_filtered_results(QUERY, "relevancescore", false);
var list = gManagerWindow.document.getElementById("search-list");
var results = get_actual_results();
@ -507,7 +493,7 @@ add_test(function() {
// Tests that searching for the empty string does nothing when in search view
add_test(function() {
search("", true, function() {
check_results(QUERY, "dateUpdated", true);
check_filtered_results(QUERY, "dateUpdated", true);
run_next_test();
});
});
@ -525,7 +511,7 @@ add_test(function() {
// and the last sort is still used
add_test(function() {
search(QUERY, true, function() {
check_results(QUERY, "dateUpdated", true);
check_filtered_results(QUERY, "dateUpdated", true);
run_next_test();
});
});

View File

@ -242,6 +242,9 @@ add_test(function() {
wait_for_view_load(gManagerWindow, function() {
is(gCategoryUtilities.selectedCategory, "search", "View should have changed to search");
// Make sure to show local add-ons
EventUtils.synthesizeMouse(gDocument.getElementById("search-filter-local"), 2, 2, { }, gManagerWindow);
AddonManager.getAddonByID(ID, function(aAddon) {
ok(!(aAddon.pendingOperations & AddonManager.PENDING_UNINSTALL), "Add-on should not be pending uninstall");
ok(aAddon.operationsRequiringRestart & AddonManager.OP_NEEDS_RESTART_UNINSTALL, "Add-on should require a restart to uninstall");
@ -297,6 +300,9 @@ add_test(function() {
wait_for_view_load(gManagerWindow, function() {
is(gCategoryUtilities.selectedCategory, "search", "View should have changed to search");
// Make sure to show local add-ons
EventUtils.synthesizeMouse(gDocument.getElementById("search-filter-local"), 2, 2, { }, gManagerWindow);
AddonManager.getAddonByID(ID, function(aAddon) {
ok(aAddon.isActive, "Add-on should be active");
ok(!(aAddon.operationsRequiringRestart & AddonManager.OP_NEEDS_RESTART_UNINSTALL), "Add-on should not require a restart to uninstall");
@ -355,6 +361,9 @@ add_test(function() {
wait_for_view_load(gManagerWindow, function() {
is(gCategoryUtilities.selectedCategory, "search", "View should have changed to search");
// Make sure to show local add-ons
EventUtils.synthesizeMouse(gDocument.getElementById("search-filter-local"), 2, 2, { }, gManagerWindow);
AddonManager.getAddonByID(ID, function(aAddon) {
aAddon.userDisabled = true;
@ -680,6 +689,9 @@ add_test(function() {
wait_for_view_load(gManagerWindow, function() {
is(gCategoryUtilities.selectedCategory, "search", "View should have changed to search");
// Make sure to show local add-ons
EventUtils.synthesizeMouse(gDocument.getElementById("search-filter-local"), 2, 2, { }, gManagerWindow);
AddonManager.getAddonByID(ID, function(aAddon) {
ok(!(aAddon.pendingOperations & AddonManager.PENDING_UNINSTALL), "Add-on should not be pending uninstall");
ok(aAddon.operationsRequiringRestart & AddonManager.OP_NEEDS_RESTART_UNINSTALL, "Add-on should require a restart to uninstall");
@ -817,6 +829,9 @@ add_test(function() {
wait_for_view_load(gManagerWindow, function() {
is(gCategoryUtilities.selectedCategory, "search", "View should have changed to search");
// Make sure to show local add-ons
EventUtils.synthesizeMouse(gDocument.getElementById("search-filter-local"), 2, 2, { }, gManagerWindow);
AddonManager.getAddonByID(ID, function(aAddon) {
ok(aAddon.isActive, "Add-on should be active");
ok(!(aAddon.operationsRequiringRestart & AddonManager.OP_NEEDS_RESTART_UNINSTALL), "Add-on should not require a restart to uninstall");
@ -946,6 +961,9 @@ add_test(function() {
wait_for_view_load(gManagerWindow, function() {
is(gCategoryUtilities.selectedCategory, "search", "View should have changed to search");
// Make sure to show local add-ons
EventUtils.synthesizeMouse(gDocument.getElementById("search-filter-local"), 2, 2, { }, gManagerWindow);
AddonManager.getAddonByID(ID, function(aAddon) {
ok(aAddon.isActive, "Add-on should be active");
ok(!(aAddon.operationsRequiringRestart & AddonManager.OP_NEEDS_RESTART_UNINSTALL), "Add-on should not require a restart to uninstall");

View File

@ -455,13 +455,28 @@
/*** search view ***/
.search-filter {
padding: 20px;
-moz-box-align: center;
background-color: #FFF;
#search-filter {
padding: 5px 20px;
font-size: 120%;
}
#search-filter-label {
font-weight: bold;
color: grey;
}
.search-filter-radio {
padding: 0px 6px;
margin: 0px 3px;
}
.search-filter-radio .radio-spacer-box {
display: none;
}
.search-filter-radio .radio-icon {
display: none;
}
/*** detail view ***/

View File

@ -460,13 +460,35 @@
/*** search view ***/
.search-filter {
padding: 20px;
-moz-box-align: center;
background-color: #FFF;
#search-filter {
padding: 5px 20px;
font-size: 120%;
}
#search-filter-label {
font-weight: bold;
color: grey;
}
.search-filter-radio {
-moz-appearance: none;
padding: 0px 6px;
margin: 0px 3px;
-moz-border-radius: 100%;
}
.search-filter-radio[selected] {
background-color: grey;
color: white;
}
.search-filter-radio .radio-check {
display: none;
}
.search-filter-radio .radio-icon {
display: none;
}
/*** detail view ***/

View File

@ -460,13 +460,35 @@
/*** search view ***/
.search-filter {
padding: 20px;
-moz-box-align: center;
background-color: #FFF;
#search-filter {
padding: 5px 20px;
font-size: 120%;
}
#search-filter-label {
font-weight: bold;
color: grey;
}
.search-filter-radio {
-moz-appearance: none;
padding: 0px 6px;
margin: 0px 3px;
-moz-border-radius: 100%;
}
.search-filter-radio[selected] {
background-color: grey;
color: white;
}
.search-filter-radio .radio-check-box1 {
display: none;
}
.search-filter-radio .radio-icon {
display: none;
}
/*** detail view ***/