зеркало из https://github.com/mozilla/gecko-dev.git
Bug 595848: Dynamically generate the list of categories. r=Unfocused
This commit is contained in:
Родитель
c837809318
Коммит
e91f600ac1
|
@ -30,11 +30,6 @@
|
|||
<!-- categories / views -->
|
||||
<!ENTITY view.search.label "Search">
|
||||
<!ENTITY view.discover.label "Get Add-ons">
|
||||
<!ENTITY view.locales.label "Languages">
|
||||
<!ENTITY view.searchengines.label "Search Engines">
|
||||
<!ENTITY view.features.label "Extensions">
|
||||
<!ENTITY view.appearance2.label "Appearance">
|
||||
<!ENTITY view.plugins.label "Plugins">
|
||||
<!ENTITY view.recentUpdates.label "Recent Updates">
|
||||
<!ENTITY view.availableUpdates.label "Available Updates">
|
||||
|
||||
|
|
|
@ -104,3 +104,8 @@ cmd.purchaseAddon.accesskey=u
|
|||
|
||||
#LOCALIZATION NOTE (eulaHeader) %S is name of the add-on asking the user to agree to the EULA
|
||||
eulaHeader=%S requires that you accept the following End User License Agreement before installation can proceed:
|
||||
|
||||
type.extension.name=Extensions
|
||||
type.theme.name=Appearance
|
||||
type.locale.name=Languages
|
||||
type.plugin.name=Plugins
|
||||
|
|
|
@ -47,6 +47,8 @@ const PREF_EM_LAST_APP_VERSION = "extensions.lastAppVersion";
|
|||
const PREF_EM_LAST_PLATFORM_VERSION = "extensions.lastPlatformVersion";
|
||||
const PREF_EM_AUTOUPDATE_DEFAULT = "extensions.update.autoUpdateDefault";
|
||||
|
||||
const VALID_TYPES_REGEXP = /^[\w\-]+$/;
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
var EXPORTED_SYMBOLS = [ "AddonManager", "AddonManagerPrivate" ];
|
||||
|
@ -211,6 +213,54 @@ AddonScreenshot.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A type of add-on, used by the UI to determine how to display different types
|
||||
* of add-ons.
|
||||
*
|
||||
* @param aId
|
||||
* The add-on type ID
|
||||
* @param aLocaleURI
|
||||
* The URI of a localized properties file to get the displayable name
|
||||
* for the type from
|
||||
* @param aLocaleKey
|
||||
* The key for the string in the properties file or the actual display
|
||||
* name if aLocaleURI is null. Include %ID% to include the type ID in
|
||||
* the key
|
||||
* @param aViewType
|
||||
* The optional type of view to use in the UI
|
||||
* @param aUIPriority
|
||||
* The priority is used by the UI to list the types in order. Lower
|
||||
* values push the type higher in the list.
|
||||
* @param aFlags
|
||||
* An option set of flags that customize the display of the add-on in
|
||||
* the UI.
|
||||
*/
|
||||
function AddonType(aId, aLocaleURI, aLocaleKey, aViewType, aUIPriority, aFlags) {
|
||||
if (!aId)
|
||||
throw new Error("An AddonType must have an ID");
|
||||
if (aViewType && aUIPriority === undefined)
|
||||
throw new Error("An AddonType with a defined view must have a set UI priority");
|
||||
if (!aLocaleKey)
|
||||
throw new Error("An AddonType must have a displayable name");
|
||||
|
||||
this.id = aId;
|
||||
this.uiPriority = aUIPriority;
|
||||
this.viewType = aViewType;
|
||||
this.flags = aFlags;
|
||||
|
||||
if (aLocaleURI) {
|
||||
this.__defineGetter__("name", function() {
|
||||
delete this.name;
|
||||
let bundle = Services.strings.createBundle(aLocaleURI);
|
||||
this.name = bundle.GetStringFromName(aLocaleKey.replace("%ID%", aId));
|
||||
return this.name;
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.name = aLocaleKey;
|
||||
}
|
||||
}
|
||||
|
||||
var gStarted = false;
|
||||
|
||||
/**
|
||||
|
@ -220,7 +270,56 @@ var gStarted = false;
|
|||
var AddonManagerInternal = {
|
||||
installListeners: [],
|
||||
addonListeners: [],
|
||||
typeListeners: [],
|
||||
providers: [],
|
||||
types: {},
|
||||
|
||||
// A read-only wrapper around the types dictionary
|
||||
typesProxy: Proxy.create({
|
||||
getOwnPropertyDescriptor: function(aName) {
|
||||
if (!(aName in AddonManagerInternal.types))
|
||||
return undefined;
|
||||
|
||||
return {
|
||||
value: AddonManagerInternal.types[aName].type,
|
||||
writable: false,
|
||||
configurable: false,
|
||||
enumerable: true
|
||||
}
|
||||
},
|
||||
|
||||
getPropertyDescriptor: function(aName) {
|
||||
return this.getOwnPropertyDescriptor(aName);
|
||||
},
|
||||
|
||||
getOwnPropertyNames: function() {
|
||||
return Object.keys(AddonManagerInternal.types);
|
||||
},
|
||||
|
||||
getPropertyNames: function() {
|
||||
return this.getOwnPropertyNames();
|
||||
},
|
||||
|
||||
delete: function(aName) {
|
||||
// Not allowed to delete properties
|
||||
return false;
|
||||
},
|
||||
|
||||
defineProperty: function(aName, aProperty) {
|
||||
// Ignore attempts to define properties
|
||||
},
|
||||
|
||||
fix: function() {
|
||||
return undefined;
|
||||
},
|
||||
|
||||
// Despite MDC's claims to the contrary, it is required that this trap
|
||||
// be defined
|
||||
enumerate: function() {
|
||||
// All properties are enumerable
|
||||
return this.getPropertyNames();
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Initializes the AddonManager, loading any known providers and initializing
|
||||
|
@ -294,10 +393,37 @@ var AddonManagerInternal = {
|
|||
*
|
||||
* @param aProvider
|
||||
* The provider to register
|
||||
* @param aTypes
|
||||
* An array of add-on types
|
||||
*/
|
||||
registerProvider: function AMI_registerProvider(aProvider) {
|
||||
registerProvider: function AMI_registerProvider(aProvider, aTypes) {
|
||||
this.providers.push(aProvider);
|
||||
|
||||
if (aTypes) {
|
||||
aTypes.forEach(function(aType) {
|
||||
if (!(aType.id in this.types)) {
|
||||
if (!VALID_TYPES_REGEXP.test(aType.id)) {
|
||||
WARN("Ignoring invalid type " + aType.id);
|
||||
return;
|
||||
}
|
||||
|
||||
this.types[aType.id] = {
|
||||
type: aType,
|
||||
providers: [aProvider]
|
||||
};
|
||||
|
||||
this.typeListeners.forEach(function(aListener) {
|
||||
safeCall(function() {
|
||||
aListener.onTypeAdded(aType);
|
||||
});
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.types[aType.id].providers.push(aProvider);
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
|
||||
// If we're registering after startup call this provider's startup.
|
||||
if (gStarted)
|
||||
callProvider(aProvider, "startup");
|
||||
|
@ -318,6 +444,20 @@ var AddonManagerInternal = {
|
|||
pos++;
|
||||
}
|
||||
|
||||
for (let type in this.types) {
|
||||
this.types[type].providers = this.types[type].providers.filter(function(p) p != aProvider);
|
||||
if (this.types[type].providers.length == 0) {
|
||||
let oldType = this.types[type].type;
|
||||
delete this.types[type];
|
||||
|
||||
this.typeListeners.forEach(function(aListener) {
|
||||
safeCall(function() {
|
||||
aListener.onTypeRemoved(oldType);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// If we're unregistering after startup call this provider's shutdown.
|
||||
if (gStarted)
|
||||
callProvider(aProvider, "shutdown");
|
||||
|
@ -334,6 +474,7 @@ var AddonManagerInternal = {
|
|||
|
||||
this.installListeners.splice(0);
|
||||
this.addonListeners.splice(0);
|
||||
this.typeListeners.splice(0);
|
||||
gStarted = false;
|
||||
},
|
||||
|
||||
|
@ -869,6 +1010,25 @@ var AddonManagerInternal = {
|
|||
}
|
||||
},
|
||||
|
||||
addTypeListener: function AMI_addTypeListener(aListener) {
|
||||
if (!this.typeListeners.some(function(i) { return i == aListener; }))
|
||||
this.typeListeners.push(aListener);
|
||||
},
|
||||
|
||||
removeTypeListener: function AMI_removeTypeListener(aListener) {
|
||||
let pos = 0;
|
||||
while (pos < this.typeListeners.length) {
|
||||
if (this.typeListeners[pos] == aListener)
|
||||
this.typeListeners.splice(pos, 1);
|
||||
else
|
||||
pos++;
|
||||
}
|
||||
},
|
||||
|
||||
get addonTypes() {
|
||||
return this.typesProxy;
|
||||
},
|
||||
|
||||
get autoUpdateDefault() {
|
||||
try {
|
||||
return Services.prefs.getBoolPref(PREF_EM_AUTOUPDATE_DEFAULT);
|
||||
|
@ -888,8 +1048,8 @@ var AddonManagerPrivate = {
|
|||
AddonManagerInternal.startup();
|
||||
},
|
||||
|
||||
registerProvider: function AMP_registerProvider(aProvider) {
|
||||
AddonManagerInternal.registerProvider(aProvider);
|
||||
registerProvider: function AMP_registerProvider(aProvider, aTypes) {
|
||||
AddonManagerInternal.registerProvider(aProvider, aTypes);
|
||||
},
|
||||
|
||||
unregisterProvider: function AMP_unregisterProvider(aProvider) {
|
||||
|
@ -923,7 +1083,9 @@ var AddonManagerPrivate = {
|
|||
|
||||
AddonAuthor: AddonAuthor,
|
||||
|
||||
AddonScreenshot: AddonScreenshot
|
||||
AddonScreenshot: AddonScreenshot,
|
||||
|
||||
AddonType: AddonType
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1036,6 +1198,11 @@ var AddonManager = {
|
|||
// The combination of all scopes.
|
||||
SCOPE_ALL: 15,
|
||||
|
||||
// 1-15 are different built-in views for the add-on type
|
||||
VIEW_TYPE_LIST: "list",
|
||||
|
||||
TYPE_UI_HIDE_EMPTY: 16,
|
||||
|
||||
// Constants for Addon.applyBackgroundUpdates.
|
||||
// Indicates that the Addon should not update automatically.
|
||||
AUTOUPDATE_DISABLE: 0,
|
||||
|
@ -1114,6 +1281,18 @@ var AddonManager = {
|
|||
AddonManagerInternal.removeAddonListener(aListener);
|
||||
},
|
||||
|
||||
addTypeListener: function AM_addTypeListener(aListener) {
|
||||
AddonManagerInternal.addTypeListener(aListener);
|
||||
},
|
||||
|
||||
removeTypeListener: function AM_removeTypeListener(aListener) {
|
||||
AddonManagerInternal.removeTypeListener(aListener);
|
||||
},
|
||||
|
||||
get addonTypes() {
|
||||
return AddonManagerInternal.addonTypes;
|
||||
},
|
||||
|
||||
get autoUpdateDefault() {
|
||||
return AddonManagerInternal.autoUpdateDefault;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,10 @@ const PREF_GENERAL_SKINS_SELECTEDSKIN = "general.skins.selectedSkin";
|
|||
const PREF_EM_DSS_ENABLED = "extensions.dss.enabled";
|
||||
const ADDON_TYPE = "theme";
|
||||
|
||||
const URI_EXTENSION_STRINGS = "chrome://mozapps/locale/extensions/extensions.properties";
|
||||
|
||||
const STRING_TYPE_NAME = "type.%ID%.name";
|
||||
|
||||
const DEFAULT_MAX_USED_THEMES_COUNT = 30;
|
||||
|
||||
const MAX_PREVIEW_SECONDS = 30;
|
||||
|
@ -803,4 +807,8 @@ function _persistProgressListener(successCallback) {
|
|||
};
|
||||
}
|
||||
|
||||
AddonManagerPrivate.registerProvider(LightweightThemeManager);
|
||||
AddonManagerPrivate.registerProvider(LightweightThemeManager, [
|
||||
new AddonManagerPrivate.AddonType("theme", URI_EXTENSION_STRINGS,
|
||||
STRING_TYPE_NAME,
|
||||
AddonManager.VIEW_TYPE_LIST, 5000)
|
||||
]);
|
||||
|
|
|
@ -45,6 +45,9 @@ var EXPORTED_SYMBOLS = [];
|
|||
Components.utils.import("resource://gre/modules/AddonManager.jsm");
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const URI_EXTENSION_STRINGS = "chrome://mozapps/locale/extensions/extensions.properties";
|
||||
const STRING_TYPE_NAME = "type.%ID%.name";
|
||||
|
||||
["LOG", "WARN", "ERROR"].forEach(function(aName) {
|
||||
this.__defineGetter__(aName, function() {
|
||||
Components.utils.import("resource://gre/modules/AddonLogging.jsm");
|
||||
|
@ -342,4 +345,8 @@ PluginWrapper.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
AddonManagerPrivate.registerProvider(PluginProvider);
|
||||
AddonManagerPrivate.registerProvider(PluginProvider, [
|
||||
new AddonManagerPrivate.AddonType("plugin", URI_EXTENSION_STRINGS,
|
||||
STRING_TYPE_NAME,
|
||||
AddonManager.VIEW_TYPE_LIST, 6000)
|
||||
]);
|
||||
|
|
|
@ -78,6 +78,9 @@ const PREF_INSTALL_DISTRO_ADDONS = "extensions.installDistroAddons";
|
|||
const PREF_BRANCH_INSTALLED_ADDON = "extensions.installedDistroAddon.";
|
||||
|
||||
const URI_EXTENSION_UPDATE_DIALOG = "chrome://mozapps/content/extensions/update.xul";
|
||||
const URI_EXTENSION_STRINGS = "chrome://mozapps/locale/extensions/extensions.properties";
|
||||
|
||||
const STRING_TYPE_NAME = "type.%ID%.name";
|
||||
|
||||
const DIR_EXTENSIONS = "extensions";
|
||||
const DIR_STAGE = "staged";
|
||||
|
@ -7655,4 +7658,15 @@ WinRegInstallLocation.prototype = {
|
|||
};
|
||||
#endif
|
||||
|
||||
AddonManagerPrivate.registerProvider(XPIProvider);
|
||||
AddonManagerPrivate.registerProvider(XPIProvider, [
|
||||
new AddonManagerPrivate.AddonType("extension", URI_EXTENSION_STRINGS,
|
||||
STRING_TYPE_NAME,
|
||||
AddonManager.VIEW_TYPE_LIST, 4000),
|
||||
new AddonManagerPrivate.AddonType("theme", URI_EXTENSION_STRINGS,
|
||||
STRING_TYPE_NAME,
|
||||
AddonManager.VIEW_TYPE_LIST, 5000),
|
||||
new AddonManagerPrivate.AddonType("locale", URI_EXTENSION_STRINGS,
|
||||
STRING_TYPE_NAME,
|
||||
AddonManager.VIEW_TYPE_LIST, 2000,
|
||||
AddonManager.TYPE_UI_HIDE_EMPTY)
|
||||
]);
|
||||
|
|
|
@ -55,6 +55,7 @@ const PREF_CHECK_UPDATE_SECURITY = "extensions.checkUpdateSecurity";
|
|||
const PREF_AUTOUPDATE_DEFAULT = "extensions.update.autoUpdateDefault";
|
||||
const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled";
|
||||
const PREF_GETADDONS_CACHE_ID_ENABLED = "extensions.%ID%.getAddons.cache.enabled";
|
||||
const PREF_UI_TYPE_HIDDEN = "extensions.ui.%TYPE%.hidden";
|
||||
const PREF_UI_LASTCATEGORY = "extensions.ui.lastCategory";
|
||||
|
||||
const BRANCH_REGEXP = /^([^\.]+\.[0-9]+[a-z]*).*/gi;
|
||||
|
@ -106,9 +107,9 @@ __defineGetter__("gIsInitializing", function() gPendingInitializations > 0);
|
|||
|
||||
function initialize() {
|
||||
document.removeEventListener("load", initialize, true);
|
||||
gViewController.initialize();
|
||||
gCategories.initialize();
|
||||
gHeader.initialize();
|
||||
gViewController.initialize();
|
||||
gEventManager.initialize();
|
||||
Services.obs.addObserver(sendEMPong, "EM-ping", false);
|
||||
Services.obs.notifyObservers(window, "EM-loaded", "");
|
||||
|
@ -165,6 +166,7 @@ function loadView(aViewId) {
|
|||
if (!gViewController.initialViewSelected) {
|
||||
// The caller opened the window and immediately loaded the view so it
|
||||
// should be the initial history entry
|
||||
|
||||
gViewController.loadInitialView(aViewId);
|
||||
} else {
|
||||
gViewController.loadView(aViewId);
|
||||
|
@ -176,6 +178,12 @@ function loadView(aViewId) {
|
|||
* back/forward controls to work within the manager
|
||||
*/
|
||||
var HTML5History = {
|
||||
get index() {
|
||||
return window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.sessionHistory.index;
|
||||
},
|
||||
|
||||
get canGoBack() {
|
||||
return window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
|
@ -229,6 +237,10 @@ var FakeHistory = {
|
|||
pos: 0,
|
||||
states: [null],
|
||||
|
||||
get index() {
|
||||
return this.pos;
|
||||
},
|
||||
|
||||
get canGoBack() {
|
||||
return this.pos > 0;
|
||||
},
|
||||
|
@ -493,6 +505,7 @@ var gViewController = {
|
|||
viewObjects: {},
|
||||
viewChangeCallback: null,
|
||||
initialViewSelected: false,
|
||||
lastHistoryIndex: -1,
|
||||
|
||||
initialize: function() {
|
||||
this.viewPort = document.getElementById("view-port");
|
||||
|
@ -535,7 +548,24 @@ var gViewController = {
|
|||
},
|
||||
|
||||
updateState: function(state) {
|
||||
this.loadViewInternal(state.view, state.previousView, state);
|
||||
try {
|
||||
this.loadViewInternal(state.view, state.previousView, state);
|
||||
this.lastHistoryIndex = gHistory.index;
|
||||
}
|
||||
catch (e) {
|
||||
// The attempt to load the view failed, try moving further along history
|
||||
if (this.lastHistoryIndex > gHistory.index) {
|
||||
if (gHistory.canGoBack)
|
||||
gHistory.back();
|
||||
else
|
||||
gViewController.replaceView(VIEW_DEFAULT);
|
||||
} else {
|
||||
if (gHistory.canGoForward)
|
||||
gHistory.forward();
|
||||
else
|
||||
gViewController.replaceView(VIEW_DEFAULT);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
parseViewId: function(aViewId) {
|
||||
|
@ -564,8 +594,10 @@ var gViewController = {
|
|||
view: aViewId,
|
||||
previousView: this.currentViewId
|
||||
};
|
||||
if (!isRefresh)
|
||||
if (!isRefresh) {
|
||||
gHistory.pushState(state);
|
||||
this.lastHistoryIndex = gHistory.index;
|
||||
}
|
||||
this.loadViewInternal(aViewId, this.currentViewId, state);
|
||||
},
|
||||
|
||||
|
@ -1416,12 +1448,17 @@ function doPendingUninstalls(aListBox) {
|
|||
var gCategories = {
|
||||
node: null,
|
||||
_search: null,
|
||||
_maybeHidden: null,
|
||||
|
||||
initialize: function() {
|
||||
this.node = document.getElementById("categories");
|
||||
this._search = this.get("addons://search/");
|
||||
|
||||
var types = AddonManager.addonTypes;
|
||||
for (var type in types)
|
||||
this.onTypeAdded(types[type]);
|
||||
|
||||
AddonManager.addTypeListener(this);
|
||||
|
||||
try {
|
||||
this.node.value = Services.prefs.getCharPref(PREF_UI_LASTCATEGORY);
|
||||
} catch (e) { }
|
||||
|
@ -1451,20 +1488,88 @@ var gCategories = {
|
|||
gViewController.loadView(viewId);
|
||||
}
|
||||
}, false);
|
||||
},
|
||||
|
||||
this._maybeHidden = ["addons://list/locale", "addons://list/searchengine"];
|
||||
gPendingInitializations += this._maybeHidden.length;
|
||||
this._maybeHidden.forEach(function(aId) {
|
||||
var type = gViewController.parseViewId(aId).param;
|
||||
getAddonsAndInstalls(type, function(aAddonsList, aInstallsList) {
|
||||
shutdown: function() {
|
||||
AddonManager.removeTypeListener(this);
|
||||
},
|
||||
|
||||
_insertCategory: function(aId, aName, aView, aPriority, aStartHidden) {
|
||||
// If this category already exists then don't re-add it
|
||||
if (document.getElementById("category-" + aId))
|
||||
return;
|
||||
|
||||
var category = document.createElement("richlistitem");
|
||||
category.setAttribute("id", "category-" + aId);
|
||||
category.setAttribute("value", aView);
|
||||
category.setAttribute("class", "category");
|
||||
category.setAttribute("name", aName);
|
||||
category.setAttribute("tooltiptext", aName);
|
||||
category.setAttribute("priority", aPriority);
|
||||
category.setAttribute("hidden", aStartHidden);
|
||||
|
||||
var node = this.node.firstChild;
|
||||
while (node = node.nextSibling) {
|
||||
var nodePriority = parseInt(node.getAttribute("priority"));
|
||||
// If the new type's priority is higher than this one then this is the
|
||||
// insertion point
|
||||
if (aPriority < nodePriority)
|
||||
break;
|
||||
// If the new type's priority is lower than this one then this is isn't
|
||||
// the insertion point
|
||||
if (aPriority > nodePriority)
|
||||
continue;
|
||||
// If the priorities are equal and the new type's name is earlier
|
||||
// alphabetically then this is the insertion point
|
||||
if (String.localeCompare(aName, node.getAttribute("name")) < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
this.node.insertBefore(category, node);
|
||||
},
|
||||
|
||||
_removeCategory: function(aId) {
|
||||
var category = document.getElementById("category-" + aId);
|
||||
if (!category)
|
||||
return;
|
||||
|
||||
// If this category is currently selected then switch to the default view
|
||||
if (this.node.selectedItem == category)
|
||||
gViewController.replaceView(VIEW_DEFAULT);
|
||||
|
||||
this.node.removeChild(category);
|
||||
},
|
||||
|
||||
onTypeAdded: function(aType) {
|
||||
// Ignore types that we don't have a view object for
|
||||
if (!(aType.viewType in gViewController.viewObjects))
|
||||
return;
|
||||
|
||||
var aViewId = "addons://" + aType.viewType + "/" + aType.id;
|
||||
|
||||
var startHidden = false;
|
||||
if (aType.flags & AddonManager.TYPE_UI_HIDE_EMPTY) {
|
||||
var prefName = PREF_UI_TYPE_HIDDEN.replace("%TYPE%", aType.id);
|
||||
try {
|
||||
startHidden = Services.prefs.getBoolPref(prefName);
|
||||
}
|
||||
catch (e) {
|
||||
// Default to hidden
|
||||
startHidden = true;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
gPendingInitializations++;
|
||||
getAddonsAndInstalls(aType.id, function(aAddonsList, aInstallsList) {
|
||||
var hidden = (aAddonsList.length == 0 && aInstallsList.length == 0);
|
||||
var item = self.get(aId);
|
||||
var item = self.get(aViewId);
|
||||
|
||||
// Don't load view that is becoming hidden
|
||||
if (hidden && aId == gViewController.currentViewId)
|
||||
if (hidden && aViewId == gViewController.currentViewId)
|
||||
gViewController.loadView(VIEW_DEFAULT);
|
||||
|
||||
item.hidden = hidden;
|
||||
Services.prefs.setBoolPref(prefName, hidden);
|
||||
|
||||
if (aAddonsList.length > 0 || aInstallsList.length > 0) {
|
||||
notifyInitialized();
|
||||
|
@ -1489,8 +1594,9 @@ var gCategories = {
|
|||
},
|
||||
|
||||
_maybeShowCategory: function(aAddon) {
|
||||
if (type == aAddon.type) {
|
||||
self.get(aId).hidden = false;
|
||||
if (aType.id == aAddon.type) {
|
||||
self.get(aViewId).hidden = false;
|
||||
Services.prefs.setBoolPref(prefName, false);
|
||||
gEventManager.unregisterInstallListener(this);
|
||||
}
|
||||
}
|
||||
|
@ -1498,16 +1604,14 @@ var gCategories = {
|
|||
|
||||
notifyInitialized();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
this._insertCategory(aType.id, aType.name, aViewId, aType.uiPriority,
|
||||
startHidden);
|
||||
},
|
||||
|
||||
shutdown: function() {
|
||||
// Force persist of hidden state. See bug 15232
|
||||
var self = this;
|
||||
this._maybeHidden.forEach(function(aId) {
|
||||
var item = self.get(aId);
|
||||
item.setAttribute("hidden", !!item.hidden);
|
||||
});
|
||||
onTypeRemoved: function(aType) {
|
||||
this._removeCategory(aType.id);
|
||||
},
|
||||
|
||||
get selected() {
|
||||
|
@ -1801,6 +1905,7 @@ var gDiscoverView = {
|
|||
gHistory.replaceState(state);
|
||||
else
|
||||
gHistory.pushState(state);
|
||||
gViewController.lastHistoryIndex = gHistory.index;
|
||||
}
|
||||
|
||||
gViewController.updateCommands();
|
||||
|
@ -2228,6 +2333,9 @@ var gListView = {
|
|||
},
|
||||
|
||||
show: function(aType, aRequest) {
|
||||
if (!(aType in AddonManager.addonTypes))
|
||||
throw new Error("Attempting to show unknown type " + aType);
|
||||
|
||||
this._type = aType;
|
||||
this.node.setAttribute("type", aType);
|
||||
this.showEmptyNotice(false);
|
||||
|
|
|
@ -211,43 +211,20 @@
|
|||
<richlistbox id="categories">
|
||||
<richlistitem id="category-search" value="addons://search/"
|
||||
class="category"
|
||||
name="&view.search.label;"
|
||||
name="&view.search.label;" priority="0"
|
||||
tooltiptext="&view.search.label;" disabled="true"/>
|
||||
<richlistitem id="category-discover" value="addons://discover/"
|
||||
class="category"
|
||||
name="&view.discover.label;"
|
||||
name="&view.discover.label;" priority="1000"
|
||||
tooltiptext="&view.discover.label;"/>
|
||||
<richlistitem id="category-languages" value="addons://list/locale"
|
||||
class="category"
|
||||
name="&view.locales.label;"
|
||||
tooltiptext="&view.locales.label;"
|
||||
hidden="true" persist="hidden"/>
|
||||
<richlistitem id="category-searchengines"
|
||||
value="addons://list/searchengine"
|
||||
class="category"
|
||||
name="&view.searchengines.label;"
|
||||
tooltiptext="&view.searchengines.label;"
|
||||
hidden="true" persist="hidden"/>
|
||||
<richlistitem id="category-extensions" value="addons://list/extension"
|
||||
class="category"
|
||||
name="&view.features.label;"
|
||||
tooltiptext="&view.features.label;"/>
|
||||
<richlistitem id="category-themes" value="addons://list/theme"
|
||||
class="category"
|
||||
name="&view.appearance2.label;"
|
||||
tooltiptext="&view.appearance2.label;"/>
|
||||
<richlistitem id="category-plugins" value="addons://list/plugin"
|
||||
class="category"
|
||||
name="&view.plugins.label;"
|
||||
tooltiptext="&view.plugins.label;"/>
|
||||
<richlistitem id="category-availableUpdates" value="addons://updates/available"
|
||||
class="category"
|
||||
name="&view.availableUpdates.label;"
|
||||
name="&view.availableUpdates.label;" priority="100000"
|
||||
tooltiptext="&view.availableUpdates.label;"
|
||||
disabled="true"/>
|
||||
<richlistitem id="category-recentUpdates" value="addons://updates/recent"
|
||||
class="category"
|
||||
name="&view.recentUpdates.label;"
|
||||
name="&view.recentUpdates.label;" priority="101000"
|
||||
tooltiptext="&view.recentUpdates.label;" disabled="true"/>
|
||||
</richlistbox>
|
||||
|
||||
|
|
|
@ -86,6 +86,7 @@ _MAIN_TEST_FILES = \
|
|||
browser_updateid.js \
|
||||
browser_purchase.js \
|
||||
browser_openDialog.js \
|
||||
browser_types.js \
|
||||
$(NULL)
|
||||
|
||||
_TEST_FILES = \
|
||||
|
|
|
@ -185,7 +185,7 @@ add_test(function() {
|
|||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/extension", false, false);
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugins"), { }, aManager);
|
||||
EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugin"), { }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 2");
|
||||
|
@ -303,7 +303,7 @@ add_test(function() {
|
|||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/extension", false, false);
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugins"), { }, aManager);
|
||||
EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugin"), { }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 2");
|
||||
|
@ -356,7 +356,7 @@ add_test(function() {
|
|||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/plugin", false, false);
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-extensions"), { }, aManager);
|
||||
EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-extension"), { }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 2");
|
||||
|
@ -625,7 +625,7 @@ add_test(function() {
|
|||
info("Part 1");
|
||||
is_in_list(aManager, "addons://list/extension", false, false);
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugins"), { }, aManager);
|
||||
EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugin"), { }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
info("Part 2");
|
||||
|
@ -783,7 +783,7 @@ add_test(function() {
|
|||
waitForLoad(aManager, function() {
|
||||
is_in_discovery(aManager, SECOND_URL, true, false);
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugins"), { }, aManager);
|
||||
EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugin"), { }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
is_in_list(aManager, "addons://list/plugin", true, false);
|
||||
|
@ -831,7 +831,7 @@ add_test(function() {
|
|||
waitForLoad(aManager, function() {
|
||||
is_in_discovery(aManager, SECOND_URL, true, false);
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugins"), { }, aManager);
|
||||
EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugin"), { }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
is_in_list(aManager, "addons://list/plugin", true, false);
|
||||
|
|
|
@ -33,7 +33,12 @@ let gExtensionProperties = {
|
|||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
gProvider = new MockProvider();
|
||||
gProvider = new MockProvider(true, [{
|
||||
id: "mock-addon",
|
||||
name: "Mock Add-ons",
|
||||
uiPriority: 4500,
|
||||
flags: AddonManager.TYPE_UI_VIEW_LIST
|
||||
}]);
|
||||
|
||||
open_manager(VIEW_ID, function(aWindow) {
|
||||
gManagerWindow = aWindow;
|
||||
|
|
|
@ -20,7 +20,7 @@ add_test(function() {
|
|||
is_element_hidden(button, "Plugin Check message button should be hidden");
|
||||
|
||||
info("Changing view to plugins")
|
||||
EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugins"), { }, aManager);
|
||||
EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("category-plugin"), { }, aManager);
|
||||
|
||||
wait_for_view_load(aManager, function(aManager) {
|
||||
var button = aManager.document.querySelector("#list-view hbox.global-info-plugincheck button.button-link");
|
||||
|
|
|
@ -0,0 +1,473 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Tests that registering new types works
|
||||
|
||||
var gManagerWindow;
|
||||
var gCategoryUtilities;
|
||||
|
||||
var gProvider = {
|
||||
};
|
||||
|
||||
var gTypes = [
|
||||
new AddonManagerPrivate.AddonType("type1", null, "Type 1",
|
||||
AddonManager.VIEW_TYPE_LIST, 4500),
|
||||
new AddonManagerPrivate.AddonType("missing1", null, "Missing 1"),
|
||||
new AddonManagerPrivate.AddonType("type2", null, "Type 1",
|
||||
AddonManager.VIEW_TYPE_LIST, 5100,
|
||||
AddonManager.TYPE_UI_HIDE_EMPTY),
|
||||
{
|
||||
id: "type3",
|
||||
name: "Type 3",
|
||||
uiPriority: 5200,
|
||||
viewType: AddonManager.VIEW_TYPE_LIST
|
||||
}
|
||||
];
|
||||
|
||||
function go_back(aManager) {
|
||||
if (gUseInContentUI) {
|
||||
gBrowser.goBack();
|
||||
} else {
|
||||
EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("back-btn"),
|
||||
{ }, aManager);
|
||||
}
|
||||
}
|
||||
|
||||
function go_forward(aManager) {
|
||||
if (gUseInContentUI) {
|
||||
gBrowser.goForward();
|
||||
} else {
|
||||
EventUtils.synthesizeMouseAtCenter(aManager.document.getElementById("forward-btn"),
|
||||
{ }, aManager);
|
||||
}
|
||||
}
|
||||
|
||||
function check_state(aManager, canGoBack, canGoForward) {
|
||||
var doc = aManager.document;
|
||||
|
||||
if (gUseInContentUI) {
|
||||
is(gBrowser.canGoBack, canGoBack, "canGoBack should be correct");
|
||||
is(gBrowser.canGoForward, canGoForward, "canGoForward should be correct");
|
||||
}
|
||||
|
||||
if (!is_hidden(doc.getElementById("back-btn"))) {
|
||||
is(!doc.getElementById("back-btn").disabled, canGoBack, "Back button should have the right state");
|
||||
is(!doc.getElementById("forward-btn").disabled, canGoForward, "Forward button should have the right state");
|
||||
}
|
||||
}
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function end_test() {
|
||||
finish();
|
||||
}
|
||||
|
||||
// Add a new type, open the manager and make sure it is in the right place
|
||||
add_test(function() {
|
||||
AddonManagerPrivate.registerProvider(gProvider, gTypes);
|
||||
|
||||
open_manager(null, function(aWindow) {
|
||||
gManagerWindow = aWindow;
|
||||
gCategoryUtilities = new CategoryUtilities(gManagerWindow);
|
||||
|
||||
ok(gCategoryUtilities.get("type1"), "Type 1 should be present");
|
||||
ok(gCategoryUtilities.get("type2"), "Type 2 should be present");
|
||||
ok(!gCategoryUtilities.get("missing1", true), "Missing 1 should be absent");
|
||||
|
||||
is(gCategoryUtilities.get("type1").previousSibling.getAttribute("value"),
|
||||
"addons://list/extension", "Type 1 should be in the right place");
|
||||
is(gCategoryUtilities.get("type2").previousSibling.getAttribute("value"),
|
||||
"addons://list/theme", "Type 2 should be in the right place");
|
||||
|
||||
ok(gCategoryUtilities.isTypeVisible("type1"), "Type 1 should be visible");
|
||||
ok(!gCategoryUtilities.isTypeVisible("type2"), "Type 2 should be hidden");
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
|
||||
// Select the type, close the manager and remove it then open the manager and
|
||||
// check we're back to the default view
|
||||
add_test(function() {
|
||||
gCategoryUtilities.openType("type1", function() {
|
||||
close_manager(gManagerWindow, function() {
|
||||
AddonManagerPrivate.unregisterProvider(gProvider);
|
||||
|
||||
open_manager(null, function(aWindow) {
|
||||
gManagerWindow = aWindow;
|
||||
gCategoryUtilities = new CategoryUtilities(gManagerWindow);
|
||||
|
||||
ok(!gCategoryUtilities.get("type1", true), "Type 1 should be absent");
|
||||
ok(!gCategoryUtilities.get("type2", true), "Type 2 should be absent");
|
||||
ok(!gCategoryUtilities.get("missing1", true), "Missing 1 should be absent");
|
||||
|
||||
is(gCategoryUtilities.selectedCategory, "discover", "Should be back to the default view");
|
||||
|
||||
close_manager(gManagerWindow, run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Add a type while the manager is still open and check it appears
|
||||
add_test(function() {
|
||||
open_manager("addons://list/extension", function(aWindow) {
|
||||
gManagerWindow = aWindow;
|
||||
gCategoryUtilities = new CategoryUtilities(gManagerWindow);
|
||||
|
||||
ok(!gCategoryUtilities.get("type1", true), "Type 1 should be absent");
|
||||
ok(!gCategoryUtilities.get("type2", true), "Type 2 should be absent");
|
||||
ok(!gCategoryUtilities.get("missing1", true), "Missing 1 should be absent");
|
||||
|
||||
AddonManagerPrivate.registerProvider(gProvider, gTypes);
|
||||
|
||||
ok(gCategoryUtilities.get("type1"), "Type 1 should be present");
|
||||
ok(gCategoryUtilities.get("type2"), "Type 2 should be present");
|
||||
ok(!gCategoryUtilities.get("missing1", true), "Missing 1 should be absent");
|
||||
|
||||
is(gCategoryUtilities.get("type1").previousSibling.getAttribute("value"),
|
||||
"addons://list/extension", "Type 1 should be in the right place");
|
||||
is(gCategoryUtilities.get("type2").previousSibling.getAttribute("value"),
|
||||
"addons://list/theme", "Type 2 should be in the right place");
|
||||
|
||||
ok(gCategoryUtilities.isTypeVisible("type1"), "Type 1 should be visible");
|
||||
ok(!gCategoryUtilities.isTypeVisible("type2"), "Type 2 should be hidden");
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
|
||||
// Remove the type while it is beng viewed and check it is replaced with the
|
||||
// default view
|
||||
add_test(function() {
|
||||
gCategoryUtilities.openType("type1", function() {
|
||||
gCategoryUtilities.openType("plugin", function() {
|
||||
go_back(gManagerWindow);
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
is(gCategoryUtilities.selectedCategory, "type1", "Should be showing the custom view");
|
||||
check_state(gManagerWindow, true, true);
|
||||
|
||||
AddonManagerPrivate.unregisterProvider(gProvider);
|
||||
|
||||
ok(!gCategoryUtilities.get("type1", true), "Type 1 should be absent");
|
||||
ok(!gCategoryUtilities.get("type2", true), "Type 2 should be absent");
|
||||
ok(!gCategoryUtilities.get("missing1", true), "Missing 1 should be absent");
|
||||
|
||||
is(gCategoryUtilities.selectedCategory, "discover", "Should be back to the default view");
|
||||
check_state(gManagerWindow, true, true);
|
||||
|
||||
go_back(gManagerWindow);
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
is(gCategoryUtilities.selectedCategory, "extension", "Should be showing the extension view");
|
||||
check_state(gManagerWindow, false, true);
|
||||
|
||||
go_forward(gManagerWindow);
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
is(gCategoryUtilities.selectedCategory, "discover", "Should be back to the default view");
|
||||
check_state(gManagerWindow, true, true);
|
||||
|
||||
go_forward(gManagerWindow);
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
is(gCategoryUtilities.selectedCategory, "plugin", "Should be back to the plugins view");
|
||||
check_state(gManagerWindow, true, false);
|
||||
|
||||
go_back(gManagerWindow);
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
is(gCategoryUtilities.selectedCategory, "discover", "Should be back to the default view");
|
||||
check_state(gManagerWindow, true, true);
|
||||
|
||||
close_manager(gManagerWindow, run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Test that when going back to a now missing category we skip it
|
||||
add_test(function() {
|
||||
open_manager("addons://list/extension", function(aWindow) {
|
||||
gManagerWindow = aWindow;
|
||||
gCategoryUtilities = new CategoryUtilities(gManagerWindow);
|
||||
|
||||
AddonManagerPrivate.registerProvider(gProvider, gTypes);
|
||||
|
||||
ok(gCategoryUtilities.get("type1"), "Type 1 should be present");
|
||||
ok(gCategoryUtilities.isTypeVisible("type1"), "Type 1 should be visible");
|
||||
|
||||
gCategoryUtilities.openType("type1", function() {
|
||||
gCategoryUtilities.openType("plugin", function() {
|
||||
AddonManagerPrivate.unregisterProvider(gProvider);
|
||||
|
||||
ok(!gCategoryUtilities.get("type1", true), "Type 1 should not be present");
|
||||
|
||||
go_back(gManagerWindow);
|
||||
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
is(gCategoryUtilities.selectedCategory, "extension", "Should be back to the first view");
|
||||
check_state(gManagerWindow, false, true);
|
||||
|
||||
close_manager(gManagerWindow, run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Test that when going forward to a now missing category we skip it
|
||||
add_test(function() {
|
||||
open_manager("addons://list/extension", function(aWindow) {
|
||||
gManagerWindow = aWindow;
|
||||
gCategoryUtilities = new CategoryUtilities(gManagerWindow);
|
||||
|
||||
AddonManagerPrivate.registerProvider(gProvider, gTypes);
|
||||
|
||||
ok(gCategoryUtilities.get("type1"), "Type 1 should be present");
|
||||
ok(gCategoryUtilities.isTypeVisible("type1"), "Type 1 should be visible");
|
||||
|
||||
gCategoryUtilities.openType("type1", function() {
|
||||
gCategoryUtilities.openType("plugin", function() {
|
||||
go_back(gManagerWindow);
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
go_back(gManagerWindow);
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
is(gCategoryUtilities.selectedCategory, "extension", "Should be back to the extension view");
|
||||
|
||||
AddonManagerPrivate.unregisterProvider(gProvider);
|
||||
|
||||
ok(!gCategoryUtilities.get("type1", true), "Type 1 should not be present");
|
||||
|
||||
go_forward(gManagerWindow);
|
||||
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
is(gCategoryUtilities.selectedCategory, "plugin", "Should be back to the plugin view");
|
||||
check_state(gManagerWindow, true, false);
|
||||
|
||||
close_manager(gManagerWindow, run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Test that when going back to a now missing category and we can't go back any
|
||||
// any further then we just display the default view
|
||||
add_test(function() {
|
||||
AddonManagerPrivate.registerProvider(gProvider, gTypes);
|
||||
|
||||
open_manager("addons://list/type1", function(aWindow) {
|
||||
gManagerWindow = aWindow;
|
||||
gCategoryUtilities = new CategoryUtilities(gManagerWindow);
|
||||
is(gCategoryUtilities.selectedCategory, "type1", "Should be at the custom view");
|
||||
|
||||
ok(gCategoryUtilities.get("type1"), "Type 1 should be present");
|
||||
ok(gCategoryUtilities.isTypeVisible("type1"), "Type 1 should be visible");
|
||||
|
||||
gCategoryUtilities.openType("extension", function() {
|
||||
AddonManagerPrivate.unregisterProvider(gProvider);
|
||||
|
||||
ok(!gCategoryUtilities.get("type1", true), "Type 1 should not be present");
|
||||
|
||||
go_back(gManagerWindow);
|
||||
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
is(gCategoryUtilities.selectedCategory, "discover", "Should be at the default view");
|
||||
check_state(gManagerWindow, false, true);
|
||||
|
||||
close_manager(gManagerWindow, run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Test that when going forward to a now missing category and we can't go
|
||||
// forward any further then we just display the default view
|
||||
add_test(function() {
|
||||
AddonManagerPrivate.registerProvider(gProvider, gTypes);
|
||||
|
||||
open_manager("addons://list/extension", function(aWindow) {
|
||||
gManagerWindow = aWindow;
|
||||
gCategoryUtilities = new CategoryUtilities(gManagerWindow);
|
||||
|
||||
ok(gCategoryUtilities.get("type1"), "Type 1 should be present");
|
||||
ok(gCategoryUtilities.isTypeVisible("type1"), "Type 1 should be visible");
|
||||
|
||||
gCategoryUtilities.openType("type1", function() {
|
||||
go_back(gManagerWindow);
|
||||
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
is(gCategoryUtilities.selectedCategory, "extension", "Should be at the extension view");
|
||||
|
||||
AddonManagerPrivate.unregisterProvider(gProvider);
|
||||
|
||||
ok(!gCategoryUtilities.get("type1", true), "Type 1 should not be present");
|
||||
|
||||
go_forward(gManagerWindow);
|
||||
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
is(gCategoryUtilities.selectedCategory, "discover", "Should be at the default view");
|
||||
check_state(gManagerWindow, true, false);
|
||||
|
||||
close_manager(gManagerWindow, run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Test that when going back we skip multiple missing categories
|
||||
add_test(function() {
|
||||
open_manager("addons://list/extension", function(aWindow) {
|
||||
gManagerWindow = aWindow;
|
||||
gCategoryUtilities = new CategoryUtilities(gManagerWindow);
|
||||
|
||||
AddonManagerPrivate.registerProvider(gProvider, gTypes);
|
||||
|
||||
ok(gCategoryUtilities.get("type1"), "Type 1 should be present");
|
||||
ok(gCategoryUtilities.isTypeVisible("type1"), "Type 1 should be visible");
|
||||
|
||||
gCategoryUtilities.openType("type1", function() {
|
||||
gCategoryUtilities.openType("type3", function() {
|
||||
gCategoryUtilities.openType("plugin", function() {
|
||||
AddonManagerPrivate.unregisterProvider(gProvider);
|
||||
|
||||
ok(!gCategoryUtilities.get("type1", true), "Type 1 should not be present");
|
||||
|
||||
go_back(gManagerWindow);
|
||||
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
is(gCategoryUtilities.selectedCategory, "extension", "Should be back to the first view");
|
||||
check_state(gManagerWindow, false, true);
|
||||
|
||||
close_manager(gManagerWindow, run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Test that when going forward we skip multiple missing categories
|
||||
add_test(function() {
|
||||
open_manager("addons://list/extension", function(aWindow) {
|
||||
gManagerWindow = aWindow;
|
||||
gCategoryUtilities = new CategoryUtilities(gManagerWindow);
|
||||
|
||||
AddonManagerPrivate.registerProvider(gProvider, gTypes);
|
||||
|
||||
ok(gCategoryUtilities.get("type1"), "Type 1 should be present");
|
||||
ok(gCategoryUtilities.isTypeVisible("type1"), "Type 1 should be visible");
|
||||
|
||||
gCategoryUtilities.openType("type1", function() {
|
||||
gCategoryUtilities.openType("type3", function() {
|
||||
gCategoryUtilities.openType("plugin", function() {
|
||||
go_back(gManagerWindow);
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
go_back(gManagerWindow);
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
go_back(gManagerWindow);
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
is(gCategoryUtilities.selectedCategory, "extension", "Should be back to the extension view");
|
||||
|
||||
AddonManagerPrivate.unregisterProvider(gProvider);
|
||||
|
||||
ok(!gCategoryUtilities.get("type1", true), "Type 1 should not be present");
|
||||
|
||||
go_forward(gManagerWindow);
|
||||
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
is(gCategoryUtilities.selectedCategory, "plugin", "Should be back to the plugin view");
|
||||
check_state(gManagerWindow, true, false);
|
||||
|
||||
close_manager(gManagerWindow, run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Test that when going back we skip all missing categories and when we can't go
|
||||
// back any any further then we just display the default view
|
||||
add_test(function() {
|
||||
AddonManagerPrivate.registerProvider(gProvider, gTypes);
|
||||
|
||||
open_manager("addons://list/type1", function(aWindow) {
|
||||
gManagerWindow = aWindow;
|
||||
gCategoryUtilities = new CategoryUtilities(gManagerWindow);
|
||||
is(gCategoryUtilities.selectedCategory, "type1", "Should be at the custom view");
|
||||
|
||||
ok(gCategoryUtilities.get("type1"), "Type 1 should be present");
|
||||
ok(gCategoryUtilities.isTypeVisible("type1"), "Type 1 should be visible");
|
||||
|
||||
gCategoryUtilities.openType("type3", function() {
|
||||
gCategoryUtilities.openType("extension", function() {
|
||||
AddonManagerPrivate.unregisterProvider(gProvider);
|
||||
|
||||
ok(!gCategoryUtilities.get("type1", true), "Type 1 should not be present");
|
||||
|
||||
go_back(gManagerWindow);
|
||||
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
is(gCategoryUtilities.selectedCategory, "discover", "Should be at the default view");
|
||||
check_state(gManagerWindow, false, true);
|
||||
|
||||
close_manager(gManagerWindow, run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Test that when going forward we skip all missing categories and when we can't
|
||||
// go back any any further then we just display the default view
|
||||
add_test(function() {
|
||||
AddonManagerPrivate.registerProvider(gProvider, gTypes);
|
||||
|
||||
open_manager("addons://list/extension", function(aWindow) {
|
||||
gManagerWindow = aWindow;
|
||||
gCategoryUtilities = new CategoryUtilities(gManagerWindow);
|
||||
|
||||
ok(gCategoryUtilities.get("type1"), "Type 1 should be present");
|
||||
ok(gCategoryUtilities.isTypeVisible("type1"), "Type 1 should be visible");
|
||||
|
||||
gCategoryUtilities.openType("type1", function() {
|
||||
gCategoryUtilities.openType("type3", function() {
|
||||
go_back(gManagerWindow);
|
||||
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
go_back(gManagerWindow);
|
||||
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
is(gCategoryUtilities.selectedCategory, "extension", "Should be at the extension view");
|
||||
|
||||
AddonManagerPrivate.unregisterProvider(gProvider);
|
||||
|
||||
ok(!gCategoryUtilities.get("type1", true), "Type 1 should not be present");
|
||||
|
||||
go_forward(gManagerWindow);
|
||||
|
||||
wait_for_view_load(gManagerWindow, function() {
|
||||
is(gCategoryUtilities.selectedCategory, "discover", "Should be at the default view");
|
||||
check_state(gManagerWindow, true, false);
|
||||
|
||||
close_manager(gManagerWindow, run_next_test);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -382,7 +382,7 @@ CategoryUtilities.prototype = {
|
|||
return (view.type == "list") ? view.param : view.type;
|
||||
},
|
||||
|
||||
get: function(aCategoryType) {
|
||||
get: function(aCategoryType, aAllowMissing) {
|
||||
isnot(this.window, null, "Should not get category when manager window is not loaded");
|
||||
var categories = this.window.document.getElementById("categories");
|
||||
|
||||
|
@ -396,7 +396,8 @@ CategoryUtilities.prototype = {
|
|||
if (items.length)
|
||||
return items[0];
|
||||
|
||||
ok(false, "Should have found a category with type " + aCategoryType);
|
||||
if (!aAllowMissing)
|
||||
ok(false, "Should have found a category with type " + aCategoryType);
|
||||
return null;
|
||||
},
|
||||
|
||||
|
@ -480,11 +481,17 @@ function addCertOverride(host, bits) {
|
|||
|
||||
/***** Mock Provider *****/
|
||||
|
||||
function MockProvider(aUseAsyncCallbacks) {
|
||||
function MockProvider(aUseAsyncCallbacks, aTypes) {
|
||||
this.addons = [];
|
||||
this.installs = [];
|
||||
this.callbackTimers = [];
|
||||
this.useAsyncCallbacks = (aUseAsyncCallbacks === undefined) ? true : aUseAsyncCallbacks;
|
||||
this.types = (aTypes === undefined) ? [{
|
||||
id: "extension",
|
||||
name: "Extensions",
|
||||
uiPriority: 4000,
|
||||
flags: AddonManager.TYPE_UI_VIEW_LIST
|
||||
}] : aTypes;
|
||||
|
||||
var self = this;
|
||||
registerCleanupFunction(function() {
|
||||
|
@ -502,6 +509,7 @@ MockProvider.prototype = {
|
|||
apiDelay: 10,
|
||||
callbackTimers: null,
|
||||
useAsyncCallbacks: null,
|
||||
types: null,
|
||||
|
||||
/***** Utility functions *****/
|
||||
|
||||
|
@ -509,7 +517,7 @@ MockProvider.prototype = {
|
|||
* Register this provider with the AddonManager
|
||||
*/
|
||||
register: function MP_register() {
|
||||
AddonManagerPrivate.registerProvider(this);
|
||||
AddonManagerPrivate.registerProvider(this, this.types);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// This verifies that custom types can be defined and undefined
|
||||
|
||||
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
|
||||
|
||||
function run_test() {
|
||||
startupManager();
|
||||
|
||||
do_check_false("test" in AddonManager.addonTypes);
|
||||
let types = AddonManager.addonTypes;
|
||||
|
||||
// The dumbest provider possible
|
||||
var provider = {
|
||||
};
|
||||
|
||||
var expectedAdd = "test";
|
||||
var expectedRemove = null;
|
||||
|
||||
AddonManager.addTypeListener({
|
||||
onTypeAdded: function(aType) {
|
||||
do_check_eq(aType.id, expectedAdd);
|
||||
expectedAdd = null;
|
||||
},
|
||||
|
||||
onTypeRemoved: function(aType) {
|
||||
do_check_eq(aType.id, expectedRemove);
|
||||
expectedRemove = null;
|
||||
}
|
||||
});
|
||||
|
||||
AddonManagerPrivate.registerProvider(provider, [{
|
||||
id: "test",
|
||||
name: "Test",
|
||||
uiPriority: 1
|
||||
}, {
|
||||
id: "t$e%st",
|
||||
name: "Test",
|
||||
uiPriority: 1
|
||||
}]);
|
||||
|
||||
do_check_eq(expectedAdd, null);
|
||||
|
||||
do_check_true("test" in types);
|
||||
do_check_eq(types["test"].name, "Test");
|
||||
do_check_false("t$e%st" in types);
|
||||
|
||||
delete types["test"];
|
||||
do_check_true("test" in types);
|
||||
|
||||
types["foo"] = "bar";
|
||||
do_check_false("foo" in types);
|
||||
|
||||
expectedRemove = "test";
|
||||
|
||||
AddonManagerPrivate.unregisterProvider(provider);
|
||||
|
||||
do_check_eq(expectedRemove, null);
|
||||
|
||||
do_check_false("test" in AddonManager.addonTypes);
|
||||
// The cached reference to addonTypes is live
|
||||
do_check_false("test" in types);
|
||||
}
|
|
@ -256,19 +256,19 @@
|
|||
#category-discover > .category-icon {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/category-discover.png");
|
||||
}
|
||||
#category-languages > .category-icon {
|
||||
#category-locale > .category-icon {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/category-languages.png");
|
||||
}
|
||||
#category-searchengines > .category-icon {
|
||||
#category-searchengine > .category-icon {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/category-searchengines.png");
|
||||
}
|
||||
#category-extensions > .category-icon {
|
||||
#category-extension > .category-icon {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/category-extensions.png");
|
||||
}
|
||||
#category-themes > .category-icon {
|
||||
#category-theme > .category-icon {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/category-themes.png");
|
||||
}
|
||||
#category-plugins > .category-icon {
|
||||
#category-plugin > .category-icon {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/category-plugins.png");
|
||||
}
|
||||
#category-availableUpdates > .category-icon {
|
||||
|
|
|
@ -288,19 +288,19 @@
|
|||
#category-discover > .category-icon {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/category-discover.png");
|
||||
}
|
||||
#category-languages > .category-icon {
|
||||
#category-locale > .category-icon {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/category-languages.png");
|
||||
}
|
||||
#category-searchengines > .category-icon {
|
||||
#category-searchengine > .category-icon {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/category-searchengines.png");
|
||||
}
|
||||
#category-extensions > .category-icon {
|
||||
#category-extension > .category-icon {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/category-extensions.png");
|
||||
}
|
||||
#category-themes > .category-icon {
|
||||
#category-theme > .category-icon {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/category-themes.png");
|
||||
}
|
||||
#category-plugins > .category-icon {
|
||||
#category-plugin > .category-icon {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/category-plugins.png");
|
||||
}
|
||||
#category-availableUpdates > .category-icon {
|
||||
|
|
|
@ -346,19 +346,19 @@
|
|||
#category-discover > .category-icon {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/category-discover.png");
|
||||
}
|
||||
#category-languages > .category-icon {
|
||||
#category-locale > .category-icon {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/category-languages.png");
|
||||
}
|
||||
#category-searchengines > .category-icon {
|
||||
#category-searchengine > .category-icon {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/category-searchengines.png");
|
||||
}
|
||||
#category-extensions > .category-icon {
|
||||
#category-extension > .category-icon {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/category-extensions.png");
|
||||
}
|
||||
#category-themes > .category-icon {
|
||||
#category-theme > .category-icon {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/category-themes.png");
|
||||
}
|
||||
#category-plugins > .category-icon {
|
||||
#category-plugin > .category-icon {
|
||||
list-style-image: url("chrome://mozapps/skin/extensions/category-plugins.png");
|
||||
}
|
||||
#category-availableUpdates > .category-icon {
|
||||
|
|
Загрузка…
Ссылка в новой задаче