зеркало из https://github.com/mozilla/pjs.git
Bug 614416: Building add-on lists is too slow. r=Unfocused, a=blocks-final
--HG-- extra : rebase_source : 9daed9f67dbb8fd0dd9130d7cac10dd137d61240
This commit is contained in:
Родитель
57521acf6c
Коммит
3d6bf6189b
|
@ -74,8 +74,6 @@ const XMLURI_PARSE_ERROR = "http://www.mozilla.org/newlayout/xml/parsererror.xml
|
|||
|
||||
const VIEW_DEFAULT = "addons://list/extension";
|
||||
|
||||
const INTEGER_FIELDS = ["dateUpdated", "size", "relevancescore"];
|
||||
|
||||
var gStrings = {};
|
||||
XPCOMUtils.defineLazyServiceGetter(gStrings, "bundleSvc",
|
||||
"@mozilla.org/intl/stringbundle;1",
|
||||
|
@ -1163,16 +1161,81 @@ function createItem(aObj, aIsInstall, aIsRemote) {
|
|||
// the binding handles the rest
|
||||
item.setAttribute("value", aObj.id);
|
||||
|
||||
// The XUL sort service only supports 32 bit integers so we strip the
|
||||
// milliseconds to make this small enough
|
||||
if (aObj.updateDate)
|
||||
item.setAttribute("dateUpdated", aObj.updateDate.getTime() / 1000);
|
||||
|
||||
if (aObj.size)
|
||||
item.setAttribute("size", aObj.size);
|
||||
return item;
|
||||
}
|
||||
|
||||
function sortElements(aElements, aSortBy, aAscending) {
|
||||
const DATE_FIELDS = ["updateDate"];
|
||||
const INTEGER_FIELDS = ["size", "relevancescore"];
|
||||
|
||||
function dateCompare(a, b) {
|
||||
var aTime = a.getTime();
|
||||
var bTime = b.getTime();
|
||||
if (aTime < bTime)
|
||||
return -1;
|
||||
if (aTime > bTime)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
function intCompare(a, b) {
|
||||
return a - b;
|
||||
}
|
||||
|
||||
function stringCompare(a, b) {
|
||||
return a.localeCompare(b);
|
||||
}
|
||||
|
||||
function getValue(aObj) {
|
||||
if (!aObj)
|
||||
return null;
|
||||
|
||||
if (aObj.hasAttribute(aSortBy))
|
||||
return aObj.getAttribute(aSortBy);
|
||||
|
||||
addon = aObj.mAddon || aObj.mInstall;
|
||||
if (!addon)
|
||||
return null;
|
||||
|
||||
return addon[aSortBy];
|
||||
}
|
||||
|
||||
var sortFunc = stringCompare;
|
||||
if (DATE_FIELDS.indexOf(aSortBy) != -1)
|
||||
sortFunc = dateCompare;
|
||||
else if (INTEGER_FIELDS.indexOf(aSortBy) != -1)
|
||||
sortFunc = intCompare;
|
||||
|
||||
aElements.sort(function(a, b) {
|
||||
if (!aAscending)
|
||||
[a, b] = [b, a];
|
||||
|
||||
var aValue = getValue(a);
|
||||
var bValue = getValue(b);
|
||||
|
||||
if (!aValue && !bValue)
|
||||
return 0;
|
||||
if (!aValue)
|
||||
return -1;
|
||||
if (!bValue)
|
||||
return 1;
|
||||
|
||||
return sortFunc(aValue, bValue);
|
||||
});
|
||||
}
|
||||
|
||||
function sortList(aList, aSortBy, aAscending) {
|
||||
var elements = Array.slice(aList.childNodes, 0);
|
||||
sortElements(elements, aSortBy, aAscending);
|
||||
|
||||
while (aList.listChild)
|
||||
aList.removeChild(aList.lastChild);
|
||||
|
||||
elements.forEach(function(aElement) {
|
||||
aList.appendChild(aElement);
|
||||
});
|
||||
}
|
||||
|
||||
function getAddonsAndInstalls(aType, aCallback) {
|
||||
var addonTypes = null, installTypes = null;
|
||||
if (aType != null) {
|
||||
|
@ -1562,8 +1625,9 @@ var gSearchView = {
|
|||
this._pendingSearches = 2;
|
||||
this._sorters.setSort("relevancescore", false);
|
||||
|
||||
var elements = [];
|
||||
|
||||
function createSearchResults(aObjsList, aIsInstall, aIsRemote) {
|
||||
var createdCount = 0;
|
||||
aObjsList.forEach(function(aObj) {
|
||||
let score = 0;
|
||||
if (aQuery.length > 0) {
|
||||
|
@ -1577,16 +1641,18 @@ var gSearchView = {
|
|||
if (aIsRemote)
|
||||
gCachedAddons[aObj.id] = aObj;
|
||||
|
||||
self._listBox.insertBefore(item, self._listBox.lastChild);
|
||||
createdCount++;
|
||||
elements.push(item);
|
||||
});
|
||||
|
||||
return createdCount;
|
||||
}
|
||||
|
||||
function finishSearch(createdCount) {
|
||||
if (createdCount > 0)
|
||||
self.onSortChanged(self._sorters.sortBy, self._sorters.ascending);
|
||||
if (elements.length > 0) {
|
||||
sortElements(elements, self._sorters.sortBy, self._sorters.ascending);
|
||||
elements.forEach(function(aElement) {
|
||||
self._listBox.insertBefore(aElement, self._listBox.lastChild);
|
||||
});
|
||||
self.updateListAttributes();
|
||||
}
|
||||
|
||||
self._pendingSearches--;
|
||||
self.updateView();
|
||||
|
@ -1599,9 +1665,9 @@ var gSearchView = {
|
|||
if (gViewController && aRequest != gViewController.currentViewRequest)
|
||||
return;
|
||||
|
||||
var createdCount = createSearchResults(aAddons, false, false);
|
||||
createdCount += createSearchResults(aInstalls, true, false);
|
||||
finishSearch(createdCount);
|
||||
createSearchResults(aAddons, false, false);
|
||||
createSearchResults(aInstalls, true, false);
|
||||
finishSearch();
|
||||
});
|
||||
|
||||
var maxRemoteResults = 0;
|
||||
|
@ -1748,18 +1814,7 @@ var gSearchView = {
|
|||
this._allResultsLink.hidden = false;
|
||||
},
|
||||
|
||||
onSortChanged: function(aSortBy, aAscending) {
|
||||
var footer = this._listBox.lastChild;
|
||||
this._listBox.removeChild(footer);
|
||||
|
||||
var hints = aAscending ? "ascending" : "descending";
|
||||
if (INTEGER_FIELDS.indexOf(aSortBy) >= 0)
|
||||
hints += " integer";
|
||||
|
||||
var sortService = Cc["@mozilla.org/xul/xul-sort-service;1"].
|
||||
getService(Ci.nsIXULSortService);
|
||||
sortService.sort(this._listBox, aSortBy, hints);
|
||||
|
||||
updateListAttributes: function() {
|
||||
var item = this._listBox.querySelector("richlistitem[remote='true'][first]");
|
||||
if (item)
|
||||
item.removeAttribute("first");
|
||||
|
@ -1784,6 +1839,15 @@ var gSearchView = {
|
|||
items[items.length - 1].setAttribute("last", true);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
onSortChanged: function(aSortBy, aAscending) {
|
||||
var footer = this._listBox.lastChild;
|
||||
this._listBox.removeChild(footer);
|
||||
|
||||
sortList(this._listBox, aSortBy, aAscending);
|
||||
this.updateListAttributes();
|
||||
|
||||
this._listBox.appendChild(footer);
|
||||
},
|
||||
|
||||
|
@ -1860,20 +1924,22 @@ var gListView = {
|
|||
if (gViewController && aRequest != gViewController.currentViewRequest)
|
||||
return;
|
||||
|
||||
for (let i = 0; i < aAddonsList.length; i++) {
|
||||
let item = createItem(aAddonsList[i]);
|
||||
self._listBox.appendChild(item);
|
||||
}
|
||||
var elements = [];
|
||||
|
||||
for (let i = 0; i < aInstallsList.length; i++) {
|
||||
let item = createItem(aInstallsList[i], true);
|
||||
self._listBox.appendChild(item);
|
||||
}
|
||||
for (let i = 0; i < aAddonsList.length; i++)
|
||||
elements.push(createItem(aAddonsList[i]));
|
||||
|
||||
if (self._listBox.childElementCount > 0)
|
||||
self.onSortChanged(self._sorters.sortBy, self._sorters.ascending);
|
||||
else
|
||||
for (let i = 0; i < aInstallsList.length; i++)
|
||||
elements.push(createItem(aInstallsList[i], true));
|
||||
|
||||
if (elements.length > 0) {
|
||||
sortElements(elements, self._sorters.sortBy, self._sorters.ascending);
|
||||
elements.forEach(function(aElement) {
|
||||
self._listBox.appendChild(aElement);
|
||||
});
|
||||
} else {
|
||||
self.showEmptyNotice(true);
|
||||
}
|
||||
|
||||
gEventManager.registerInstallListener(self);
|
||||
gViewController.updateCommands();
|
||||
|
@ -1906,13 +1972,7 @@ var gListView = {
|
|||
},
|
||||
|
||||
onSortChanged: function(aSortBy, aAscending) {
|
||||
var hints = aAscending ? "ascending" : "descending";
|
||||
if (INTEGER_FIELDS.indexOf(aSortBy) >= 0)
|
||||
hints += " integer";
|
||||
|
||||
var sortService = Cc["@mozilla.org/xul/xul-sort-service;1"].
|
||||
getService(Ci.nsIXULSortService);
|
||||
sortService.sort(this._listBox, aSortBy, hints);
|
||||
sortList(this._listBox, aSortBy, aAscending);
|
||||
},
|
||||
|
||||
onNewInstall: function(aInstall) {
|
||||
|
@ -2402,19 +2462,23 @@ var gUpdatesView = {
|
|||
if (gViewController && aRequest != gViewController.currentViewRequest)
|
||||
return;
|
||||
|
||||
var elements = [];
|
||||
let threshold = Date.now() - UPDATES_RECENT_TIMESPAN;
|
||||
aAddonsList.forEach(function(aAddon) {
|
||||
if (!aAddon.updateDate || aAddon.updateDate.getTime() < threshold)
|
||||
return;
|
||||
|
||||
let item = createItem(aAddon);
|
||||
self._listBox.appendChild(item);
|
||||
elements.push(createItem(aAddon));
|
||||
});
|
||||
|
||||
if (self._listBox.itemCount > 0)
|
||||
self.onSortChanged(self._sorters.sortBy, self._sorters.ascending);
|
||||
else
|
||||
if (elements.length > 0) {
|
||||
sortElements(elements, self._sorters.sortBy, self._sorters.ascending);
|
||||
elements.forEach(function(aElement) {
|
||||
self._listBox.appendChild(aElement);
|
||||
});
|
||||
} else {
|
||||
self.showEmptyNotice(true);
|
||||
}
|
||||
|
||||
gViewController.notifyViewChanged();
|
||||
});
|
||||
|
@ -2440,6 +2504,8 @@ var gUpdatesView = {
|
|||
self._listBox.removeItemAt(0);
|
||||
}
|
||||
|
||||
var elements = [];
|
||||
|
||||
aInstallsList.forEach(function(aInstall) {
|
||||
if (!self.isManualUpdate(aInstall))
|
||||
return;
|
||||
|
@ -2449,12 +2515,15 @@ var gUpdatesView = {
|
|||
item.addEventListener("IncludeUpdateChanged", function() {
|
||||
self.maybeDisableUpdateSelected();
|
||||
}, false);
|
||||
self._listBox.appendChild(item);
|
||||
elements.push(item);
|
||||
});
|
||||
|
||||
if (self._listBox.itemCount > 0) {
|
||||
if (elements.length > 0) {
|
||||
self._updateSelected.hidden = false;
|
||||
self.onSortChanged(self._sorters.sortBy, self._sorters.ascending);
|
||||
sortElements(elements, self._sorters.sortBy, self._sorters.ascending);
|
||||
elements.forEach(function(aElement) {
|
||||
self._listBox.appendChild(aElement);
|
||||
});
|
||||
} else {
|
||||
self.showEmptyNotice(true);
|
||||
}
|
||||
|
@ -2575,13 +2644,7 @@ var gUpdatesView = {
|
|||
},
|
||||
|
||||
onSortChanged: function(aSortBy, aAscending) {
|
||||
var hints = aAscending ? "ascending" : "descending";
|
||||
if (INTEGER_FIELDS.indexOf(aSortBy) >= 0)
|
||||
hints += " integer";
|
||||
|
||||
var sortService = Cc["@mozilla.org/xul/xul-sort-service;1"].
|
||||
getService(Ci.nsIXULSortService);
|
||||
sortService.sort(this._listBox, aSortBy, hints);
|
||||
sortList(this._listBox, aSortBy, aAscending);
|
||||
},
|
||||
|
||||
onNewInstall: function(aInstall) {
|
||||
|
|
|
@ -246,7 +246,7 @@
|
|||
<xul:button anonid="date-btn" class="sorter"
|
||||
label="&sort.dateUpdated.label;"
|
||||
tooltiptext="&sort.dateUpdated.tooltip;"
|
||||
oncommand="this.parentNode._handleChange('dateUpdated');"/>
|
||||
oncommand="this.parentNode._handleChange('updateDate');"/>
|
||||
<xul:button anonid="relevance-btn" class="sorter" hidden="true"
|
||||
label="&sort.relevance.label;"
|
||||
tooltiptext="&sort.relevance.tooltip;"
|
||||
|
@ -348,7 +348,7 @@
|
|||
this._btnName.checked = false;
|
||||
}
|
||||
|
||||
if (sortBy == "dateUpdated") {
|
||||
if (sortBy == "updateDate") {
|
||||
this._btnDate.checkState = checkState;
|
||||
this._btnDate.checked = true;
|
||||
} else {
|
||||
|
@ -1034,11 +1034,6 @@
|
|||
|
||||
this.setAttribute("name", aAddon.name);
|
||||
|
||||
if (aAddon.size)
|
||||
this.setAttribute("size", aAddon.size);
|
||||
else
|
||||
this.removeAttribute("size");
|
||||
|
||||
var iconURL = this.mAddon.iconURL;
|
||||
if (iconURL)
|
||||
this._icon.src = iconURL;
|
||||
|
@ -1111,13 +1106,10 @@
|
|||
);
|
||||
}
|
||||
|
||||
if (this.mAddon.updateDate) {
|
||||
if (this.mAddon.updateDate)
|
||||
this._dateUpdated.value = formatDate(this.mAddon.updateDate);
|
||||
this.setAttribute("dateUpdated", this.mAddon.updateDate.getTime() / 1000);
|
||||
} else {
|
||||
else
|
||||
this._dateUpdated.value = this._dateUpdated.getAttribute("unknown");
|
||||
this.removeAttribute("dateUpdated");
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
|
|
@ -416,7 +416,7 @@
|
|||
<spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
|
||||
</hbox>
|
||||
<spacer flex="1"/>
|
||||
<hbox id="updates-sorters" class="sort-controls" sortby="dateUpdated"
|
||||
<hbox id="updates-sorters" class="sort-controls" sortby="updateDate"
|
||||
ascending="false"/>
|
||||
</hbox>
|
||||
<vbox id="updates-list-empty" class="alert-container"
|
||||
|
|
|
@ -68,7 +68,7 @@ add_test(function() {
|
|||
add_test(function() {
|
||||
var updatesList = gManagerWindow.document.getElementById("updates-list");
|
||||
var items = updatesList.getElementsByTagName("richlistitem");
|
||||
var possible = ["addon1@tests.mozilla.org", "addon2@tests.mozilla.org", "addon2@tests.mozilla.org"];
|
||||
var possible = ["addon1@tests.mozilla.org", "addon2@tests.mozilla.org", "addon3@tests.mozilla.org"];
|
||||
var expected = ["addon2@tests.mozilla.org", "addon1@tests.mozilla.org"];
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
let item = items[i];
|
||||
|
@ -76,7 +76,7 @@ add_test(function() {
|
|||
if (possible.indexOf(itemId) == -1)
|
||||
continue; // skip over any other addons, such as shipped addons that would update on every build
|
||||
isnot(expected.length, 0, "Should be expecting more items");
|
||||
is(itemId, expected.shift(), "Should get expected item based on recenty of update");
|
||||
is(itemId, expected.shift(), "Should get expected item based on recentness of update");
|
||||
if (itemId == "addon1@tests.mozilla.org")
|
||||
is_element_visible(item._relNotesToggle, "Release notes toggle should be visible for addon with release notes");
|
||||
else
|
||||
|
|
|
@ -60,9 +60,8 @@ function check_order(aExpectedOrder) {
|
|||
var node = list.firstChild;
|
||||
while (node) {
|
||||
var id = node.getAttribute("value");
|
||||
if (id && id.substring(id.length - 18) != "@tests.mozilla.org")
|
||||
return;
|
||||
order.push(node.getAttribute("value"));
|
||||
if (id && id.substring(id.length - 18) == "@tests.mozilla.org")
|
||||
order.push(node.getAttribute("value"));
|
||||
node = node.nextSibling;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче