зеркало из https://github.com/mozilla/pjs.git
Bug 568728: Move nsAddonRepository.js to a JSM. r=dtownsend
--HG-- rename : toolkit/mozapps/extensions/nsAddonRepository.js => toolkit/mozapps/extensions/AddonRepository.jsm
This commit is contained in:
Родитель
90ae4aedf0
Коммит
1af482ca7b
|
@ -265,7 +265,6 @@
|
|||
@BINPATH@/components/FeedWriter.js
|
||||
@BINPATH@/components/fuelApplication.js
|
||||
@BINPATH@/components/WebContentConverter.js
|
||||
@BINPATH@/components/nsAddonRepository.js
|
||||
@BINPATH@/components/nsBrowserContentHandler.js
|
||||
@BINPATH@/components/nsBrowserGlue.js
|
||||
@BINPATH@/components/nsSetDefaultBrowser.js
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/*
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
@ -44,6 +43,8 @@ const Cr = Components.results;
|
|||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/AddonManager.jsm");
|
||||
|
||||
var EXPORTED_SYMBOLS = [ "AddonRepository" ];
|
||||
|
||||
const PREF_GETADDONS_BROWSEADDONS = "extensions.getAddons.browseAddons";
|
||||
const PREF_GETADDONS_BROWSERECOMMENDED = "extensions.getAddons.recommended.browseURL";
|
||||
const PREF_GETADDONS_GETRECOMMENDED = "extensions.getAddons.recommended.url";
|
||||
|
@ -54,33 +55,137 @@ const XMLURI_PARSE_ERROR = "http://www.mozilla.org/newlayout/xml/parsererror.xm
|
|||
|
||||
const API_VERSION = "1.2";
|
||||
|
||||
function AddonSearchResult() {
|
||||
function AddonSearchResult(aId) {
|
||||
this.id = aId;
|
||||
this.screenshots = [];
|
||||
}
|
||||
|
||||
AddonSearchResult.prototype = {
|
||||
/**
|
||||
* The ID of the add-on
|
||||
*/
|
||||
id: null,
|
||||
|
||||
/**
|
||||
* The name of the add-on
|
||||
*/
|
||||
name: null,
|
||||
|
||||
/**
|
||||
* The version of the add-on
|
||||
*/
|
||||
version: null,
|
||||
summary: null,
|
||||
|
||||
/**
|
||||
* A short description of the add-on
|
||||
*/
|
||||
description: null,
|
||||
rating: null,
|
||||
|
||||
/**
|
||||
* The full description of the add-on
|
||||
*/
|
||||
fullDescription: null,
|
||||
|
||||
/**
|
||||
* The rating of the add-on, 0-5 or -1 if unrated
|
||||
*/
|
||||
rating: -1,
|
||||
|
||||
/**
|
||||
* The url of the add-ons icon or empty if there is no icon
|
||||
*/
|
||||
iconURL: null,
|
||||
thumbnailURL: null,
|
||||
|
||||
/**
|
||||
* An array of screenshot urls for the add-on
|
||||
*/
|
||||
screenshots: null,
|
||||
|
||||
/**
|
||||
* The homepage for the add-on
|
||||
*/
|
||||
homepageURL: null,
|
||||
eula: null,
|
||||
|
||||
/**
|
||||
* The add-on type (e.g. "extension" or "theme")
|
||||
*/
|
||||
type: null,
|
||||
xpiURL: null,
|
||||
xpiHash: null,
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAddonSearchResult])
|
||||
/**
|
||||
* AddonInstall object generated from the add-on XPI url
|
||||
*/
|
||||
install: null,
|
||||
|
||||
/**
|
||||
* True or false depending on whether the add-on is compatible with the
|
||||
* current version and platform of the application
|
||||
*/
|
||||
isCompatible: true,
|
||||
|
||||
/**
|
||||
* True if the add-on has a secure means of updating
|
||||
*/
|
||||
providesUpdatesSecurely: true,
|
||||
|
||||
/**
|
||||
* The current blocklist state of the add-on
|
||||
*/
|
||||
blocklistState: Ci.nsIBlocklistService.STATE_NOT_BLOCKED,
|
||||
|
||||
/**
|
||||
* True if this add-on cannot be used in the application based on version
|
||||
* compatibility, dependencies and blocklisting
|
||||
*/
|
||||
appDisabled: false,
|
||||
|
||||
/**
|
||||
* True if the user wants this add-on to be disabled
|
||||
*/
|
||||
userDisabled: false,
|
||||
|
||||
/**
|
||||
* Indicates what scope the add-on is installed in, per profile, user,
|
||||
* system or application
|
||||
*/
|
||||
scope: AddonManager.SCOPE_PROFILE,
|
||||
|
||||
/**
|
||||
* True if the add-on is currently functional
|
||||
*/
|
||||
isActive: true,
|
||||
|
||||
/**
|
||||
* The creator of the add-on
|
||||
*/
|
||||
creator: null,
|
||||
|
||||
/**
|
||||
* A bitfield holding all of the current operations that are waiting to be
|
||||
* performed for this add-on
|
||||
*/
|
||||
pendingOperations: AddonManager.PENDING_NONE,
|
||||
|
||||
/**
|
||||
* A bitfield holding all the the operations that can be performed on
|
||||
* this add-on
|
||||
*/
|
||||
permissions: 0
|
||||
}
|
||||
|
||||
function AddonRepository() {
|
||||
}
|
||||
|
||||
AddonRepository.prototype = {
|
||||
/**
|
||||
* The add-on repository is a source of add-ons that can be installed. It can
|
||||
* be searched in two ways. One returns a list of add-ons that come highly
|
||||
* recommended, this list should change frequently. The other way is to
|
||||
* search for specific search terms entered by the user. Searches are
|
||||
* asynchronous and results should be passed to the provided callback object
|
||||
* when complete. The results passed to the callback should only include add-ons
|
||||
* that are compatible with the current application and are not already
|
||||
* installed. Searches are always asynchronous and should be passed to the
|
||||
* callback object provided.
|
||||
*/
|
||||
var AddonRepository = {
|
||||
// The current set of results
|
||||
_addons: null,
|
||||
_results: null,
|
||||
|
||||
// Whether we are currently searching or not
|
||||
_searching: false,
|
||||
|
@ -91,40 +196,75 @@ AddonRepository.prototype = {
|
|||
// XHR associated with the current request
|
||||
_request: null,
|
||||
|
||||
// Callback object to notify on completion
|
||||
/*
|
||||
* Addon search results callback object that contains two functions
|
||||
*
|
||||
* searchSucceeded - Called when a search has suceeded.
|
||||
*
|
||||
* @param aAddons an array of the add-on results. In the case of
|
||||
* searching for specific terms the ordering of results
|
||||
* may be determined by the search provider.
|
||||
* @param aAddonCount The length of aAddons
|
||||
* @param aTotalResults The total results actually available in the
|
||||
* repository
|
||||
*
|
||||
*
|
||||
* searchFailed - Called when an error occurred when performing a search.
|
||||
*/
|
||||
_callback: null,
|
||||
|
||||
// Maximum number of results to return
|
||||
_maxResults: null,
|
||||
|
||||
/**
|
||||
* The homepage for visiting this repository. This may be null or an empty
|
||||
* string.
|
||||
*/
|
||||
get homepageURL() {
|
||||
return Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
|
||||
.getService(Components.interfaces.nsIURLFormatter)
|
||||
.formatURLPref(PREF_GETADDONS_BROWSEADDONS);
|
||||
return Cc["@mozilla.org/toolkit/URLFormatterService;1"].
|
||||
getService(Ci.nsIURLFormatter).
|
||||
formatURLPref(PREF_GETADDONS_BROWSEADDONS);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns whether this instance is currently performing a search. New
|
||||
* searches will not be performed while this is the case.
|
||||
*/
|
||||
get isSearching() {
|
||||
return this._searching;
|
||||
},
|
||||
|
||||
/**
|
||||
* The url that can be visited to see recommended add-ons in this repository.
|
||||
*/
|
||||
getRecommendedURL: function() {
|
||||
var urlf = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
|
||||
.getService(Components.interfaces.nsIURLFormatter);
|
||||
var urlf = Cc["@mozilla.org/toolkit/URLFormatterService;1"].
|
||||
getService(Ci.nsIURLFormatter);
|
||||
|
||||
return urlf.formatURLPref(PREF_GETADDONS_BROWSERECOMMENDED);
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves the url that can be visited to see search results for the given
|
||||
* terms.
|
||||
*
|
||||
* @param aSearchTerms search terms used to search the repository
|
||||
*/
|
||||
getSearchURL: function(aSearchTerms) {
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefBranch);
|
||||
var urlf = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
|
||||
.getService(Components.interfaces.nsIURLFormatter);
|
||||
var prefs = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
var urlf = Cc["@mozilla.org/toolkit/URLFormatterService;1"].
|
||||
getService(Ci.nsIURLFormatter);
|
||||
|
||||
var url = prefs.getCharPref(PREF_GETADDONS_BROWSESEARCHRESULTS);
|
||||
url = url.replace(/%TERMS%/g, encodeURIComponent(aSearchTerms));
|
||||
return urlf.formatURL(url);
|
||||
},
|
||||
|
||||
/**
|
||||
* Cancels the search in progress. If there is no search in progress this
|
||||
* does nothing.
|
||||
*/
|
||||
cancelSearch: function() {
|
||||
this._searching = false;
|
||||
if (this._request) {
|
||||
|
@ -132,23 +272,30 @@ AddonRepository.prototype = {
|
|||
this._request = null;
|
||||
}
|
||||
this._callback = null;
|
||||
this._addons = null;
|
||||
this._results = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Begins a search for recommended add-ons in this repository. Results will
|
||||
* be passed to the given callback.
|
||||
*
|
||||
* @param aMaxResults the maximum number of results to return
|
||||
* @param aCallback the callback to pass results to
|
||||
*/
|
||||
retrieveRecommendedAddons: function(aMaxResults, aCallback) {
|
||||
if (this._searching)
|
||||
return;
|
||||
|
||||
this._searching = true;
|
||||
this._addons = [];
|
||||
this._results = [];
|
||||
this._callback = aCallback;
|
||||
this._recommended = true;
|
||||
this._maxResults = aMaxResults;
|
||||
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefBranch);
|
||||
var urlf = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
|
||||
.getService(Components.interfaces.nsIURLFormatter);
|
||||
var prefs = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
var urlf = Cc["@mozilla.org/toolkit/URLFormatterService;1"].
|
||||
getService(Ci.nsIURLFormatter);
|
||||
|
||||
var uri = prefs.getCharPref(PREF_GETADDONS_GETRECOMMENDED);
|
||||
uri = uri.replace(/%API_VERSION%/g, API_VERSION);
|
||||
|
@ -156,20 +303,28 @@ AddonRepository.prototype = {
|
|||
this._loadList(uri);
|
||||
},
|
||||
|
||||
/**
|
||||
* Begins a search for add-ons in this repository. Results will be passed to
|
||||
* the given callback.
|
||||
*
|
||||
* @param aSearchTerms the terms to search for
|
||||
* @param aMaxResults the maximum number of results to return
|
||||
* @param aCallback the callback to pass results to
|
||||
*/
|
||||
searchAddons: function(aSearchTerms, aMaxResults, aCallback) {
|
||||
if (this._searching)
|
||||
return;
|
||||
|
||||
this._searching = true;
|
||||
this._addons = [];
|
||||
this._results = [];
|
||||
this._callback = aCallback;
|
||||
this._recommended = false;
|
||||
this._maxResults = aMaxResults;
|
||||
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefBranch);
|
||||
var urlf = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
|
||||
.getService(Components.interfaces.nsIURLFormatter);
|
||||
var prefs = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
var urlf = Cc["@mozilla.org/toolkit/URLFormatterService;1"].
|
||||
getService(Ci.nsIURLFormatter);
|
||||
|
||||
var uri = prefs.getCharPref(PREF_GETADDONS_GETSEARCHRESULTS);
|
||||
uri = uri.replace(/%API_VERSION%/g, API_VERSION);
|
||||
|
@ -180,57 +335,57 @@ AddonRepository.prototype = {
|
|||
},
|
||||
|
||||
// Posts results to the callback
|
||||
_reportSuccess: function(aCount) {
|
||||
_reportSuccess: function(aTotalResults) {
|
||||
this._searching = false;
|
||||
this._request = null;
|
||||
// The callback may want to trigger a new search so clear references early
|
||||
var addons = this._addons;
|
||||
var addons = [result.addon for each(result in this._results)];
|
||||
var callback = this._callback;
|
||||
this._callback = null;
|
||||
this._addons = null;
|
||||
callback.searchSucceeded(addons, addons.length, this._recommended ? -1 : aCount);
|
||||
this._results = null;
|
||||
callback.searchSucceeded(addons, addons.length, this._recommended ? -1 : aTotalResults);
|
||||
},
|
||||
|
||||
// Notifies the callback of a failure
|
||||
_reportFailure: function(aEvent) {
|
||||
_reportFailure: function() {
|
||||
this._searching = false;
|
||||
this._request = null;
|
||||
// The callback may want to trigger a new search so clear references early
|
||||
var callback = this._callback;
|
||||
this._callback = null;
|
||||
this._addons = null;
|
||||
this._results = null;
|
||||
callback.searchFailed();
|
||||
},
|
||||
|
||||
// Parses an add-on entry from an <addon> element
|
||||
_parseAddon: function(element, known_ids) {
|
||||
_parseAddon: function(aElement, aSkip) {
|
||||
var app = Cc["@mozilla.org/xre/app-info;1"].
|
||||
getService(Ci.nsIXULAppInfo).
|
||||
QueryInterface(Ci.nsIXULRuntime);
|
||||
|
||||
var guidList = element.getElementsByTagName("guid");
|
||||
var guidList = aElement.getElementsByTagName("guid");
|
||||
if (guidList.length != 1)
|
||||
return;
|
||||
|
||||
var guid = guidList[0].textContent.trim();
|
||||
|
||||
// Ignore add-ons already seen in the results
|
||||
for (var i = 0; i < this._addons.length; i++)
|
||||
if (this._addons[i].id == guid)
|
||||
for (var i = 0; i < this._results.length; i++)
|
||||
if (this._results[i].addon.id == guid)
|
||||
return;
|
||||
|
||||
// Ignore installed add-ons
|
||||
if (known_ids.indexOf(guid) != -1)
|
||||
if (aSkip.ids.indexOf(guid) != -1)
|
||||
return;
|
||||
|
||||
// Ignore sandboxed add-ons
|
||||
var status = element.getElementsByTagName("status");
|
||||
var status = aElement.getElementsByTagName("status");
|
||||
// The status element has a unique id for each status type. 4 is Public.
|
||||
if (status.length != 1 || status[0].getAttribute("id") != 4)
|
||||
return;
|
||||
|
||||
// Ignore add-ons not compatible with this OS
|
||||
var osList = element.getElementsByTagName("compatible_os");
|
||||
var osList = aElement.getElementsByTagName("compatible_os");
|
||||
// Only the version 0 schema included compatible_os if it isn't there then
|
||||
// we will see os compatibility on the install elements.
|
||||
if (osList.length > 0) {
|
||||
|
@ -250,7 +405,7 @@ AddonRepository.prototype = {
|
|||
|
||||
// Ignore add-ons not compatible with this Application
|
||||
compatible = false;
|
||||
var tags = element.getElementsByTagName("compatible_applications");
|
||||
var tags = aElement.getElementsByTagName("compatible_applications");
|
||||
if (tags.length != 1)
|
||||
return;
|
||||
var vc = Cc["@mozilla.org/xpcom/version-comparator;1"].
|
||||
|
@ -273,20 +428,26 @@ AddonRepository.prototype = {
|
|||
if (!compatible)
|
||||
return;
|
||||
|
||||
var addon = new AddonSearchResult();
|
||||
addon.id = guid;
|
||||
addon.rating = -1;
|
||||
var node = element.firstChild;
|
||||
var addon = new AddonSearchResult(guid);
|
||||
var result = {
|
||||
addon: addon,
|
||||
xpiURL: null,
|
||||
xpiHash: null
|
||||
};
|
||||
var node = aElement.firstChild;
|
||||
while (node) {
|
||||
if (node instanceof Ci.nsIDOMElement) {
|
||||
switch (node.localName) {
|
||||
case "name":
|
||||
case "version":
|
||||
case "summary":
|
||||
case "description":
|
||||
case "eula":
|
||||
addon[node.localName] = node.textContent.trim();
|
||||
break;
|
||||
case "summary":
|
||||
addon.description = node.textContent.trim();
|
||||
break;
|
||||
case "description":
|
||||
addon.fullDescription = node.textContent.trim();
|
||||
break;
|
||||
case "rating":
|
||||
if (node.textContent.length > 0) {
|
||||
var rating = parseInt(node.textContent);
|
||||
|
@ -295,7 +456,7 @@ AddonRepository.prototype = {
|
|||
}
|
||||
break;
|
||||
case "thumbnail":
|
||||
addon.thumbnailURL = node.textContent.trim();
|
||||
addon.screenshots.push(node.textContent.trim());
|
||||
break;
|
||||
case "icon":
|
||||
addon.iconURL = node.textContent.trim();
|
||||
|
@ -306,10 +467,7 @@ AddonRepository.prototype = {
|
|||
case "type":
|
||||
// The type element has an id attribute that is the id from AMO's
|
||||
// database. This doesn't match our type values to perform a mapping
|
||||
if (node.getAttribute("id") == 2)
|
||||
addon.type = Ci.nsIAddonSearchResult.TYPE_THEME;
|
||||
else
|
||||
addon.type = Ci.nsIAddonSearchResult.TYPE_EXTENSION;
|
||||
addon.type = (node.getAttribute("id") == 2) ? "theme" : "extension";
|
||||
break;
|
||||
case "install":
|
||||
// No os attribute means the xpi is compatible with any os
|
||||
|
@ -319,9 +477,13 @@ AddonRepository.prototype = {
|
|||
if (os != "all" && os != app.OS.toLowerCase())
|
||||
break;
|
||||
}
|
||||
addon.xpiURL = node.textContent.trim();
|
||||
if (node.hasAttribute("hash"))
|
||||
addon.xpiHash = node.getAttribute("hash");
|
||||
result.xpiURL = node.textContent.trim();
|
||||
|
||||
// Ignore add-on installs
|
||||
if (aSkip.sourceURLs.indexOf(result.xpiURL) != -1)
|
||||
return;
|
||||
|
||||
result.xpiHash = node.hasAttribute("hash") ? node.getAttribute("hash") : null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -329,8 +491,34 @@ AddonRepository.prototype = {
|
|||
}
|
||||
|
||||
// Add only if there was an xpi compatible with this os
|
||||
if (addon.xpiURL)
|
||||
this._addons.push(addon);
|
||||
if (result.xpiURL)
|
||||
this._results.push(result);
|
||||
},
|
||||
|
||||
_parseAddons: function(aElements, aTotalResults, aSkip) {
|
||||
for (var i = 0; i < aElements.length && this._results.length < this._maxResults; i++)
|
||||
this._parseAddon(aElements[i], aSkip);
|
||||
|
||||
var pendingResults = this._results.length;
|
||||
if (pendingResults == 0) {
|
||||
this._reportSuccess(aTotalResults);
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this._results.forEach(function(aResult) {
|
||||
var addon = aResult.addon;
|
||||
var callback = function(aInstall) {
|
||||
addon.install = aInstall;
|
||||
pendingResults--;
|
||||
if (pendingResults == 0)
|
||||
self._reportSuccess(aTotalResults);
|
||||
}
|
||||
|
||||
AddonManager.getInstallForURL(aResult.xpiURL, callback,
|
||||
"application/x-xpinstall", aResult.xpiHash,
|
||||
addon.name, addon.iconURL, addon.version);
|
||||
});
|
||||
},
|
||||
|
||||
// Called when a single request has completed, parses out any add-ons and
|
||||
|
@ -345,26 +533,30 @@ AddonRepository.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
var elements = responseXML.documentElement.getElementsByTagName("addon");
|
||||
if (responseXML.documentElement.hasAttribute("total_results"))
|
||||
var totalResults = responseXML.documentElement.getAttribute("total_results");
|
||||
else
|
||||
var totalResults = elements.length;
|
||||
|
||||
var self = this;
|
||||
AddonManager.getAllAddons(function(addons) {
|
||||
var known_ids = [a.id for each(a in addons)];
|
||||
var skip = {ids: null, sourceURLs: null};
|
||||
|
||||
var elements = responseXML.documentElement.getElementsByTagName("addon");
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
self._parseAddon(elements[i], known_ids);
|
||||
|
||||
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefBranch);
|
||||
if (self._addons.length == self._maxResults) {
|
||||
self._reportSuccess(elements.length);
|
||||
return;
|
||||
}
|
||||
}
|
||||
AddonManager.getAllAddons(function(aAddons) {
|
||||
skip.ids = [a.id for each (a in aAddons)];
|
||||
if (skip.sourceURLs)
|
||||
self._parseAddons(elements, totalResults, skip);
|
||||
});
|
||||
|
||||
if (responseXML.documentElement.hasAttribute("total_results"))
|
||||
self._reportSuccess(responseXML.documentElement.getAttribute("total_results"));
|
||||
else
|
||||
self._reportSuccess(elements.length);
|
||||
AddonManager.getAllInstalls(function(aInstalls) {
|
||||
skip.sourceURLs = [];
|
||||
aInstalls.forEach(function(aInstall) {
|
||||
if (aInstall.state != AddonManager.STATE_AVAILABLE)
|
||||
skip.sourceURLs.push(aInstall.sourceURL);
|
||||
});
|
||||
|
||||
if (skip.ids)
|
||||
self._parseAddons(elements, totalResults, skip);
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -376,17 +568,9 @@ AddonRepository.prototype = {
|
|||
this._request.overrideMimeType("text/xml");
|
||||
|
||||
var self = this;
|
||||
this._request.onerror = function(event) { self._reportFailure(event); };
|
||||
this._request.onload = function(event) { self._listLoaded(event); };
|
||||
this._request.onerror = function(aEvent) { self._reportFailure(); };
|
||||
this._request.onload = function(aEvent) { self._listLoaded(aEvent); };
|
||||
this._request.send(null);
|
||||
},
|
||||
|
||||
classDescription: "Addon Repository",
|
||||
contractID: "@mozilla.org/extensions/addon-repository;1",
|
||||
classID: Components.ID("{8eaaf524-7d6d-4f7d-ae8b-9277b324008d}"),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAddonRepository])
|
||||
}
|
||||
}
|
||||
|
||||
function NSGetModule(aCompMgr, aFileSpec) {
|
||||
return XPCOMUtils.generateModule([AddonRepository]);
|
||||
}
|
|
@ -53,7 +53,6 @@ XPIDLSRCS = \
|
|||
amIInstallTrigger.idl \
|
||||
amIWebInstallListener.idl \
|
||||
amIWebInstaller.idl \
|
||||
nsIAddonRepository.idl \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
|
@ -61,7 +60,6 @@ CPPSRCS = \
|
|||
$(NULL)
|
||||
|
||||
EXTRA_PP_COMPONENTS = \
|
||||
nsAddonRepository.js \
|
||||
nsBlocklistService.js \
|
||||
addonManager.js \
|
||||
amContentHandler.js \
|
||||
|
@ -70,6 +68,7 @@ EXTRA_PP_COMPONENTS = \
|
|||
|
||||
EXTRA_PP_JS_MODULES = \
|
||||
AddonManager.jsm \
|
||||
AddonRepository.jsm \
|
||||
XPIProvider.jsm \
|
||||
PluginProvider.jsm \
|
||||
AddonUpdateChecker.jsm \
|
||||
|
|
|
@ -1,204 +0,0 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Extension Manager.
|
||||
*
|
||||
* The Initial Developer of the Original Code is mozilla.org
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dave Townsend <dtownsend@oxymoronical.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(f81ed0bc-ee98-4edd-bf2d-751b47bf665d)]
|
||||
interface nsIAddonSearchResult : nsISupports
|
||||
{
|
||||
/**
|
||||
* Values for the type attribute
|
||||
*/
|
||||
const unsigned long TYPE_EXTENSION = 0x02;
|
||||
const unsigned long TYPE_THEME = 0x04;
|
||||
|
||||
/**
|
||||
* The ID of the add-on
|
||||
*/
|
||||
readonly attribute AString id;
|
||||
|
||||
/**
|
||||
* The name of the add-on
|
||||
*/
|
||||
readonly attribute AString name;
|
||||
|
||||
/**
|
||||
* The version of the add-on
|
||||
*/
|
||||
readonly attribute AString version;
|
||||
|
||||
/**
|
||||
* A short summary of the add-on
|
||||
*/
|
||||
readonly attribute AString summary;
|
||||
|
||||
/**
|
||||
* The full description of the add-on
|
||||
*/
|
||||
readonly attribute AString description;
|
||||
|
||||
/**
|
||||
* The rating of the add-on, 0-5 or -1 if unrated.
|
||||
*/
|
||||
readonly attribute long rating;
|
||||
|
||||
/**
|
||||
* The url of the add-ons icon or empty if there is no icon.
|
||||
*/
|
||||
readonly attribute AString iconURL;
|
||||
|
||||
/**
|
||||
* The url of a thumbnail for the add-on
|
||||
*/
|
||||
readonly attribute AString thumbnailURL;
|
||||
|
||||
/**
|
||||
* The homepage for the add-on
|
||||
*/
|
||||
readonly attribute AString homepageURL;
|
||||
|
||||
/**
|
||||
* A EULA that must be accepted before install.
|
||||
*/
|
||||
readonly attribute AString eula;
|
||||
|
||||
/**
|
||||
* The add-on type (see nsIUpdateItem).
|
||||
*/
|
||||
readonly attribute unsigned long type;
|
||||
|
||||
/**
|
||||
* The url of the xpi for this add-on
|
||||
*/
|
||||
readonly attribute AString xpiURL;
|
||||
|
||||
/**
|
||||
* The hash for the xpi.
|
||||
*/
|
||||
readonly attribute AString xpiHash;
|
||||
};
|
||||
|
||||
[scriptable, uuid(a6f70917-dd30-4eb6-8b3d-453204f96f33)]
|
||||
interface nsIAddonSearchResultsCallback : nsISupports
|
||||
{
|
||||
/**
|
||||
* Called when a search has suceeded.
|
||||
*
|
||||
* @param aAddons an array of the add-on results. In the case of
|
||||
* searching for specific terms the ordering of results
|
||||
* may be determined by the search provider.
|
||||
* @param aAddonCount The length of aAddons
|
||||
* @param aTotalResults The total results actually available in the
|
||||
* repository
|
||||
*/
|
||||
void searchSucceeded([array, size_is(aAddonCount)] in nsIAddonSearchResult aAddons,
|
||||
in unsigned long aAddonCount,
|
||||
in unsigned long aTotalResults);
|
||||
|
||||
/**
|
||||
* Called when an error occurred when performing a search.
|
||||
*/
|
||||
void searchFailed();
|
||||
};
|
||||
|
||||
/**
|
||||
* The add-on repository is a source of add-ons that can be installed. It can
|
||||
* be searched in two ways. One returns a list of add-ons that come highly
|
||||
* recommended, this list should change frequently. The other way is to
|
||||
* search for specific search terms entered by the user. Searches are
|
||||
* asynchronous and results should be passed to the provided callback object
|
||||
* when complete. The results passed to the callback should only include add-ons
|
||||
* that are compatible with the current application and are not already
|
||||
* installed. Searches are always asynchronous and should be passed to the
|
||||
* callback object provided.
|
||||
*/
|
||||
[scriptable, uuid(c4d2ac29-6edc-43cd-8dc8-e4cf213aa1be)]
|
||||
interface nsIAddonRepository : nsISupports
|
||||
{
|
||||
/**
|
||||
* The homepage for visiting this repository. This may be null or an empty
|
||||
* string.
|
||||
*/
|
||||
readonly attribute AString homepageURL;
|
||||
|
||||
/**
|
||||
* Returns whether this instance is currently performing a search. New
|
||||
* searches will not be performed while this is the case.
|
||||
*/
|
||||
readonly attribute boolean isSearching;
|
||||
|
||||
/**
|
||||
* The url that can be visited to see recommended add-ons in this repository.
|
||||
*/
|
||||
AString getRecommendedURL();
|
||||
|
||||
/**
|
||||
* Retrieves the url that can be visited to see search results for the given
|
||||
* terms.
|
||||
*
|
||||
* @param aSearchTerms search terms used to search the repository
|
||||
*/
|
||||
AString getSearchURL(in AString aSearchTerms);
|
||||
|
||||
/**
|
||||
* Begins a search for recommended add-ons in this repository. Results will
|
||||
* be passed to the given callback.
|
||||
*
|
||||
* @param aMaxResults the maximum number of results to return
|
||||
* @param aCallback the callback to pass results to
|
||||
*/
|
||||
void retrieveRecommendedAddons(in unsigned long aMaxResults,
|
||||
in nsIAddonSearchResultsCallback aCallback);
|
||||
|
||||
/**
|
||||
* Begins a search for add-ons in this repository. Results will be passed to
|
||||
* the given callback.
|
||||
*
|
||||
* @param aSearchTerms the terms to search for
|
||||
* @param aMaxResults the maximum number of results to return
|
||||
* @param aCallback the callback to pass results to
|
||||
*/
|
||||
void searchAddons(in AString aSearchTerms, in unsigned long aMaxResults,
|
||||
in nsIAddonSearchResultsCallback aCallback);
|
||||
|
||||
/**
|
||||
* Cancels the search in progress. If there is no search in progress this
|
||||
* does nothing.
|
||||
*/
|
||||
void cancelSearch();
|
||||
};
|
|
@ -36,6 +36,8 @@
|
|||
* ***** END LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
Components.utils.import("resource://gre/modules/AddonRepository.jsm");
|
||||
|
||||
const PREF_GETADDONS_BROWSEADDONS = "extensions.getAddons.browseAddons";
|
||||
const PREF_GETADDONS_BROWSERECOMMENDED = "extensions.getAddons.recommended.browseURL";
|
||||
const PREF_GETADDONS_GETRECOMMENDED = "extensions.getAddons.recommended.url";
|
||||
|
@ -55,38 +57,33 @@ var BROWSE_SEARCH_URLS = [
|
|||
|
||||
do_load_httpd_js();
|
||||
var server;
|
||||
var addonRepo;
|
||||
|
||||
var RESULTS = [
|
||||
{
|
||||
id: "test5@tests.mozilla.org",
|
||||
name: "PASS",
|
||||
version: "1.0",
|
||||
summary: "This should work fine",
|
||||
description: "Test description",
|
||||
rating: -1,
|
||||
iconURL: null,
|
||||
thumbnailURL: null,
|
||||
homepageURL: "https://addons.mozilla.org/addon/5992",
|
||||
eula: null,
|
||||
type: Ci.nsIAddonSearchResult.TYPE_EXTENSION,
|
||||
xpiURL: "http://localhost:4444/test.xpi",
|
||||
xpiHash: "sha1:c26f0b0d62e5dcddcda95074d3f3fedb9bbc26e3"
|
||||
id: "test5@tests.mozilla.org",
|
||||
name: "PASS",
|
||||
version: "1.0",
|
||||
description: "This should work fine",
|
||||
fullDescription: "Test description",
|
||||
rating: -1,
|
||||
iconURL: null,
|
||||
screenshots: [],
|
||||
homepageURL: "https://addons.mozilla.org/addon/5992",
|
||||
type: "extension",
|
||||
sourceURL: "http://localhost:4444/test.xpi"
|
||||
},
|
||||
{
|
||||
id: "test6@tests.mozilla.org",
|
||||
name: "PASS",
|
||||
version: "1.0",
|
||||
summary: "Specific OS should work fine",
|
||||
description: null,
|
||||
rating: 4,
|
||||
iconURL: "http://localhost:4444/test_bug404024/icon.png",
|
||||
thumbnailURL: "http://localhost:4444/test_bug404024/thumbnail.png",
|
||||
homepageURL: null,
|
||||
eula: "EULA should be confirmed",
|
||||
type: Ci.nsIAddonSearchResult.TYPE_THEME,
|
||||
xpiURL: "http://localhost:4444/test.xpi",
|
||||
xpiHash: null
|
||||
id: "test6@tests.mozilla.org",
|
||||
name: "PASS",
|
||||
version: "1.0",
|
||||
description: "Specific OS should work fine",
|
||||
fullDescription: null,
|
||||
rating: 4,
|
||||
iconURL: "http://localhost:4444/test_bug404024/icon.png",
|
||||
screenshots: ["http://localhost:4444/test_bug404024/thumbnail.png"],
|
||||
homepageURL: null,
|
||||
type: "theme",
|
||||
sourceURL: "http://localhost:4444/test.xpi"
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -102,7 +99,22 @@ function checkResults(addons, length) {
|
|||
}
|
||||
|
||||
for (var i = 0; i < addons.length; i++) {
|
||||
do_check_neq(addons[i]["install"], null);
|
||||
|
||||
for (var p in RESULTS[i]) {
|
||||
if (p == "screenshots") {
|
||||
do_check_eq(addons[i][p].length, RESULTS[i][p].length);
|
||||
for (var j = 0; j < addons[i][p].length; j++)
|
||||
do_check_eq(addons[i][p][j], addons[i][p][j]);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p == "sourceURL") {
|
||||
do_check_eq(addons[i]["install"][p], RESULTS[i][p]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (addons[i][p] != RESULTS[i][p])
|
||||
do_throw("Failed on property " + p + " on add-on " + addons[i].id +
|
||||
addons[i][p] + " == " + RESULTS[i][p]);
|
||||
|
@ -113,14 +125,14 @@ function checkResults(addons, length) {
|
|||
var RecommendedCallback = {
|
||||
searchSucceeded: function(addons, length, total) {
|
||||
// Search is complete
|
||||
do_check_false(addonRepo.isSearching);
|
||||
do_check_false(AddonRepository.isSearching);
|
||||
checkResults(addons, length);
|
||||
|
||||
// "search" for the same results
|
||||
addonRepo.searchAddons("bug404024", 10, SearchCallback);
|
||||
AddonRepository.searchAddons("bug404024", 10, SearchCallback);
|
||||
// Should be searching now and any attempt to retrieve again should be ignored
|
||||
do_check_true(addonRepo.isSearching);
|
||||
addonRepo.searchAddons("test search", 10, FailCallback);
|
||||
do_check_true(AddonRepository.isSearching);
|
||||
AddonRepository.searchAddons("test search", 10, FailCallback);
|
||||
},
|
||||
|
||||
searchFailed: function() {
|
||||
|
@ -131,7 +143,7 @@ var RecommendedCallback = {
|
|||
|
||||
var SearchCallback = {
|
||||
searchSucceeded: function(addons, length, total) {
|
||||
do_check_false(addonRepo.isSearching);
|
||||
do_check_false(AddonRepository.isSearching);
|
||||
checkResults(addons, length);
|
||||
|
||||
server.stop(do_test_finished);
|
||||
|
@ -177,29 +189,26 @@ function run_test()
|
|||
Services.prefs.setCharPref(PREF_GETADDONS_BROWSESEARCHRESULTS, SEARCH + "%TERMS%");
|
||||
Services.prefs.setCharPref(PREF_GETADDONS_GETSEARCHRESULTS, "http://localhost:4444/test_%TERMS%.xml");
|
||||
|
||||
addonRepo = Components.classes["@mozilla.org/extensions/addon-repository;1"]
|
||||
.getService(Components.interfaces.nsIAddonRepository);
|
||||
|
||||
do_check_neq(addonRepo, null);
|
||||
do_check_neq(AddonRepository, null);
|
||||
// Check the homepage and recommended urls
|
||||
do_check_eq(addonRepo.homepageURL, BROWSE);
|
||||
do_check_eq(addonRepo.getRecommendedURL(), RECOMMENDED);
|
||||
do_check_eq(AddonRepository.homepageURL, BROWSE);
|
||||
do_check_eq(AddonRepository.getRecommendedURL(), RECOMMENDED);
|
||||
|
||||
// Check that search urls are correct
|
||||
for (var i = 0; i < BROWSE_SEARCH_URLS.length; i++) {
|
||||
var url = addonRepo.getSearchURL(BROWSE_SEARCH_URLS[i][0]);
|
||||
var url = AddonRepository.getSearchURL(BROWSE_SEARCH_URLS[i][0]);
|
||||
if (url != BROWSE_SEARCH_URLS[i][1])
|
||||
do_throw("BROWSE_SEARCH_URL[" + i + "] returned " + url);
|
||||
}
|
||||
|
||||
// This should fail because we cancel it immediately.
|
||||
addonRepo.retrieveRecommendedAddons(10, FailCallback);
|
||||
addonRepo.cancelSearch();
|
||||
AddonRepository.retrieveRecommendedAddons(10, FailCallback);
|
||||
AddonRepository.cancelSearch();
|
||||
// Pull some results.
|
||||
addonRepo.retrieveRecommendedAddons(10, RecommendedCallback);
|
||||
AddonRepository.retrieveRecommendedAddons(10, RecommendedCallback);
|
||||
// Should be searching now and any attempt to retrieve again should be ignored
|
||||
do_check_true(addonRepo.isSearching);
|
||||
addonRepo.retrieveRecommendedAddons(10, FailCallback);
|
||||
do_check_true(AddonRepository.isSearching);
|
||||
AddonRepository.retrieveRecommendedAddons(10, FailCallback);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
* ***** END LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
Components.utils.import("resource://gre/modules/AddonRepository.jsm");
|
||||
|
||||
const PREF_GETADDONS_BROWSEADDONS = "extensions.getAddons.browseAddons";
|
||||
const PREF_GETADDONS_BROWSERECOMMENDED = "extensions.getAddons.recommended.browseURL";
|
||||
const PREF_GETADDONS_GETRECOMMENDED = "extensions.getAddons.recommended.url";
|
||||
|
@ -55,38 +57,33 @@ var BROWSE_SEARCH_URLS = [
|
|||
|
||||
do_load_httpd_js();
|
||||
var server;
|
||||
var addonRepo;
|
||||
|
||||
var RESULTS = [
|
||||
{
|
||||
id: "test5@tests.mozilla.org",
|
||||
name: "PASS",
|
||||
version: "1.0",
|
||||
summary: "This should work fine",
|
||||
description: "Test description",
|
||||
rating: -1,
|
||||
iconURL: null,
|
||||
thumbnailURL: null,
|
||||
homepageURL: "https://addons.mozilla.org/addon/5992",
|
||||
eula: null,
|
||||
type: Ci.nsIAddonSearchResult.TYPE_EXTENSION,
|
||||
xpiURL: "http://localhost:4444/test.xpi",
|
||||
xpiHash: "sha1:c26f0b0d62e5dcddcda95074d3f3fedb9bbc26e3"
|
||||
id: "test5@tests.mozilla.org",
|
||||
name: "PASS",
|
||||
version: "1.0",
|
||||
description: "This should work fine",
|
||||
fullDescription: "Test description",
|
||||
rating: -1,
|
||||
iconURL: null,
|
||||
screenshots: [],
|
||||
homepageURL: "https://addons.mozilla.org/addon/5992",
|
||||
type: "extension",
|
||||
sourceURL: "http://localhost:4444/test.xpi"
|
||||
},
|
||||
{
|
||||
id: "test6@tests.mozilla.org",
|
||||
name: "PASS",
|
||||
version: "1.0",
|
||||
summary: "Specific OS should work fine",
|
||||
description: null,
|
||||
rating: 4,
|
||||
iconURL: "http://localhost:4444/test_bug404024/icon.png",
|
||||
thumbnailURL: "http://localhost:4444/test_bug404024/thumbnail.png",
|
||||
homepageURL: null,
|
||||
eula: "EULA should be confirmed",
|
||||
type: Ci.nsIAddonSearchResult.TYPE_THEME,
|
||||
xpiURL: "http://localhost:4444/XPCShell.xpi",
|
||||
xpiHash: null
|
||||
id: "test6@tests.mozilla.org",
|
||||
name: "PASS",
|
||||
version: "1.0",
|
||||
description: "Specific OS should work fine",
|
||||
fullDescription: null,
|
||||
rating: 4,
|
||||
iconURL: "http://localhost:4444/test_bug404024/icon.png",
|
||||
screenshots: ["http://localhost:4444/test_bug404024/thumbnail.png"],
|
||||
homepageURL: null,
|
||||
type: "theme",
|
||||
sourceURL: "http://localhost:4444/XPCShell.xpi"
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -101,7 +98,22 @@ function checkResults(addons) {
|
|||
}
|
||||
|
||||
for (var i = 0; i < addons.length; i++) {
|
||||
do_check_neq(addons[i]["install"], null);
|
||||
|
||||
for (var p in RESULTS[i]) {
|
||||
if (p == "screenshots") {
|
||||
do_check_eq(addons[i][p].length, RESULTS[i][p].length);
|
||||
for (var j = 0; j < addons[i][p].length; j++)
|
||||
do_check_eq(addons[i][p][j], addons[i][p][j]);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p == "sourceURL") {
|
||||
do_check_eq(addons[i]["install"][p], RESULTS[i][p]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (addons[i][p] != RESULTS[i][p])
|
||||
do_throw("Failed on property " + p + " on add-on " + addons[i].id +
|
||||
addons[i][p] + " == " + RESULTS[i][p]);
|
||||
|
@ -112,14 +124,14 @@ function checkResults(addons) {
|
|||
var RecommendedCallback = {
|
||||
searchSucceeded: function(addons, length, total) {
|
||||
// Search is complete
|
||||
do_check_false(addonRepo.isSearching);
|
||||
do_check_false(AddonRepository.isSearching);
|
||||
checkResults(addons);
|
||||
|
||||
// "search" for the same results
|
||||
addonRepo.searchAddons("bug417606", 10, SearchCallback);
|
||||
AddonRepository.searchAddons("bug417606", 10, SearchCallback);
|
||||
// Should be searching now and any attempt to retrieve again should be ignored
|
||||
do_check_true(addonRepo.isSearching);
|
||||
addonRepo.searchAddons("test search", 10, FailCallback);
|
||||
do_check_true(AddonRepository.isSearching);
|
||||
AddonRepository.searchAddons("test search", 10, FailCallback);
|
||||
},
|
||||
|
||||
searchFailed: function() {
|
||||
|
@ -130,7 +142,7 @@ var RecommendedCallback = {
|
|||
|
||||
var SearchCallback = {
|
||||
searchSucceeded: function(addons, length, total) {
|
||||
do_check_false(addonRepo.isSearching);
|
||||
do_check_false(AddonRepository.isSearching);
|
||||
do_check_eq(total, 100);
|
||||
checkResults(addons);
|
||||
|
||||
|
@ -177,29 +189,26 @@ function run_test()
|
|||
Services.prefs.setCharPref(PREF_GETADDONS_BROWSESEARCHRESULTS, SEARCH + "%TERMS%");
|
||||
Services.prefs.setCharPref(PREF_GETADDONS_GETSEARCHRESULTS, "http://localhost:4444/test_%TERMS%.xml");
|
||||
|
||||
addonRepo = Components.classes["@mozilla.org/extensions/addon-repository;1"]
|
||||
.getService(Components.interfaces.nsIAddonRepository);
|
||||
|
||||
do_check_neq(addonRepo, null);
|
||||
do_check_neq(AddonRepository, null);
|
||||
// Check the homepage and recommended urls
|
||||
do_check_eq(addonRepo.homepageURL, BROWSE);
|
||||
do_check_eq(addonRepo.getRecommendedURL(), RECOMMENDED);
|
||||
do_check_eq(AddonRepository.homepageURL, BROWSE);
|
||||
do_check_eq(AddonRepository.getRecommendedURL(), RECOMMENDED);
|
||||
|
||||
// Check that search urls are correct
|
||||
for (var i = 0; i < BROWSE_SEARCH_URLS.length; i++) {
|
||||
var url = addonRepo.getSearchURL(BROWSE_SEARCH_URLS[i][0]);
|
||||
var url = AddonRepository.getSearchURL(BROWSE_SEARCH_URLS[i][0]);
|
||||
if (url != BROWSE_SEARCH_URLS[i][1])
|
||||
do_throw("BROWSE_SEARCH_URL[" + i + "] returned " + url);
|
||||
}
|
||||
|
||||
// This should fail because we cancel it immediately.
|
||||
addonRepo.retrieveRecommendedAddons(10, FailCallback);
|
||||
addonRepo.cancelSearch();
|
||||
AddonRepository.retrieveRecommendedAddons(10, FailCallback);
|
||||
AddonRepository.cancelSearch();
|
||||
// Pull some results.
|
||||
addonRepo.retrieveRecommendedAddons(10, RecommendedCallback);
|
||||
AddonRepository.retrieveRecommendedAddons(10, RecommendedCallback);
|
||||
// Should be searching now and any attempt to retrieve again should be ignored
|
||||
do_check_true(addonRepo.isSearching);
|
||||
addonRepo.retrieveRecommendedAddons(10, FailCallback);
|
||||
do_check_true(AddonRepository.isSearching);
|
||||
AddonRepository.retrieveRecommendedAddons(10, FailCallback);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -35,13 +35,12 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK *****
|
||||
*/
|
||||
Components.utils.import("resource://gre/modules/AddonRepository.jsm");
|
||||
|
||||
const PREF_GETADDONS_GETRECOMMENDED = "extensions.getAddons.recommended.url";
|
||||
|
||||
do_load_httpd_js();
|
||||
var server;
|
||||
var addonRepo;
|
||||
|
||||
var RESULTS = [
|
||||
-1,
|
||||
-1,
|
||||
|
@ -85,13 +84,10 @@ function run_test()
|
|||
// Point the addons repository to the test server
|
||||
Services.prefs.setCharPref(PREF_GETADDONS_GETRECOMMENDED, "http://localhost:4444/test_bug424262.xml");
|
||||
|
||||
addonRepo = Components.classes["@mozilla.org/extensions/addon-repository;1"]
|
||||
.getService(Components.interfaces.nsIAddonRepository);
|
||||
|
||||
do_check_neq(addonRepo, null);
|
||||
do_check_neq(AddonRepository, null);
|
||||
|
||||
do_test_pending();
|
||||
// Pull some results.
|
||||
addonRepo.retrieveRecommendedAddons(RESULTS.length, RecommendedCallback);
|
||||
AddonRepository.retrieveRecommendedAddons(RESULTS.length, RecommendedCallback);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче