diff --git a/extensions/spellcheck/hunspell/src/mozHunspell.cpp b/extensions/spellcheck/hunspell/src/mozHunspell.cpp index af09663ac6d..d66f074b533 100644 --- a/extensions/spellcheck/hunspell/src/mozHunspell.cpp +++ b/extensions/spellcheck/hunspell/src/mozHunspell.cpp @@ -128,6 +128,7 @@ mozHunspell::Init() nsCOMPtr obs = mozilla::services::GetObserverService(); if (obs) { obs->AddObserver(this, "profile-do-change", PR_TRUE); + obs->AddObserver(this, "profile-after-change", PR_TRUE); } mHunspellReporter = new NS_MEMORY_REPORTER_NAME(Hunspell); @@ -593,7 +594,8 @@ NS_IMETHODIMP mozHunspell::Observe(nsISupports* aSubj, const char *aTopic, const PRUnichar *aData) { - NS_ASSERTION(!strcmp(aTopic, "profile-do-change"), + NS_ASSERTION(!strcmp(aTopic, "profile-do-change") + || !strcmp(aTopic, "profile-after-change"), "Unexpected observer topic"); LoadDictionaryList(); diff --git a/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.properties b/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.properties index 7882a1d2704..60e0642b5a2 100644 --- a/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.properties +++ b/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.properties @@ -109,3 +109,4 @@ type.extension.name=Extensions type.theme.name=Appearance type.locale.name=Languages type.plugin.name=Plugins +type.dictionary.name=Dictionaries diff --git a/toolkit/mozapps/extensions/AddonRepository.jsm b/toolkit/mozapps/extensions/AddonRepository.jsm index 36a7cf92f95..54c739ea5c0 100644 --- a/toolkit/mozapps/extensions/AddonRepository.jsm +++ b/toolkit/mozapps/extensions/AddonRepository.jsm @@ -63,7 +63,7 @@ const PREF_GETADDONS_GETSEARCHRESULTS = "extensions.getAddons.search.url"; const XMLURI_PARSE_ERROR = "http://www.mozilla.org/newlayout/xml/parsererror.xml"; const API_VERSION = "1.5"; -const DEFAULT_CACHE_TYPES = "extension,theme,locale"; +const DEFAULT_CACHE_TYPES = "extension,theme,locale,dictionary"; const KEY_PROFILEDIR = "ProfD"; const FILE_DATABASE = "addons.sqlite"; @@ -933,6 +933,9 @@ var AddonRepository = { case 2: addon.type = "theme"; break; + case 3: + addon.type = "dictionary"; + break; default: WARN("Unknown type id when parsing addon: " + id); } diff --git a/toolkit/mozapps/extensions/Makefile.in b/toolkit/mozapps/extensions/Makefile.in index e8919ebf76f..67f8e48b719 100644 --- a/toolkit/mozapps/extensions/Makefile.in +++ b/toolkit/mozapps/extensions/Makefile.in @@ -72,6 +72,7 @@ EXTRA_PP_JS_MODULES = \ EXTRA_JS_MODULES = \ LightweightThemeManager.jsm \ + SpellCheckDictionaryBootstrap.js \ $(NULL) ifdef ENABLE_TESTS diff --git a/toolkit/mozapps/extensions/SpellCheckDictionaryBootstrap.js b/toolkit/mozapps/extensions/SpellCheckDictionaryBootstrap.js new file mode 100644 index 00000000000..5dc556217a7 --- /dev/null +++ b/toolkit/mozapps/extensions/SpellCheckDictionaryBootstrap.js @@ -0,0 +1,49 @@ +/* ***** 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 + * Jesper Kristensen . + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * 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 ***** */ + +var hunspell, dir; + +function startup(data) { + hunspell = Components.classes["@mozilla.org/spellchecker/engine;1"] + .getService(Components.interfaces.mozISpellCheckingEngine); + dir = data.installPath.clone(); + dir.append("dictionaries"); + hunspell.addDirectory(dir); +} + +function shutdown() { + hunspell.removeDirectory(dir); +} diff --git a/toolkit/mozapps/extensions/XPIProvider.jsm b/toolkit/mozapps/extensions/XPIProvider.jsm index 01d512e9c33..ae2c7609d2e 100644 --- a/toolkit/mozapps/extensions/XPIProvider.jsm +++ b/toolkit/mozapps/extensions/XPIProvider.jsm @@ -164,7 +164,8 @@ const TYPES = { extension: 2, theme: 4, locale: 8, - multipackage: 32 + multipackage: 32, + dictionary: 64 }; const MSG_JAR_FLUSH = "AddonJarFlush"; @@ -712,6 +713,10 @@ function loadManifestFromRDF(aUri, aStream) { } } else { + // spell check dictionaries never require a restart + if (addon.type == "dictionary") + addon.bootstrap = true; + // Only extensions are allowed to provide an optionsURL, optionsType or aboutURL. For // all other types they are silently ignored addon.optionsURL = null; @@ -1621,7 +1626,8 @@ var XPIProvider = { for (let id in this.bootstrappedAddons) { let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile); file.persistentDescriptor = this.bootstrappedAddons[id].descriptor; - this.callBootstrapMethod(id, this.bootstrappedAddons[id].version, file, + this.callBootstrapMethod(id, this.bootstrappedAddons[id].version, + this.bootstrappedAddons[id].type, file, "startup", BOOTSTRAP_REASONS.APP_STARTUP); } @@ -1635,7 +1641,7 @@ var XPIProvider = { let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile); file.persistentDescriptor = XPIProvider.bootstrappedAddons[id].descriptor; XPIProvider.callBootstrapMethod(id, XPIProvider.bootstrappedAddons[id].version, - file, "shutdown", + XPIProvider.bootstrappedAddons[id].type, file, "shutdown", BOOTSTRAP_REASONS.APP_SHUTDOWN); } Services.obs.removeObserver(this, "quit-application-granted"); @@ -2031,7 +2037,7 @@ var XPIProvider = { BOOTSTRAP_REASONS.ADDON_DOWNGRADE; this.callBootstrapMethod(existingAddonID, oldBootstrap.version, - existingAddon, "uninstall", uninstallReason); + oldBootstrap.type, existingAddon, "uninstall", uninstallReason); this.unloadBootstrapScope(existingAddonID); flushStartupCache(); } @@ -2060,7 +2066,7 @@ var XPIProvider = { if (oldBootstrap) { // Re-install the old add-on this.callBootstrapMethod(existingAddonID, oldBootstrap.version, - existingAddon, "install", + oldBootstrap.type, existingAddon, "install", BOOTSTRAP_REASONS.ADDON_INSTALL); } continue; @@ -2322,7 +2328,7 @@ var XPIProvider = { let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile); file.persistentDescriptor = aAddonState.descriptor; - XPIProvider.callBootstrapMethod(newAddon.id, newAddon.version, file, + XPIProvider.callBootstrapMethod(newAddon.id, newAddon.version, newAddon.type, file, "install", installReason); return false; } @@ -2398,7 +2404,7 @@ var XPIProvider = { // The add-on is bootstrappable so call its install script let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile); file.persistentDescriptor = aAddonState.descriptor; - XPIProvider.callBootstrapMethod(aOldAddon.id, aOldAddon.version, file, + XPIProvider.callBootstrapMethod(aOldAddon.id, aOldAddon.version, aOldAddon.type, file, "install", BOOTSTRAP_REASONS.ADDON_INSTALL); @@ -2476,6 +2482,7 @@ var XPIProvider = { if (aOldAddon.visible && aOldAddon.active && aOldAddon.bootstrap) { XPIProvider.bootstrappedAddons[aOldAddon.id] = { version: aOldAddon.version, + type: aOldAddon.type, descriptor: aAddonState.descriptor }; } @@ -2682,7 +2689,7 @@ var XPIProvider = { oldAddonFile.persistentDescriptor = oldBootstrap.descriptor; XPIProvider.callBootstrapMethod(newAddon.id, oldBootstrap.version, - oldAddonFile, "uninstall", + oldBootstrap.type, oldAddonFile, "uninstall", installReason); XPIProvider.unloadBootstrapScope(newAddon.id); @@ -2698,7 +2705,7 @@ var XPIProvider = { // Visible bootstrapped add-ons need to have their install method called let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile); file.persistentDescriptor = aAddonState.descriptor; - XPIProvider.callBootstrapMethod(newAddon.id, newAddon.version, file, + XPIProvider.callBootstrapMethod(newAddon.id, newAddon.version, newAddon.type, file, "install", installReason); if (!newAddon.active) XPIProvider.unloadBootstrapScope(newAddon.id); @@ -3450,11 +3457,12 @@ var XPIProvider = { * The add-on's version * @return a JavaScript scope */ - loadBootstrapScope: function XPI_loadBootstrapScope(aId, aFile, aVersion) { + loadBootstrapScope: function XPI_loadBootstrapScope(aId, aFile, aVersion, aType) { LOG("Loading bootstrap scope from " + aFile.path); // Mark the add-on as active for the crash reporter before loading this.bootstrappedAddons[aId] = { version: aVersion, + type: aType, descriptor: aFile.persistentDescriptor }; this.addAddonsToCrashReporter(); @@ -3480,7 +3488,12 @@ var XPIProvider = { // As we don't want our caller to control the JS version used for the // bootstrap file, we run loadSubScript within the context of the // sandbox with the latest JS version set explicitly. - this.bootstrapScopes[aId].__SCRIPT_URI_SPEC__ = uri; + if (aType == "dictionary") { + this.bootstrapScopes[aId].__SCRIPT_URI_SPEC__ = + "resource://gre/modules/SpellCheckDictionaryBootstrap.js" + } else { + this.bootstrapScopes[aId].__SCRIPT_URI_SPEC__ = uri; + } Components.utils.evalInSandbox( "Components.classes['@mozilla.org/moz/jssubscript-loader;1'] \ .createInstance(Components.interfaces.mozIJSSubScriptLoader) \ @@ -3515,6 +3528,8 @@ var XPIProvider = { * The ID of the add-on * @param aVersion * The version of the add-on + * @param aType + * The type for the add-on * @param aFile * The nsILocalFile for the add-on * @param aMethod @@ -3522,7 +3537,7 @@ var XPIProvider = { * @param aReason * The reason flag to pass to the bootstrap's startup method */ - callBootstrapMethod: function XPI_callBootstrapMethod(aId, aVersion, aFile, + callBootstrapMethod: function XPI_callBootstrapMethod(aId, aVersion, aType, aFile, aMethod, aReason) { // Never call any bootstrap methods in safe mode if (Services.appinfo.inSafeMode) @@ -3530,7 +3545,7 @@ var XPIProvider = { // Load the scope if it hasn't already been loaded if (!(aId in this.bootstrapScopes)) - this.loadBootstrapScope(aId, aFile, aVersion); + this.loadBootstrapScope(aId, aFile, aVersion, aType); if (!(aMethod in this.bootstrapScopes[aId])) { WARN("Add-on " + aId + " is missing bootstrap method " + aMethod); @@ -3651,7 +3666,7 @@ var XPIProvider = { if (isDisabled) { if (aAddon.bootstrap) { let file = aAddon._installLocation.getLocationForID(aAddon.id); - this.callBootstrapMethod(aAddon.id, aAddon.version, file, "shutdown", + this.callBootstrapMethod(aAddon.id, aAddon.version, aAddon.type, file, "shutdown", BOOTSTRAP_REASONS.ADDON_DISABLE); this.unloadBootstrapScope(aAddon.id); } @@ -3660,7 +3675,7 @@ var XPIProvider = { else { if (aAddon.bootstrap) { let file = aAddon._installLocation.getLocationForID(aAddon.id); - this.callBootstrapMethod(aAddon.id, aAddon.version, file, "startup", + this.callBootstrapMethod(aAddon.id, aAddon.version, aAddon.type, file, "startup", BOOTSTRAP_REASONS.ADDON_ENABLE); } AddonManagerPrivate.callAddonListeners("onEnabled", wrapper); @@ -3728,11 +3743,11 @@ var XPIProvider = { if (aAddon.bootstrap) { let file = aAddon._installLocation.getLocationForID(aAddon.id); - XPIProvider.callBootstrapMethod(aAddon.id, aAddon.version, file, + XPIProvider.callBootstrapMethod(aAddon.id, aAddon.version, aAddon.type, file, "install", BOOTSTRAP_REASONS.ADDON_INSTALL); if (aAddon.active) { - XPIProvider.callBootstrapMethod(aAddon.id, aAddon.version, file, + XPIProvider.callBootstrapMethod(aAddon.id, aAddon.version, aAddon.type, file, "startup", BOOTSTRAP_REASONS.ADDON_INSTALL); } else { @@ -3762,11 +3777,13 @@ var XPIProvider = { if (aAddon.bootstrap) { let file = aAddon._installLocation.getLocationForID(aAddon.id); if (aAddon.active) { - this.callBootstrapMethod(aAddon.id, aAddon.version, file, "shutdown", + this.callBootstrapMethod(aAddon.id, aAddon.version, aAddon.type, file, + "shutdown", BOOTSTRAP_REASONS.ADDON_UNINSTALL); } - this.callBootstrapMethod(aAddon.id, aAddon.version, file, "uninstall", + this.callBootstrapMethod(aAddon.id, aAddon.version, aAddon.type, file, + "uninstall", BOOTSTRAP_REASONS.ADDON_UNINSTALL); this.unloadBootstrapScope(aAddon.id); flushStartupCache(); @@ -6353,12 +6370,14 @@ AddonInstall.prototype = { if (this.existingAddon.active) { XPIProvider.callBootstrapMethod(this.existingAddon.id, this.existingAddon.version, - file, "shutdown", reason); + this.existingAddon.type, file, + "shutdown", reason); } XPIProvider.callBootstrapMethod(this.existingAddon.id, this.existingAddon.version, - file, "uninstall", reason); + this.existingAddon.type, file, + "uninstall", reason); XPIProvider.unloadBootstrapScope(this.existingAddon.id); flushStartupCache(); } @@ -6397,10 +6416,12 @@ AddonInstall.prototype = { self.addon = a; if (self.addon.bootstrap) { XPIProvider.callBootstrapMethod(self.addon.id, self.addon.version, - file, "install", reason); + self.addon.type, file, "install", + reason); if (self.addon.active) { XPIProvider.callBootstrapMethod(self.addon.id, self.addon.version, - file, "startup", reason); + self.addon.type, file, "startup", + reason); } else { XPIProvider.unloadBootstrapScope(self.addon.id); @@ -7966,8 +7987,12 @@ AddonManagerPrivate.registerProvider(XPIProvider, [ new AddonManagerPrivate.AddonType("theme", URI_EXTENSION_STRINGS, STRING_TYPE_NAME, AddonManager.VIEW_TYPE_LIST, 5000), + new AddonManagerPrivate.AddonType("dictionary", URI_EXTENSION_STRINGS, + STRING_TYPE_NAME, + AddonManager.VIEW_TYPE_LIST, 7000, + AddonManager.TYPE_UI_HIDE_EMPTY), new AddonManagerPrivate.AddonType("locale", URI_EXTENSION_STRINGS, STRING_TYPE_NAME, - AddonManager.VIEW_TYPE_LIST, 2000, + AddonManager.VIEW_TYPE_LIST, 8000, AddonManager.TYPE_UI_HIDE_EMPTY) ]); diff --git a/toolkit/mozapps/extensions/nsBlocklistService.js b/toolkit/mozapps/extensions/nsBlocklistService.js index 23cd11a75a5..d752b9c4264 100644 --- a/toolkit/mozapps/extensions/nsBlocklistService.js +++ b/toolkit/mozapps/extensions/nsBlocklistService.js @@ -907,7 +907,7 @@ Blocklist.prototype = { var addonList = []; var self = this; - AddonManager.getAddonsByTypes(["extension", "theme", "locale"], function(addons) { + AddonManager.getAddonsByTypes(["extension", "theme", "locale", "dictionary"], function(addons) { for (let i = 0; i < addons.length; i++) { let oldState = Ci.nsIBlocklistService.STATE_NOTBLOCKED; diff --git a/toolkit/mozapps/extensions/test/addons/test_dictionary/dictionaries/ab-CD.dic b/toolkit/mozapps/extensions/test/addons/test_dictionary/dictionaries/ab-CD.dic new file mode 100644 index 00000000000..3feac546d42 --- /dev/null +++ b/toolkit/mozapps/extensions/test/addons/test_dictionary/dictionaries/ab-CD.dic @@ -0,0 +1,2 @@ +1 +test1 diff --git a/toolkit/mozapps/extensions/test/addons/test_dictionary/install.rdf b/toolkit/mozapps/extensions/test/addons/test_dictionary/install.rdf new file mode 100644 index 00000000000..9e66ab237e4 --- /dev/null +++ b/toolkit/mozapps/extensions/test/addons/test_dictionary/install.rdf @@ -0,0 +1,25 @@ + + + + + + ab-CD@dictionaries.addons.mozilla.org + 1.0 + 64 + true + + + Test Dictionary + Test Description + + + + xpcshell@tests.mozilla.org + 1 + 1 + + + + + diff --git a/toolkit/mozapps/extensions/test/addons/test_dictionary_2/dictionaries/ab-CD.dic b/toolkit/mozapps/extensions/test/addons/test_dictionary_2/dictionaries/ab-CD.dic new file mode 100644 index 00000000000..b35b9c1a6af --- /dev/null +++ b/toolkit/mozapps/extensions/test/addons/test_dictionary_2/dictionaries/ab-CD.dic @@ -0,0 +1,2 @@ +1 +test2 diff --git a/toolkit/mozapps/extensions/test/addons/test_dictionary_2/install.rdf b/toolkit/mozapps/extensions/test/addons/test_dictionary_2/install.rdf new file mode 100644 index 00000000000..a74a114fddd --- /dev/null +++ b/toolkit/mozapps/extensions/test/addons/test_dictionary_2/install.rdf @@ -0,0 +1,24 @@ + + + + + + ab-CD@dictionaries.addons.mozilla.org + 2.0 + true + + + Test Dictionary + Test Description + + + + xpcshell@tests.mozilla.org + 1 + 1 + + + + + diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_dictionary.js b/toolkit/mozapps/extensions/test/xpcshell/test_dictionary.js new file mode 100644 index 00000000000..d08c06d7a86 --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpcshell/test_dictionary.js @@ -0,0 +1,628 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// This verifies that bootstrappable add-ons can be used without restarts. +Components.utils.import("resource://gre/modules/Services.jsm"); + +// Enable loading extensions from the user scopes +Services.prefs.setIntPref("extensions.enabledScopes", + AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_USER); + +createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2"); + +const profileDir = gProfD.clone(); +profileDir.append("extensions"); +const userExtDir = gProfD.clone(); +userExtDir.append("extensions2"); +userExtDir.append(gAppInfo.ID); +registerDirectory("XREUSysExt", userExtDir.parent); + +do_load_httpd_js(); +var testserver; + +/** + * This object is both a factory and an mozISpellCheckingEngine implementation (so, it + * is de-facto a service). It's also an interface requestor that gives out + * itself when asked for mozISpellCheckingEngine. + */ +var HunspellEngine = { + dictionaryDirs: [], + + QueryInterface: function hunspell_qi(iid) { + if (iid.equals(Components.interfaces.nsISupports) || + iid.equals(Components.interfaces.nsIFactory) || + iid.equals(Components.interfaces.mozISpellCheckingEngine)) + return this; + throw Components.results.NS_ERROR_NO_INTERFACE; + }, + createInstance: function hunspell_ci(outer, iid) { + if (outer) + throw Components.results.NS_ERROR_NO_AGGREGATION; + return this.QueryInterface(iid); + }, + lockFactory: function hunspell_lockf(lock) { + throw Components.results.NS_ERROR_NOT_IMPLEMENTED; + }, + + addDirectory: function hunspell_addDirectory(dir) { + this.dictionaryDirs.push(dir); + }, + + removeDirectory: function hunspell_addDirectory(dir) { + this.dictionaryDirs.splice(this.dictionaryDirs.indexOf(dir), 1); + }, + + getInterface: function hunspell_gi(iid) { + if (iid.equals(Components.interfaces.mozISpellCheckingEngine)) + return this; + throw Components.results.NS_ERROR_NO_INTERFACE; + }, + + contractID: "@mozilla.org/spellchecker/engine;1", + classID: Components.ID("{6f3c63bc-a4fd-449b-9a58-a2d9bd972cce}"), + + activate: function hunspell_activate() { + this.origClassID = Components.manager.nsIComponentRegistrar + .contractIDToCID(this.contractID); + this.origFactory = Components.manager + .getClassObject(Components.classes[this.contractID], + Components.interfaces.nsIFactory); + + Components.manager.nsIComponentRegistrar + .unregisterFactory(this.origClassID, this.origFactory); + Components.manager.nsIComponentRegistrar.registerFactory(this.classID, + "Test hunspell", this.contractID, this); + }, + + deactivate: function hunspell_deactivate() { + Components.manager.nsIComponentRegistrar.unregisterFactory(this.classID, this); + Components.manager.nsIComponentRegistrar.registerFactory(this.origClassID, + "Hunspell", this.contractID, this.origFactory); + }, + + isDictionaryEnabled: function hunspell_isDictionaryEnabled(name) { + return this.dictionaryDirs.some(function(dir) { + var dic = dir.clone(); + dic.append(name); + return dic.exists(); + }); + } +}; + +function run_test() { + do_test_pending(); + + // Create and configure the HTTP server. + testserver = new nsHttpServer(); + testserver.registerDirectory("/addons/", do_get_file("addons")); + testserver.start(4444); + + startupManager(); + + run_test_1(); +} + +// Tests that installing doesn't require a restart +function run_test_1() { + prepare_test({ }, [ + "onNewInstall" + ]); + + HunspellEngine.activate(); + + AddonManager.getInstallForFile(do_get_addon("test_dictionary"), function(install) { + ensure_test_completed(); + + do_check_neq(install, null); + do_check_eq(install.type, "dictionary"); + do_check_eq(install.version, "1.0"); + do_check_eq(install.name, "Test Dictionary"); + do_check_eq(install.state, AddonManager.STATE_DOWNLOADED); + do_check_true(install.addon.hasResource("install.rdf")); + do_check_false(install.addon.hasResource("bootstrap.js")); + do_check_eq(install.addon.operationsRequiringRestart & + AddonManager.OP_NEEDS_RESTART_INSTALL, 0); + do_check_not_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0"); + + let addon = install.addon; + prepare_test({ + "ab-CD@dictionaries.addons.mozilla.org": [ + ["onInstalling", false], + "onInstalled" + ] + }, [ + "onInstallStarted", + "onInstallEnded", + ], function() { + do_check_true(addon.hasResource("install.rdf")); + check_test_1(); + }); + install.install(); + }); +} + +function check_test_1() { + AddonManager.getAllInstalls(function(installs) { + // There should be no active installs now since the install completed and + // doesn't require a restart. + do_check_eq(installs.length, 0); + + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) { + do_check_neq(b1, null); + do_check_eq(b1.version, "1.0"); + do_check_false(b1.appDisabled); + do_check_false(b1.userDisabled); + do_check_true(b1.isActive); + do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic")); + do_check_true(b1.hasResource("install.rdf")); + do_check_false(b1.hasResource("bootstrap.js")); + do_check_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0"); + + let dir = do_get_addon_root_uri(profileDir, "ab-CD@dictionaries.addons.mozilla.org"); + + AddonManager.getAddonsWithOperationsByTypes(null, function(list) { + do_check_eq(list.length, 0); + + run_test_2(); + }); + }); + }); +} + +// Tests that disabling doesn't require a restart +function run_test_2() { + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) { + prepare_test({ + "ab-CD@dictionaries.addons.mozilla.org": [ + ["onDisabling", false], + "onDisabled" + ] + }); + + do_check_eq(b1.operationsRequiringRestart & + AddonManager.OP_NEEDS_RESTART_DISABLE, 0); + b1.userDisabled = true; + ensure_test_completed(); + + do_check_neq(b1, null); + do_check_eq(b1.version, "1.0"); + do_check_false(b1.appDisabled); + do_check_true(b1.userDisabled); + do_check_false(b1.isActive); + do_check_false(HunspellEngine.isDictionaryEnabled("ab-CD.dic")); + do_check_not_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0"); + + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(newb1) { + do_check_neq(newb1, null); + do_check_eq(newb1.version, "1.0"); + do_check_false(newb1.appDisabled); + do_check_true(newb1.userDisabled); + do_check_false(newb1.isActive); + + run_test_3(); + }); + }); +} + +// Test that restarting doesn't accidentally re-enable +function run_test_3() { + shutdownManager(); + do_check_false(HunspellEngine.isDictionaryEnabled("ab-CD.dic")); + startupManager(false); + do_check_false(HunspellEngine.isDictionaryEnabled("ab-CD.dic")); + do_check_not_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0"); + + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) { + do_check_neq(b1, null); + do_check_eq(b1.version, "1.0"); + do_check_false(b1.appDisabled); + do_check_true(b1.userDisabled); + do_check_false(b1.isActive); + + run_test_4(); + }); +} + +// Tests that enabling doesn't require a restart +function run_test_4() { + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) { + prepare_test({ + "ab-CD@dictionaries.addons.mozilla.org": [ + ["onEnabling", false], + "onEnabled" + ] + }); + + do_check_eq(b1.operationsRequiringRestart & + AddonManager.OP_NEEDS_RESTART_ENABLE, 0); + b1.userDisabled = false; + ensure_test_completed(); + + do_check_neq(b1, null); + do_check_eq(b1.version, "1.0"); + do_check_false(b1.appDisabled); + do_check_false(b1.userDisabled); + do_check_true(b1.isActive); + do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic")); + do_check_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0"); + + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(newb1) { + do_check_neq(newb1, null); + do_check_eq(newb1.version, "1.0"); + do_check_false(newb1.appDisabled); + do_check_false(newb1.userDisabled); + do_check_true(newb1.isActive); + + run_test_5(); + }); + }); +} + +// Tests that a restart shuts down and restarts the add-on +function run_test_5() { + shutdownManager(); + do_check_false(HunspellEngine.isDictionaryEnabled("ab-CD.dic")); + do_check_not_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0"); + startupManager(false); + do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic")); + do_check_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0"); + + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) { + do_check_neq(b1, null); + do_check_eq(b1.version, "1.0"); + do_check_false(b1.appDisabled); + do_check_false(b1.userDisabled); + do_check_true(b1.isActive); + do_check_false(isExtensionInAddonsList(profileDir, b1.id)); + + run_test_7(); + }); +} + +// Tests that uninstalling doesn't require a restart +function run_test_7() { + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) { + prepare_test({ + "ab-CD@dictionaries.addons.mozilla.org": [ + ["onUninstalling", false], + "onUninstalled" + ] + }); + + do_check_eq(b1.operationsRequiringRestart & + AddonManager.OP_NEEDS_RESTART_UNINSTALL, 0); + b1.uninstall(); + + check_test_7(); + }); +} + +function check_test_7() { + ensure_test_completed(); + do_check_false(HunspellEngine.isDictionaryEnabled("ab-CD.dic")); + do_check_not_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0"); + + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) { + do_check_eq(b1, null); + + restartManager(); + + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(newb1) { + do_check_eq(newb1, null); + + run_test_8(); + }); + }); +} + +// Test that a bootstrapped extension dropped into the profile loads properly +// on startup and doesn't cause an EM restart +function run_test_8() { + shutdownManager(); + + let dir = profileDir.clone(); + dir.append("ab-CD@dictionaries.addons.mozilla.org"); + dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755); + let zip = AM_Cc["@mozilla.org/libjar/zip-reader;1"]. + createInstance(AM_Ci.nsIZipReader); + zip.open(do_get_addon("test_dictionary")); + dir.append("install.rdf"); + zip.extract("install.rdf", dir); + dir = dir.parent; + dir.append("dictionaries"); + dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755); + dir.append("ab-CD.dic"); + zip.extract("dictionaries/ab-CD.dic", dir); + zip.close(); + + startupManager(false); + + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) { + do_check_neq(b1, null); + do_check_eq(b1.version, "1.0"); + do_check_false(b1.appDisabled); + do_check_false(b1.userDisabled); + do_check_true(b1.isActive); + do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic")); + do_check_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0"); + + run_test_9(); + }); +} + +// Test that items detected as removed during startup get removed properly +function run_test_9() { + shutdownManager(); + + let dir = profileDir.clone(); + dir.append("ab-CD@dictionaries.addons.mozilla.org"); + dir.remove(true); + startupManager(false); + + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) { + do_check_eq(b1, null); + do_check_not_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0"); + + run_test_12(); + }); +} + + +// Tests that bootstrapped extensions are correctly loaded even if the app is +// upgraded at the same time +function run_test_12() { + shutdownManager(); + + let dir = profileDir.clone(); + dir.append("ab-CD@dictionaries.addons.mozilla.org"); + dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755); + let zip = AM_Cc["@mozilla.org/libjar/zip-reader;1"]. + createInstance(AM_Ci.nsIZipReader); + zip.open(do_get_addon("test_dictionary")); + dir.append("install.rdf"); + zip.extract("install.rdf", dir); + dir = dir.parent; + dir.append("dictionaries"); + dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755); + dir.append("ab-CD.dic"); + zip.extract("dictionaries/ab-CD.dic", dir); + zip.close(); + + startupManager(true); + + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) { + do_check_neq(b1, null); + do_check_eq(b1.version, "1.0"); + do_check_false(b1.appDisabled); + do_check_false(b1.userDisabled); + do_check_true(b1.isActive); + do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic")); + do_check_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0"); + + b1.uninstall(); + restartManager(); + + run_test_16(); + }); +} + + +// Tests that bootstrapped extensions don't get loaded when in safe mode +function run_test_16() { + installAllFiles([do_get_addon("test_dictionary")], function() { + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) { + // Should have installed and started + do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic")); + + shutdownManager(); + + // Should have stopped + do_check_false(HunspellEngine.isDictionaryEnabled("ab-CD.dic")); + + gAppInfo.inSafeMode = true; + startupManager(false); + + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) { + // Should still be stopped + do_check_false(HunspellEngine.isDictionaryEnabled("ab-CD.dic")); + do_check_false(b1.isActive); + + shutdownManager(); + gAppInfo.inSafeMode = false; + startupManager(false); + + // Should have started + do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic")); + + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) { + b1.uninstall(); + + run_test_17(); + }); + }); + }); + }); +} + +// Check that a bootstrapped extension in a non-profile location is loaded +function run_test_17() { + shutdownManager(); + + let dir = userExtDir.clone(); + dir.append("ab-CD@dictionaries.addons.mozilla.org"); + dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755); + let zip = AM_Cc["@mozilla.org/libjar/zip-reader;1"]. + createInstance(AM_Ci.nsIZipReader); + zip.open(do_get_addon("test_dictionary")); + dir.append("install.rdf"); + zip.extract("install.rdf", dir); + dir = dir.parent; + dir.append("dictionaries"); + dir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755); + dir.append("ab-CD.dic"); + zip.extract("dictionaries/ab-CD.dic", dir); + zip.close(); + + startupManager(); + + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) { + // Should have installed and started + do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic")); + do_check_neq(b1, null); + do_check_eq(b1.version, "1.0"); + do_check_true(b1.isActive); + + // From run_test_21 + dir = userExtDir.clone(); + dir.append("ab-CD@dictionaries.addons.mozilla.org"); + dir.remove(true); + + restartManager(); + + run_test_23(); + }); +} + +// Tests that installing from a URL doesn't require a restart +function run_test_23() { + prepare_test({ }, [ + "onNewInstall" + ]); + + let url = "http://localhost:4444/addons/test_dictionary.xpi"; + AddonManager.getInstallForURL(url, function(install) { + ensure_test_completed(); + + do_check_neq(install, null); + + prepare_test({ }, [ + "onDownloadStarted", + "onDownloadEnded" + ], function() { + do_check_eq(install.type, "dictionary"); + do_check_eq(install.version, "1.0"); + do_check_eq(install.name, "Test Dictionary"); + do_check_eq(install.state, AddonManager.STATE_DOWNLOADED); + do_check_true(install.addon.hasResource("install.rdf")); + do_check_false(install.addon.hasResource("bootstrap.js")); + do_check_eq(install.addon.operationsRequiringRestart & + AddonManager.OP_NEEDS_RESTART_INSTALL, 0); + do_check_not_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0"); + + let addon = install.addon; + prepare_test({ + "ab-CD@dictionaries.addons.mozilla.org": [ + ["onInstalling", false], + "onInstalled" + ] + }, [ + "onInstallStarted", + "onInstallEnded", + ], function() { + do_check_true(addon.hasResource("install.rdf")); + check_test_23(); + }); + }); + install.install(); + }, "application/x-xpinstall"); +} + +function check_test_23() { + AddonManager.getAllInstalls(function(installs) { + // There should be no active installs now since the install completed and + // doesn't require a restart. + do_check_eq(installs.length, 0); + + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) { + do_check_neq(b1, null); + do_check_eq(b1.version, "1.0"); + do_check_false(b1.appDisabled); + do_check_false(b1.userDisabled); + do_check_true(b1.isActive); + do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic")); + do_check_true(b1.hasResource("install.rdf")); + do_check_false(b1.hasResource("bootstrap.js")); + do_check_in_crash_annotation("ab-CD@dictionaries.addons.mozilla.org", "1.0"); + + let dir = do_get_addon_root_uri(profileDir, "ab-CD@dictionaries.addons.mozilla.org"); + + AddonManager.getAddonsWithOperationsByTypes(null, function(list) { + do_check_eq(list.length, 0); + + restartManager(); + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) { + b1.uninstall(); + restartManager(); + + testserver.stop(run_test_25); + }); + }); + }); + }); +} + +// Tests that updating from a bootstrappable add-on to a normal add-on calls +// the uninstall method +function run_test_25() { + installAllFiles([do_get_addon("test_dictionary")], function() { + do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic")); + + installAllFiles([do_get_addon("test_dictionary_2")], function() { + // Needs a restart to complete this so the old version stays running + do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic")); + + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) { + do_check_neq(b1, null); + do_check_eq(b1.version, "1.0"); + do_check_true(b1.isActive); + do_check_true(hasFlag(b1.pendingOperations, AddonManager.PENDING_UPGRADE)); + + restartManager(); + + do_check_false(HunspellEngine.isDictionaryEnabled("ab-CD.dic")); + + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) { + do_check_neq(b1, null); + do_check_eq(b1.version, "2.0"); + do_check_true(b1.isActive); + do_check_eq(b1.pendingOperations, AddonManager.PENDING_NONE); + + run_test_26(); + }); + }); + }); + }); +} + +// Tests that updating from a normal add-on to a bootstrappable add-on calls +// the install method +function run_test_26() { + installAllFiles([do_get_addon("test_dictionary")], function() { + // Needs a restart to complete this + do_check_false(HunspellEngine.isDictionaryEnabled("ab-CD.dic")); + + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) { + do_check_neq(b1, null); + do_check_eq(b1.version, "2.0"); + do_check_true(b1.isActive); + do_check_true(hasFlag(b1.pendingOperations, AddonManager.PENDING_UPGRADE)); + + restartManager(); + + do_check_true(HunspellEngine.isDictionaryEnabled("ab-CD.dic")); + + AddonManager.getAddonByID("ab-CD@dictionaries.addons.mozilla.org", function(b1) { + do_check_neq(b1, null); + do_check_eq(b1.version, "1.0"); + do_check_true(b1.isActive); + do_check_eq(b1.pendingOperations, AddonManager.PENDING_NONE); + + HunspellEngine.deactivate(); + + do_test_finished(); + }); + }); + }); +} + diff --git a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini index 335f5628bc9..c3b57d04644 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini +++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini @@ -120,6 +120,7 @@ fail-if = os == "android" [test_cacheflush.js] [test_checkcompatibility.js] [test_corrupt.js] +[test_dictionary.js] [test_disable.js] [test_distribution.js] [test_dss.js] diff --git a/toolkit/themes/gnomestripe/mozapps/extensions/category-dictionaries.png b/toolkit/themes/gnomestripe/mozapps/extensions/category-dictionaries.png new file mode 100644 index 00000000000..a1e0d53596d Binary files /dev/null and b/toolkit/themes/gnomestripe/mozapps/extensions/category-dictionaries.png differ diff --git a/toolkit/themes/gnomestripe/mozapps/extensions/dictionaryGeneric-16.png b/toolkit/themes/gnomestripe/mozapps/extensions/dictionaryGeneric-16.png new file mode 100644 index 00000000000..08a0447a470 Binary files /dev/null and b/toolkit/themes/gnomestripe/mozapps/extensions/dictionaryGeneric-16.png differ diff --git a/toolkit/themes/gnomestripe/mozapps/extensions/dictionaryGeneric.png b/toolkit/themes/gnomestripe/mozapps/extensions/dictionaryGeneric.png new file mode 100644 index 00000000000..a1e0d53596d Binary files /dev/null and b/toolkit/themes/gnomestripe/mozapps/extensions/dictionaryGeneric.png differ diff --git a/toolkit/themes/gnomestripe/mozapps/extensions/extensions.css b/toolkit/themes/gnomestripe/mozapps/extensions/extensions.css index 0a13c09a190..1a6bc1a8bba 100644 --- a/toolkit/themes/gnomestripe/mozapps/extensions/extensions.css +++ b/toolkit/themes/gnomestripe/mozapps/extensions/extensions.css @@ -253,6 +253,9 @@ #category-plugin > .category-icon { list-style-image: url("chrome://mozapps/skin/extensions/category-plugins.png"); } +#category-dictionary > .category-icon { + list-style-image: url("chrome://mozapps/skin/extensions/category-dictionaries.png"); +} #category-availableUpdates > .category-icon { list-style-image: url("chrome://mozapps/skin/extensions/category-available.png"); } @@ -434,6 +437,10 @@ list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.png"); } +.addon-view[type="dictionary"] .icon { + list-style-image: url("chrome://mozapps/skin/extensions/dictionaryGeneric.png"); +} + .name-container { font-size: 150%; margin-bottom: 0; diff --git a/toolkit/themes/gnomestripe/mozapps/extensions/newaddon.css b/toolkit/themes/gnomestripe/mozapps/extensions/newaddon.css index a995683bf63..d85ab597618 100644 --- a/toolkit/themes/gnomestripe/mozapps/extensions/newaddon.css +++ b/toolkit/themes/gnomestripe/mozapps/extensions/newaddon.css @@ -83,6 +83,10 @@ list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.png"); } +.addon-info[type="dictionary"] #icon { + list-style-image: url("chrome://mozapps/skin/plugins/dictionaryGeneric.png"); +} + #name { font-size: 130%; } diff --git a/toolkit/themes/gnomestripe/mozapps/extensions/selectAddons.css b/toolkit/themes/gnomestripe/mozapps/extensions/selectAddons.css index d9666d36e52..213a0ea5eb5 100644 --- a/toolkit/themes/gnomestripe/mozapps/extensions/selectAddons.css +++ b/toolkit/themes/gnomestripe/mozapps/extensions/selectAddons.css @@ -158,6 +158,10 @@ list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric-16.png"); } +.addon-icon[type="dictionary"] { + list-style-image: url("chrome://mozapps/skin/extensions/dictionaryGeneric-16.png"); +} + .action-list { margin-top: 10px; -moz-margin-start: 5em; diff --git a/toolkit/themes/gnomestripe/mozapps/jar.mn b/toolkit/themes/gnomestripe/mozapps/jar.mn index 1ee4badd29b..4d147689b61 100644 --- a/toolkit/themes/gnomestripe/mozapps/jar.mn +++ b/toolkit/themes/gnomestripe/mozapps/jar.mn @@ -11,11 +11,14 @@ toolkit.jar: + skin/classic/mozapps/extensions/category-extensions.png (extensions/category-extensions.png) + skin/classic/mozapps/extensions/category-themes.png (extensions/category-themes.png) + skin/classic/mozapps/extensions/category-plugins.png (extensions/category-plugins.png) ++ skin/classic/mozapps/extensions/category-dictionaries.png (extensions/category-dictionaries.png) + skin/classic/mozapps/extensions/category-recent.png (extensions/category-recent.png) + skin/classic/mozapps/extensions/category-available.png (extensions/category-available.png) + skin/classic/mozapps/extensions/discover-logo.png (extensions/discover-logo.png) + skin/classic/mozapps/extensions/extensionGeneric.png (extensions/extensionGeneric.png) + skin/classic/mozapps/extensions/extensionGeneric-16.png (extensions/extensionGeneric-16.png) ++ skin/classic/mozapps/extensions/dictionaryGeneric.png (extensions/dictionaryGeneric.png) ++ skin/classic/mozapps/extensions/dictionaryGeneric-16.png (extensions/dictionaryGeneric-16.png) + skin/classic/mozapps/extensions/themeGeneric.png (extensions/themeGeneric.png) + skin/classic/mozapps/extensions/themeGeneric-16.png (extensions/themeGeneric-16.png) + skin/classic/mozapps/extensions/localeGeneric.png (extensions/localeGeneric.png) diff --git a/toolkit/themes/pinstripe/mozapps/extensions/about.css b/toolkit/themes/pinstripe/mozapps/extensions/about.css index ad150e174d1..23213dc304e 100644 --- a/toolkit/themes/pinstripe/mozapps/extensions/about.css +++ b/toolkit/themes/pinstripe/mozapps/extensions/about.css @@ -33,6 +33,10 @@ list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.png"); } +#genericAbout[addontype="dictionary"] #extensionIcon { + list-style-image: url("chrome://mozapps/skin/extensions/dictionaryGeneric.png"); +} + #extensionName { font-size: 200%; font-weight: bolder; diff --git a/toolkit/themes/pinstripe/mozapps/extensions/category-dictionaries.png b/toolkit/themes/pinstripe/mozapps/extensions/category-dictionaries.png new file mode 100644 index 00000000000..54ae4f93fc5 Binary files /dev/null and b/toolkit/themes/pinstripe/mozapps/extensions/category-dictionaries.png differ diff --git a/toolkit/themes/pinstripe/mozapps/extensions/dictionaryGeneric-16.png b/toolkit/themes/pinstripe/mozapps/extensions/dictionaryGeneric-16.png new file mode 100644 index 00000000000..4ad1a1a8251 Binary files /dev/null and b/toolkit/themes/pinstripe/mozapps/extensions/dictionaryGeneric-16.png differ diff --git a/toolkit/themes/pinstripe/mozapps/extensions/dictionaryGeneric.png b/toolkit/themes/pinstripe/mozapps/extensions/dictionaryGeneric.png new file mode 100644 index 00000000000..54ae4f93fc5 Binary files /dev/null and b/toolkit/themes/pinstripe/mozapps/extensions/dictionaryGeneric.png differ diff --git a/toolkit/themes/pinstripe/mozapps/extensions/eula.css b/toolkit/themes/pinstripe/mozapps/extensions/eula.css index 5d9293b426d..eb77668a1d1 100644 --- a/toolkit/themes/pinstripe/mozapps/extensions/eula.css +++ b/toolkit/themes/pinstripe/mozapps/extensions/eula.css @@ -17,6 +17,10 @@ list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.png"); } +#eula-dialog[addontype="dictionary"] #icon { + list-style-image: url("chrome://mozapps/skin/extensions/dictionaryGeneric.png"); +} + #heading-container { -moz-box-align: center; } diff --git a/toolkit/themes/pinstripe/mozapps/extensions/extensions.css b/toolkit/themes/pinstripe/mozapps/extensions/extensions.css index 7cbfe7bb92e..a9ecb721f33 100644 --- a/toolkit/themes/pinstripe/mozapps/extensions/extensions.css +++ b/toolkit/themes/pinstripe/mozapps/extensions/extensions.css @@ -286,6 +286,9 @@ #category-plugin > .category-icon { list-style-image: url("chrome://mozapps/skin/extensions/category-plugins.png"); } +#category-dictionary > .category-icon { + list-style-image: url("chrome://mozapps/skin/extensions/category-dictionaries.png"); +} #category-availableUpdates > .category-icon { list-style-image: url("chrome://mozapps/skin/extensions/category-available.png"); } @@ -499,6 +502,10 @@ list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.png"); } +.addon-view[type="dictionary"] .icon { + list-style-image: url("chrome://mozapps/skin/extensions/dictionaryGeneric.png"); +} + .name-container { font-size: 150%; margin-bottom: 0; diff --git a/toolkit/themes/pinstripe/mozapps/extensions/newaddon.css b/toolkit/themes/pinstripe/mozapps/extensions/newaddon.css index 2303b5fcdca..2cfff6b87db 100644 --- a/toolkit/themes/pinstripe/mozapps/extensions/newaddon.css +++ b/toolkit/themes/pinstripe/mozapps/extensions/newaddon.css @@ -85,6 +85,10 @@ list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.png"); } +.addon-info[type="dictionary"] #icon { + list-style-image: url("chrome://mozapps/skin/plugins/dictionaryGeneric.png"); +} + #name { font-size: 130%; } diff --git a/toolkit/themes/pinstripe/mozapps/extensions/selectAddons.css b/toolkit/themes/pinstripe/mozapps/extensions/selectAddons.css index d544dc93ad3..1848b47e340 100644 --- a/toolkit/themes/pinstripe/mozapps/extensions/selectAddons.css +++ b/toolkit/themes/pinstripe/mozapps/extensions/selectAddons.css @@ -157,6 +157,10 @@ list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric-16.png"); } +.addon-icon[type="dictionary"] { + list-style-image: url("chrome://mozapps/skin/extensions/dictionaryGeneric-16.png"); +} + .action-list { margin-top: 10px; -moz-margin-start: 5em; diff --git a/toolkit/themes/pinstripe/mozapps/jar.mn b/toolkit/themes/pinstripe/mozapps/jar.mn index 8534da61490..ea7b50dbfba 100644 --- a/toolkit/themes/pinstripe/mozapps/jar.mn +++ b/toolkit/themes/pinstripe/mozapps/jar.mn @@ -12,6 +12,7 @@ toolkit.jar: skin/classic/mozapps/extensions/category-extensions.png (extensions/category-extensions.png) skin/classic/mozapps/extensions/category-themes.png (extensions/category-themes.png) skin/classic/mozapps/extensions/category-plugins.png (extensions/category-plugins.png) + skin/classic/mozapps/extensions/category-dictionaries.png (extensions/category-dictionaries.png) skin/classic/mozapps/extensions/category-recent.png (extensions/category-recent.png) skin/classic/mozapps/extensions/category-available.png (extensions/category-available.png) skin/classic/mozapps/extensions/discover-logo.png (extensions/discover-logo.png) @@ -19,6 +20,8 @@ toolkit.jar: skin/classic/mozapps/extensions/extensionGeneric-16.png (extensions/extensionGeneric-16.png) skin/classic/mozapps/extensions/themeGeneric.png (extensions/themeGeneric.png) skin/classic/mozapps/extensions/themeGeneric-16.png (extensions/themeGeneric-16.png) + skin/classic/mozapps/extensions/dictionaryGeneric.png (extensions/dictionaryGeneric.png) + skin/classic/mozapps/extensions/dictionaryGeneric-16.png (extensions/dictionaryGeneric-16.png) skin/classic/mozapps/extensions/localeGeneric.png (extensions/localeGeneric.png) skin/classic/mozapps/extensions/rating-won.png (extensions/rating-won.png) skin/classic/mozapps/extensions/rating-not-won.png (extensions/rating-not-won.png) diff --git a/toolkit/themes/pinstripe/mozapps/xpinstall/xpinstallConfirm.css b/toolkit/themes/pinstripe/mozapps/xpinstall/xpinstallConfirm.css index 6ed04be6e0b..d109f5346d7 100644 --- a/toolkit/themes/pinstripe/mozapps/xpinstall/xpinstallConfirm.css +++ b/toolkit/themes/pinstripe/mozapps/xpinstall/xpinstallConfirm.css @@ -80,3 +80,7 @@ installitem[type="locale"] .xpinstallItemIcon { installitem[type="plugin"] .xpinstallItemIcon { list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.png"); } + +installitem[type="dictionary"] .xpinstallItemIcon { + list-style-image: url("chrome://mozapps/skin/extensions/dictionaryGeneric.png"); +} diff --git a/toolkit/themes/winstripe/mozapps/extensions/about.css b/toolkit/themes/winstripe/mozapps/extensions/about.css index fa8e0681c55..42c59adddfb 100644 --- a/toolkit/themes/winstripe/mozapps/extensions/about.css +++ b/toolkit/themes/winstripe/mozapps/extensions/about.css @@ -45,6 +45,10 @@ list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.png"); } +#genericAbout[addontype="dictionary"] #extensionIcon { + list-style-image: url("chrome://mozapps/skin/extensions/dictionaryGeneric.png"); +} + #extensionName { font-size: 200%; font-weight: bolder; diff --git a/toolkit/themes/winstripe/mozapps/extensions/category-dictionaries-aero.png b/toolkit/themes/winstripe/mozapps/extensions/category-dictionaries-aero.png new file mode 100644 index 00000000000..b26bb7100c8 Binary files /dev/null and b/toolkit/themes/winstripe/mozapps/extensions/category-dictionaries-aero.png differ diff --git a/toolkit/themes/winstripe/mozapps/extensions/category-dictionaries.png b/toolkit/themes/winstripe/mozapps/extensions/category-dictionaries.png new file mode 100644 index 00000000000..b26bb7100c8 Binary files /dev/null and b/toolkit/themes/winstripe/mozapps/extensions/category-dictionaries.png differ diff --git a/toolkit/themes/winstripe/mozapps/extensions/dictionaryGeneric-16-aero.png b/toolkit/themes/winstripe/mozapps/extensions/dictionaryGeneric-16-aero.png new file mode 100644 index 00000000000..37e2a5e4ce0 Binary files /dev/null and b/toolkit/themes/winstripe/mozapps/extensions/dictionaryGeneric-16-aero.png differ diff --git a/toolkit/themes/winstripe/mozapps/extensions/dictionaryGeneric-16.png b/toolkit/themes/winstripe/mozapps/extensions/dictionaryGeneric-16.png new file mode 100644 index 00000000000..37e2a5e4ce0 Binary files /dev/null and b/toolkit/themes/winstripe/mozapps/extensions/dictionaryGeneric-16.png differ diff --git a/toolkit/themes/winstripe/mozapps/extensions/dictionaryGeneric-aero.png b/toolkit/themes/winstripe/mozapps/extensions/dictionaryGeneric-aero.png new file mode 100644 index 00000000000..b26bb7100c8 Binary files /dev/null and b/toolkit/themes/winstripe/mozapps/extensions/dictionaryGeneric-aero.png differ diff --git a/toolkit/themes/winstripe/mozapps/extensions/dictionaryGeneric.png b/toolkit/themes/winstripe/mozapps/extensions/dictionaryGeneric.png new file mode 100644 index 00000000000..b26bb7100c8 Binary files /dev/null and b/toolkit/themes/winstripe/mozapps/extensions/dictionaryGeneric.png differ diff --git a/toolkit/themes/winstripe/mozapps/extensions/eula.css b/toolkit/themes/winstripe/mozapps/extensions/eula.css index 5d9293b426d..eb77668a1d1 100644 --- a/toolkit/themes/winstripe/mozapps/extensions/eula.css +++ b/toolkit/themes/winstripe/mozapps/extensions/eula.css @@ -17,6 +17,10 @@ list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.png"); } +#eula-dialog[addontype="dictionary"] #icon { + list-style-image: url("chrome://mozapps/skin/extensions/dictionaryGeneric.png"); +} + #heading-container { -moz-box-align: center; } diff --git a/toolkit/themes/winstripe/mozapps/extensions/extensions.css b/toolkit/themes/winstripe/mozapps/extensions/extensions.css index c9d99c4b322..500b32cb2a4 100644 --- a/toolkit/themes/winstripe/mozapps/extensions/extensions.css +++ b/toolkit/themes/winstripe/mozapps/extensions/extensions.css @@ -298,6 +298,9 @@ #category-plugin > .category-icon { list-style-image: url("chrome://mozapps/skin/extensions/category-plugins.png"); } +#category-dictionary > .category-icon { + list-style-image: url("chrome://mozapps/skin/extensions/category-dictionaries.png"); +} #category-availableUpdates > .category-icon { list-style-image: url("chrome://mozapps/skin/extensions/category-available.png"); } @@ -492,6 +495,10 @@ list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.png"); } +.addon-view[type="dictionary"] .icon { + list-style-image: url("chrome://mozapps/skin/extensions/dictionaryGeneric.png"); +} + .name-container { font-size: 150%; font-weight: bold; diff --git a/toolkit/themes/winstripe/mozapps/extensions/newaddon.css b/toolkit/themes/winstripe/mozapps/extensions/newaddon.css index 6bc2b7cb281..e199653a501 100644 --- a/toolkit/themes/winstripe/mozapps/extensions/newaddon.css +++ b/toolkit/themes/winstripe/mozapps/extensions/newaddon.css @@ -83,6 +83,10 @@ list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.png"); } +.addon-info[type="dictionary"] #icon { + list-style-image: url("chrome://mozapps/skin/plugins/dictionaryGeneric.png"); +} + #name { font-size: 130%; } diff --git a/toolkit/themes/winstripe/mozapps/extensions/selectAddons.css b/toolkit/themes/winstripe/mozapps/extensions/selectAddons.css index cbbbf204227..7c22b38ae9c 100644 --- a/toolkit/themes/winstripe/mozapps/extensions/selectAddons.css +++ b/toolkit/themes/winstripe/mozapps/extensions/selectAddons.css @@ -170,6 +170,10 @@ list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric-16.png"); } +.addon-icon[type="dictionary"] { + list-style-image: url("chrome://mozapps/skin/extensions/dictionaryGeneric-16.png"); +} + .action-list { margin-top: 10px; -moz-margin-start: 5em; diff --git a/toolkit/themes/winstripe/mozapps/jar.mn b/toolkit/themes/winstripe/mozapps/jar.mn index 829975fe212..7ec9bf2022a 100644 --- a/toolkit/themes/winstripe/mozapps/jar.mn +++ b/toolkit/themes/winstripe/mozapps/jar.mn @@ -20,6 +20,7 @@ toolkit.jar: skin/classic/mozapps/extensions/category-extensions.png (extensions/category-extensions.png) skin/classic/mozapps/extensions/category-themes.png (extensions/category-themes.png) skin/classic/mozapps/extensions/category-plugins.png (extensions/category-plugins.png) + skin/classic/mozapps/extensions/category-dictionaries.png (extensions/category-dictionaries.png) skin/classic/mozapps/extensions/category-recent.png (extensions/category-recent.png) skin/classic/mozapps/extensions/category-available.png (extensions/category-available.png) skin/classic/mozapps/extensions/discover-logo.png (extensions/discover-logo.png) @@ -27,6 +28,8 @@ toolkit.jar: skin/classic/mozapps/extensions/extensionGeneric-16.png (extensions/extensionGeneric-16.png) skin/classic/mozapps/extensions/themeGeneric.png (extensions/themeGeneric.png) skin/classic/mozapps/extensions/themeGeneric-16.png (extensions/themeGeneric-16.png) + skin/classic/mozapps/extensions/dictionaryGeneric.png (extensions/dictionaryGeneric.png) + skin/classic/mozapps/extensions/dictionaryGeneric-16.png (extensions/dictionaryGeneric-16.png) skin/classic/mozapps/extensions/localeGeneric.png (extensions/localeGeneric.png) skin/classic/mozapps/extensions/rating-won.png (extensions/rating-won.png) skin/classic/mozapps/extensions/rating-not-won.png (extensions/rating-not-won.png) @@ -97,6 +100,7 @@ toolkit.jar: skin/classic/aero/mozapps/extensions/category-extensions.png (extensions/category-extensions-aero.png) skin/classic/aero/mozapps/extensions/category-themes.png (extensions/category-themes-aero.png) skin/classic/aero/mozapps/extensions/category-plugins.png (extensions/category-plugins-aero.png) + skin/classic/aero/mozapps/extensions/category-dictionaries.png (extensions/category-dictionaries-aero.png) skin/classic/aero/mozapps/extensions/category-recent.png (extensions/category-recent-aero.png) skin/classic/aero/mozapps/extensions/category-available.png (extensions/category-available-aero.png) skin/classic/aero/mozapps/extensions/discover-logo.png (extensions/discover-logo.png) @@ -104,6 +108,8 @@ toolkit.jar: skin/classic/aero/mozapps/extensions/extensionGeneric-16.png (extensions/extensionGeneric-16-aero.png) skin/classic/aero/mozapps/extensions/themeGeneric.png (extensions/themeGeneric-aero.png) skin/classic/aero/mozapps/extensions/themeGeneric-16.png (extensions/themeGeneric-16-aero.png) + skin/classic/aero/mozapps/extensions/dictionaryGeneric.png (extensions/dictionaryGeneric-aero.png) + skin/classic/aero/mozapps/extensions/dictionaryGeneric-16.png (extensions/dictionaryGeneric-16-aero.png) skin/classic/aero/mozapps/extensions/localeGeneric.png (extensions/localeGeneric-aero.png) skin/classic/aero/mozapps/extensions/rating-won.png (extensions/rating-won.png) skin/classic/aero/mozapps/extensions/rating-not-won.png (extensions/rating-not-won.png) diff --git a/toolkit/themes/winstripe/mozapps/xpinstall/xpinstallConfirm.css b/toolkit/themes/winstripe/mozapps/xpinstall/xpinstallConfirm.css index c75e94b1b4f..08a6de6fc69 100644 --- a/toolkit/themes/winstripe/mozapps/xpinstall/xpinstallConfirm.css +++ b/toolkit/themes/winstripe/mozapps/xpinstall/xpinstallConfirm.css @@ -91,3 +91,7 @@ installitem[type="locale"] .xpinstallItemIcon { installitem[type="plugin"] .xpinstallItemIcon { list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.png"); } + +installitem[type="dictionary"] .xpinstallItemIcon { + list-style-image: url("chrome://mozapps/skin/extensions/dictionaryGeneric.png"); +}