Bug 329045 - Firefox 2.0 Extension Manager user interface update (toolkit and xulrunner prefs). r=bsmedberg

This commit is contained in:
rob_strong%exchangecode.com 2006-04-27 03:04:40 +00:00
parent d9cf8d8bf8
commit e70cc1872d
13 changed files with 2866 additions and 1270 deletions

View File

@ -1,62 +1,107 @@
<!ENTITY extensions.title "Extensions">
<!ENTITY addons.title "Add-ons">
<!-- Default window size for the addon manager in pixels -->
<!ENTITY em.width "520">
<!ENTITY em.height "380">
<!ENTITY cmd.info.commandKey "i">
<!ENTITY cmd.options.commandKey ",">
<!ENTITY cmd.close.commandKey "w">
<!-- View labels -->
<!ENTITY extensions.label "Extensions">
<!ENTITY themes.label "Themes">
<!ENTITY locales.label "Languages">
<!ENTITY plugins.label "Plugins">
<!ENTITY update.label "Updates">
<!ENTITY install.label "Installation">
<!-- Command Bar items -->
<!ENTITY cmd.uninstall.label "Uninstall">
<!ENTITY cmd.uninstall.tooltip "Uninstalls the selected Extension">
<!ENTITY cmd.uninstall.accesskey "i">
<!ENTITY cmd.update.label "Find Updates">
<!ENTITY cmd.update.accesskey "U">
<!ENTITY cmd.update.tooltip "Finds Updates to your Extensions">
<!ENTITY cmd.checkUpdatesAll.label "Find Updates">
<!ENTITY cmd.checkUpdatesAll.accesskey "F">
<!ENTITY cmd.checkUpdatesAllAddon.tooltip "Finds Updates to your Add-ons">
<!ENTITY cmd.checkUpdatesAllTheme.tooltip "Finds Updates to your Themes">
<!ENTITY cmd.installFile.label "Install">
<!ENTITY cmd.installFile.accesskey "I">
<!ENTITY cmd.installFileAddon.tooltip "Install an Add-on">
<!ENTITY cmd.installFileTheme.tooltip "Install a Theme">
<!ENTITY cmd.installUpdatesAll.label "Install Updates">
<!ENTITY cmd.installUpdatesAll.accesskey "I">
<!ENTITY cmd.installUpdatesAll.tooltip "Installs the selected updates">
<!ENTITY cmd.restartApp.label "Restart &brandShortName;">
<!ENTITY cmd.restartApp.accesskey "R">
<!ENTITY cmd.restartApp.tooltip "Restarts &brandShortName; to finish the installation">
<!ENTITY cmd.enableAll.label "Enable All">
<!ENTITY cmd.enableAll.accesskey "a">
<!ENTITY cmd.enableAll.tooltip "Enable all displayed Add-ons">
<!ENTITY cmd.disableAll.label "Disable All">
<!ENTITY cmd.disableAll.accesskey "s">
<!ENTITY cmd.disableAll.tooltip "Disable all displayed Add-ons">
<!-- Displayed in the selected Add-on's richlistitem and context menu -->
<!ENTITY cmd.useTheme.label "Use Theme">
<!ENTITY cmd.useTheme.accesskey "T">
<!ENTITY cmd.useTheme.tooltip "Changes &brandShortName;'s Theme">
<!-- the following command bar items are used by thunderbird only -->
<!ENTITY cmd.install.label "Install">
<!ENTITY cmd.install.tooltip "Install an Extension">
<!ENTITY cmd.install.accesskey "n">
<!-- Context Menu Options: Extension -->
<!ENTITY cmd.options.label "Options">
<!ENTITY cmd.options.accesskey "O">
<!ENTITY cmd.options.tooltip "Set Options for the selected Extension">
<!ENTITY cmd.optionsUnix.label "Preferences">
<!ENTITY cmd.optionsUnix.accesskey "r">
<!ENTITY cmd.optionsUnix.tooltip "Edit Preferences for the selected Extension">
<!ENTITY cmd.homepage.label "Visit Home Page">
<!ENTITY cmd.homepage.accesskey "H">
<!ENTITY cmd.about.label "About this Extension">
<!ENTITY cmd.about.accesskey "A">
<!ENTITY cmd.cancelUninstall.label "Cancel Uninstall">
<!ENTITY cmd.cancelUninstall.accesskey "C">
<!ENTITY cmd.updateAddon.label "Find Update">
<!ENTITY cmd.updateAddon.accesskey "F">
<!ENTITY cmd.enable.label "Enable">
<!ENTITY cmd.enable.accesskey "E">
<!ENTITY cmd.enable.tooltip "Enable this Add-on when &brandShortName; is restarted">
<!ENTITY cmd.disable.label "Disable">
<!ENTITY cmd.disable.accesskey "D">
<!ENTITY cmd.moveToTop.label "Move to Top">
<!ENTITY cmd.moveToTop.accesskey "T">
<!ENTITY cmd.moveUp.label "Move Up">
<!ENTITY cmd.moveUp.accesskey "p">
<!ENTITY cmd.moveDn.label "Move Down">
<!ENTITY cmd.moveDn.accesskey "w">
<!ENTITY cmd.disable.tooltip "Disable this Add-on when &brandShortName; is restarted">
<!ENTITY cmd.uninstall.label "Uninstall">
<!ENTITY cmd.uninstall2.accesskey "U">
<!ENTITY cmd.uninstall2.tooltip "Uninstall this Add-on when &brandShortName; is restarted">
<!ENTITY cmd.cancelUninstall.label "Cancel Uninstall">
<!ENTITY cmd.cancelUninstall.accesskey "C">
<!ENTITY cmd.cancelUninstall.tooltip "Cancel the uninstall of this Add-on">
<!ENTITY cmd.installUpdate.label "Install Update">
<!ENTITY cmd.installUpdate.accesskey "I">
<!ENTITY cmd.installUpdate.tooltip "Install an update for this Add-on">
<!-- The selected add-on's cancel action button label -->
<!ENTITY cancel.label "Cancel">
<!ENTITY cancel.accesskey "C">
<!-- Extension Items -->
<!ENTITY options.tooltip "Options">
<!ENTITY optionsUnix.tooltip "Preferences">
<!ENTITY about.tooltip "About">
<!ENTITY homepage.tooltip "Home Page">
<!ENTITY moreInfo.label "More Information">
<!ENTITY installNow.label "Update Now">
<!-- Only displayed in the selected Add-on's context menu -->
<!ENTITY cmd.homepage.label "Visit Home Page">
<!ENTITY cmd.homepage.accesskey "H">
<!ENTITY cmd.about2.label "About this Add-on">
<!ENTITY cmd.about.accesskey "A">
<!ENTITY cmd.checkUpdate.label "Find Update">
<!ENTITY cmd.checkUpdate.accesskey "F">
<!ENTITY cmd.includeUpdate.label "Include Update">
<!ENTITY cmd.includeUpdate.accesskey "n">
<!ENTITY includeUpdate.label "Include this update">
<!ENTITY includeUpdate.accesskey "n">
<!ENTITY includeUpdate.tooltip "Include this Add-on when installing the updates">
<!-- Status Messsages -->
<!ENTITY needsDependencies.label "Requires additional items.">
<!ENTITY blocklisted.label "Disabled for your protection.">
<!ENTITY needsDisable.label "Will be disabled when &brandShortName; is restarted.">
<!ENTITY needsEnable.label "Will be enabled when &brandShortName; is restarted.">
<!ENTITY needsInstall.label "Will be installed when &brandShortName; is restarted.">
<!ENTITY needsUninstall.label "Will be uninstalled when &brandShortName; is restarted.">
<!ENTITY needsUpgrade.label "Will be upgraded when &brandShortName; is restarted.">
<!ENTITY getMoreExtensions.label "Get More Extensions">
<!ENTITY getMoreExtensions.tooltip "Get More Extensions from addons.mozilla.org">
<!ENTITY getMoreThemes.label "Get More Themes">
<!ENTITY getMoreThemes.tooltip "Get More Themes from addons.mozilla.org">
<!ENTITY previewNoThemeSelected.label "No Theme Selected">
<!ENTITY previewNoPreviewImage.label "This Theme does not have a Preview Image">
<!ENTITY moreInfo.label "More Information">
<!ENTITY closeMessage.tooltip "Close this message">
<!ENTITY installSuccess.label "Install completed successfully.">
<!ENTITY installSuccessRestart.label "Restart to complete the installation.">
<!ENTITY installWaiting.label "Waiting...">
<!ENTITY installIncompatibleUpdate.label "Checking compatibility...">
<!ENTITY installFinishing.label "Installing...">

View File

@ -1,11 +1,10 @@
aboutWindowTitle=About %S
aboutWindowCloseButton=Close
aboutWindowVersionString=version %S
aboutExtension=About %S...
updatingMessage=Looking for updates to %S...
updateAvailableMessage=A new version of %S (%S) is available.
updateCompatibilityMessage=A compatibility update has been applied to %S.
updateNoUpdateMessage=No updates were found for %S.
aboutAddon=About %S
updatingMsg=Looking for updates...
updateCompatibilityMsg=A compatibility update has been applied.
updateNoUpdateMsg=No updates were found.
updateErrorMessage=An error occurred while trying to find updates for %S.
updateDisabledMessage=Updates are disabled for %S.
updateAppManagedMessage=Updates to %S are performed when %S is updated.
@ -13,19 +12,11 @@ updateReadOnlyMessage=Update not supported (install location is read only).
updateNotManagedMessage=Update not supported (install location is not managed by %S).
restartBeforeEnableTitle=Enable Extension
restartBeforeDisableTitle=Disable Extension
restartBeforeEnableMessage=%S will be enabled when %S is restarted.
restartBeforeDisableMessage=%S will be disabled when %S is restarted.
restartBeforeDisableBlocklisted=%S will be disabled when %S is restarted for your protection.
restartBeforeUninstallTitle=Uninstall
restartBeforeUninstallMessage=%S will be uninstalled when %S is restarted.
restartBeforeInstallMessage=%S will be installed when %S is restarted.
restartBeforeUpgradeMessage=%S will be upgraded when %S is restarted.
incompatibleUpdateMessage=%S is checking for a compatibility update to %S.
installSuccess=Install completed successfully
installWaiting=Waiting...
installInstalling=Installing...
droppedInWarning=The following items were found in your Extensions folder. Do you want to install them?
disabledBySafeMode=%S is disabled by safe mode.
uninstallButton=Uninstall
disableButton=Disable
@ -34,7 +25,7 @@ restartButton=Restart %S
laterButton=Later
moreInfoText=More information
uninstallTitle=Uninstall %S
uninstallWarningDependMessage=If you uninstall %S, the functionality it offers will no longer be available and the following items that require this extension will be disabled:
uninstallWarningDependMsg=If you uninstall %S, the following items that require this add-on will be disabled:
uninstallWarningMessage=If you uninstall %S, the functionality it offers will no longer be available.
uninstallQueryMessage=Do you want to uninstall %S?
disableTitle=Disable %S
@ -70,6 +61,7 @@ incompatibleMessageNoApp=%S %S could not be installed because it is not compatib
incompatibleOlder=versions 0.8 or older.
incompatibleThemeName=this Theme
incompatibleExtension=Disabled - not compatible with %S %S
incompatibleAddonMsg=Not compatible with %S %S
needsDependenciesDisabled=Disabled - requires additional items to operate.
blocklistedDisabled=Disabled for your protection
@ -101,35 +93,22 @@ missingPackageFilesMessage="%S" could not be installed because it does not conta
errorInstallTitle=Error
errorInstallMsg=%S could not install the file at \n\n%S\n\nbecause: %S
# The following are used by Thunderbird only in order to provide a way to load
# extension and JAR files.
extensionFilter=Extensions (*.xpi)
themesFilter=Themes (*.jar)
installAdoonPickerTitle=Select an add-on to install
installThemePickerTitle=Select a theme to install
installExtensionPickerTitle=Select an extension to install
cmdUninstallTooltipTheme=Uninstalls the selected Theme
cmdUpdateTooltipTheme=Checks for Updates to your Themes
cmdUpdateTooltipAddons=Checks for updates to your Add-ons
cmdInstallTooltipAddons=Install an Add-on
cmdUpdateTooltipTheme=Checks for updates to your Themes
cmdInstallTooltipTheme=Install a Theme
dssSwitchAfterRestart=Restart %S to use.
updateFailedMsg=Update failed for this item.
updateDisabledMsg=Update is disabled for this item.
# Default window size for extensions manager and themes manager
# Size in Pixel (e.g. '460')
extensionsManagerWidth=480
extensionsManagerHeight=300
themesManagerWidth=560
themesManagerHeight=380
# The left column in themes manager
# Size in em (e.g. '20em')
# Note: the unit string 'em' is necessary here!
themesManagerLeftColumn=20em
updatesAvailableMessage1=%S found updates to the following items:
updatesAvailableMessage2=Click Install Now to download and install the updates.
updatesAvailableAccept=Install Now
@ -137,3 +116,18 @@ updatesAvailableCancel=Later
updatesAvailableTitle=Updates Found
itemFormat=%S %S (New version: %S)
finishedUpdateCheck=Finished checking for updates to %S
updateAvailableMsg=Version %S is available.
xpinstallDisabledMsgLocked=Software installation has been disabled by your system administrator.
xpinstallDisabledMsg=Software installation is currently disabled. Click Enable and try again.
safeModeMsg=All add-ons have been disabled by safe mode.
noUpdatesMsg=No updates were found.
offlineUpdateMsg=%S is currently in offline mode and is unable to update Add-ons. Click Go Online and try again.
offlineInstallMsg=%S is currently in offline mode and is unable to install Add-ons. Click Go Online and try again.
closeButtonLabel=Close
closeButtonAccesskey=C
enableButtonLabel=Enable
enableButtonAccesskey=n
goOnlineButtonLabel=Go Online
goOnlineButtonAccesskey=G

View File

@ -1,28 +1,104 @@
extension {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#extension");
-moz-box-orient: vertical;
richlistbox#extensionsView {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addons");
}
extension[state="downloading"] {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#extension-downloading");
richlistitem {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addon");
}
extension[itemType="theme"] {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#theme");
richlistitem[selected="true"] {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addon-selected");
}
extension[itemType="theme"][state="downloading"] {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#theme-downloading");
richlistitem[typeName="update"] {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#update-found");
}
.themePreviewArea {
width: 0px;
richlistitem[updateStatus] {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#update-checking");
}
extension[availableUpdateURL="none"] .extension-install-button-box {
richlistitem[state] {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#install");
}
richlistitem[state="downloading"] {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#install-downloading");
}
richlistitem[state="waiting"] hbox.addon-install-status {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addon-install-waiting");
}
richlistitem[state="incompatibleUpdate"] hbox.addon-install-status {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addon-install-incompatibleUpdate");
}
richlistitem[state="finishing"] hbox.addon-install-status {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addon-install-finishing");
}
richlistitem[state="success"] hbox.addon-install-status {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addon-install-restart");
}
richlistitem[state="success"][opType="none"] hbox.addon-install-status {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addon-install-success");
}
richlistitem[state="failure"] hbox.addon-install-status {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addon-install-fail");
}
vbox.addon-icon {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addon-icon");
}
hbox.addon-name-version {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addon-name-version");
}
/* XXXrstrong due to bug 331689 none is used for some attribute values */
richlistitem[opType="none"] hbox.addon-optype {
display: none;
}
.extension-install-button-box {
display: -moz-box;
richlistitem[opType="none"] hbox.addon-description {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addon-description-crop");
}
richlistitem[opType="needs-uninstall"] hbox.addon-optype,
richlistitem[opType="needs-uninstall"] hbox.addon-description {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addon-needs-uninstall");
}
richlistitem[opType="needs-install"] hbox.addon-optype,
richlistitem[opType="needs-install"] hbox.addon-description {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addon-needs-install");
}
richlistitem[opType="needs-upgrade"] hbox.addon-optype,
richlistitem[opType="needs-upgrade"] hbox.addon-description {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addon-needs-upgrade");
}
richlistitem[opType="needs-enable"] hbox.addon-optype,
richlistitem[opType="needs-enable"] hbox.addon-description {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addon-needs-enable");
}
richlistitem[opType="needs-disable"] hbox.addon-optype,
richlistitem[opType="needs-disable"] hbox.addon-description {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addon-needs-disable");
}
addonsmessage {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#addonsmessage");
}
#viewGroup radio {
-moz-binding: url("chrome://mozapps/content/extensions/extensions.xml#viewbutton");
-moz-box-orient: vertical;
-moz-box-align: center;
-moz-appearance: none;
}

File diff suppressed because it is too large Load Diff

View File

@ -24,6 +24,7 @@
# Contributor(s):
# Ben Goodger <ben@bengoodger.com>
# Doron Rosenberg <doronr@us.ibm.com>
# Robert Strong <robert.bugzilla@gmail.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
@ -47,92 +48,646 @@
%extensionsDTD;
]>
<bindings id="extensionBindings"
<bindings id="addonBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="extension-base" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
<resources>
<stylesheet src="chrome://mozapps/skin/extensions/extensions.css"/>
</resources>
<binding id="addons" extends="chrome://global/content/bindings/richlistbox.xml#richlistbox">
<implementation>
<method name="fireEvent">
<parameter name="aEventType"/>
<field name="_addonStrings">
document.getElementById("extensionsStrings");
</field>
<field name="_brandShortName">null</field>
<method name="getBrandShortName">
<body>
<![CDATA[
var e = document.createEvent("Events");
e.initEvent(this.eventPrefix + aEventType, true, true);
this.dispatchEvent(e);
]]>
if (!this._brandShortName)
this._brandShortName = document.getElementById("brandStrings").getString("brandShortName");
return this._brandShortName;
</body>
</method>
<field name="_appVersion">null</field>
<method name="getAppVersion">
<body>
if (!this._appVersion) {
var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
.getService(Components.interfaces.nsIXULAppInfo)
.QueryInterface(Components.interfaces.nsIXULRuntime);
this._appVersion = appInfo.version;
}
return this._appVersion;
</body>
</method>
<field name="suppressFocus">false</field>
<!-- Override of richlistbox's _setItemSelection. Allows us to prevent focus
when using the keyboard to navigate views and to ensure an element is
visible after it has had a chance to reflow. -->
<method name="_setItemSelection">
<parameter name="aItem"/>
<body>
<![CDATA[
// unselect current item
if (this._selectedItem)
this._selectedItem.selected = false
this._selectedItem = aItem;
this._selectedIndex = this.getIndexOf(aItem);
if (aItem) {
aItem.selected = true;
if (!this.suppressFocus)
aItem.focus();
}
]]>
</body>
</method>
</implementation>
</binding>
<binding id="extension" extends="chrome://mozapps/content/extensions/extensions.xml#extension-base">
<content>
<xul:hbox flex="1">
<xul:stack class="extension-icon-stack">
<xul:vbox pack="start" align="start">
<xul:image class="extension-icon" xbl:inherits="src=image"
style="width: 32px; max-width: 32px; height: 32px; max-height: 32px;"/>
</xul:vbox>
<xul:vbox pack="end" align="end">
<xul:image class="extension-badge"/>
</xul:vbox>
</xul:stack>
<xul:vbox pack="start" flex="1">
<xul:hbox>
<xul:label class="extension-item-name" xbl:inherits="value=name" crop="center"/>
<xul:label class="extension-item-version" xbl:inherits="value=version"/>
</xul:hbox>
<xul:hbox>
<xul:image class=""/>
<xul:label class="extension-item-description" xbl:inherits="value=description" crop="right"/>
<xul:label class="text-link extension-details-link"
xbl:inherits="href=blocklistDetailsURL" value="&moreInfo.label;"/>
</xul:hbox>
</xul:vbox>
<xul:vbox class="extension-install-button-box" pack="end">
<xul:button anonid="extension-install-button" class="extension-install-button" label="&installNow.label;"/>
</xul:vbox>
</xul:hbox>
</content>
<implementation>
<field name="eventPrefix">"extension-"</field>
</implementation>
<handlers>
<handler event="command">
<![CDATA[
if (event.originalTarget.getAttribute("anonid") == "extension-install-button")
this.fireEvent("updatenow");
]]>
<handler event="focus">
if (!this.hasAttribute("focused"))
this.setAttribute("focused", "true");
</handler>
<handler event="blur">
if (this.hasAttribute("focused"))
this.removeAttribute("focused");
</handler>
</handlers>
</binding>
<binding id="extension-downloading" extends="chrome://mozapps/content/extensions/extensions.xml#extension-base">
<binding id="addon-base" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
<resources>
<stylesheet src="chrome://mozapps/skin/extensions/extensions.css"/>
</resources>
<implementation>
<field name="eventPrefix">"extension-"</field>
<property name="type" onget="return parseInt(this.getAttribute('type'));"/>
<property name="isCompatible" onget="return this.getAttribute('compatible') == 'true';"/>
<property name="isBlocklisted" onget="return this.getAttribute('blocklisted') == 'true';"/>
<property name="isDisabled" onget="return this.getAttribute('isDisabled') == 'true';"/>
<property name="satisfiesDependencies" onget="return this.getAttribute('satisfiesDependencies') == 'true';"/>
<property name="opType">
<getter>
<![CDATA[
var opType = this.getAttribute('opType');
return opType == 'none' ? null : opType;
]]>
</getter>
</property>
<method name="fireEvent">
<parameter name="aEventType"/>
<body>
var e = document.createEvent("Events");
e.initEvent(this.eventPrefix + aEventType, true, true);
this.dispatchEvent(e);
</body>
</method>
</implementation>
<handlers>
<handler event="DOMMenuItemActive">
this.parentNode.ensureElementIsVisible(this);
</handler>
</handlers>
</binding>
<binding id="addon" extends="chrome://mozapps/content/extensions/extensions.xml#addon-base">
<content>
<xul:hbox flex="1">
<xul:vbox class="addon-icon" xbl:inherits="iconURL"/>
<xul:vbox flex="1" class="addonTextBox">
<xul:hbox class="addon-name-version" xbl:inherits="name, version"/>
<xul:hbox class="addon-description" xbl:inherits="description, opType"/>
</xul:vbox>
</xul:hbox>
</content>
</binding>
<binding id="addon-selected" extends="chrome://mozapps/content/extensions/extensions.xml#addon-base">
<content>
<xul:hbox flex="1">
<xul:vbox class="addon-icon" xbl:inherits="iconURL"/>
<xul:vbox flex="1" class="addonTextBox">
<xul:hbox class="addon-name-version" xbl:inherits="name, version"/>
<xul:label class="descriptionWrap" xbl:inherits="xbl:text=description"/>
<xul:vbox class="selectedStatusMsgs">
<xul:hbox class="addon-optype attention" align="center"/>
<xul:hbox flex="1" class="updateAvailableBox attention">
<xul:label xbl:inherits="value=updateAvailableMsg" crop="end"/>
</xul:hbox>
<xul:hbox flex="1" class="incompatibleBox attention">
<xul:label anonid="incompatibleLabel" crop="end"/>
</xul:hbox>
<xul:hbox flex="1" class="needsDependenciesBox attention">
<xul:label value="&needsDependencies.label;" crop="end"/>
</xul:hbox>
<xul:hbox flex="1" class="blocklistedBox attention" align="center">
<xul:label value="&blocklisted.label;" crop="end"/>
<xul:label anonid="blocklistMoreInfo" class="text-link" value="&moreInfo.label;"/>
</xul:hbox>
</xul:vbox>
<xul:hbox anonid="selectedButtons" flex="1" class="selectedButtons">
<xul:button class="uninstallHide optionsButton"
#ifdef XP_WIN
label="&cmd.options.label;" accesskey="&cmd.options.accesskey;"
tooltiptext="&cmd.options.tooltip;"
#else
label="&cmd.optionsUnix.label;" accesskey="&cmd.optionsUnix.accesskey;"
tooltiptext="&cmd.optionsUnix.tooltip;"
#endif
command="cmd_options"/>
<xul:button class="uninstallHide themeButton useThemeButton" label="&cmd.useTheme.label;"
accesskey="&cmd.useTheme.accesskey;" tooltiptext="&cmd.useTheme.tooltip;"
command="cmd_useTheme"/>
<spacer flex="1"/>
<xul:button class="disableShow enableHide uninstallHide enableButton" label="&cmd.enable.label;"
accesskey="&cmd.enable.accesskey;" tooltiptext="&cmd.enable.tooltip;"
command="cmd_enable"/>
<xul:button class="enableShow disableHide uninstallHide disableButton" label="&cmd.disable.label;"
accesskey="&cmd.disable.accesskey;" tooltiptext="&cmd.disable.tooltip;"
command="cmd_disable"/>
<xul:button class="uninstallHide uninstallButton" label="&cmd.uninstall.label;"
accesskey="&cmd.uninstall2.accesskey;" tooltiptext="&cmd.uninstall2.tooltip;"
command="cmd_uninstall"/>
<xul:button class="uninstallShow cancelUninstallButton" label="&cancel.label;"
accesskey="&cancel.accesskey;" tooltiptext="&cmd.cancelUninstall.tooltip;"
command="cmd_cancelUninstall"/>
</xul:hbox>
</xul:vbox>
</xul:hbox>
</content>
<implementation>
<constructor>
<![CDATA[
if (this.isBlocklisted) {
try {
var blocklistMoreInfo = document.getAnonymousElementByAttribute(this, "anonid", "blocklistMoreInfo");
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
blocklistMoreInfo.setAttribute("href", prefs.getCharPref("extensions.blocklist.detailsURL"));
} catch(e) {
blocklistMoreInfo.hidden = true;
}
}
if (!this.isCompatible) {
var label = document.getAnonymousElementByAttribute(this, "anonid", "incompatibleLabel");
label.setAttribute("value", this.parentNode._addonStrings.getFormattedString("incompatibleAddonMsg",
[this.parentNode.getBrandShortName(), this.parentNode.getAppVersion()]));
}
var updatedVersion = this.getAttribute('availableUpdateVersion');
if (updatedVersion) {
var msg = this.parentNode._addonStrings.getFormattedString("updateAvailableMsg", [updatedVersion]);
this.setAttribute("updateAvailableMsg", msg);
}
]]>
</constructor>
</implementation>
<handlers>
<handler event="focus">
<![CDATA[
if (this.parentNode.suppressFocus)
event.preventDefault();
]]>
</handler>
<!-- When an add-on displays a status messages the element may extend below the
bottom of the list This will ensure that the element is visible for the
most common cases. -->
<handler event="DOMAttrModified">
<![CDATA[
if (event.attrName != "disabled" ||
!event.originalTarget.hasAttribute("command"))
return;
var cmd = event.originalTarget.getAttribute("command");
var opType = this.getAttribute("opType");
if (opType == "needs-uninstall" && cmd == "cmd_uninstall" ||
opType == "needs-disable" && cmd == "cmd_disable" && !this.isDisabled ||
opType == "needs-enable" && cmd == "cmd_disable" && this.isDisabled)
this.parentNode.ensureElementIsVisible(this);
]]>
</handler>
</handlers>
</binding>
<binding id="addon-icon">
<content>
<xul:stack class="addonIconStack">
<xul:vbox pack="start" align="start">
<xul:image class="addonIcon" xbl:inherits="src=iconURL"/>
</xul:vbox>
<xul:vbox pack="end" align="start">
<xul:image class="notifyBadge"/>
</xul:vbox>
<xul:vbox pack="end" align="end">
<xul:image class="updateBadge"/>
</xul:vbox>
</xul:stack>
<xul:spacer flex="1"/>
</content>
</binding>
<binding id="addon-name-version">
<content>
<xul:label class="addonName" crop="end" xbl:inherits="value=name"/>
<xul:label class="addonVersion" xbl:inherits="value=version"/>
</content>
</binding>
<binding id="addon-description-crop">
<content>
<xul:label class="descriptionCrop" xbl:inherits="value=description" flex="1" crop="end"/>
</content>
</binding>
<binding id="addon-needs-install">
<content>
<xul:label value="&needsInstall.label;" crop="end"/>
</content>
</binding>
<binding id="addon-needs-upgrade">
<content>
<xul:label value="&needsUpgrade.label;" crop="end"/>
</content>
</binding>
<binding id="addon-needs-uninstall">
<content>
<xul:label value="&needsUninstall.label;" crop="end"/>
</content>
</binding>
<binding id="addon-needs-enable">
<content>
<xul:label value="&needsEnable.label;" crop="end"/>
</content>
</binding>
<binding id="addon-needs-disable">
<content>
<xul:label value="&needsDisable.label;" crop="end"/>
</content>
</binding>
<binding id="update-checking" extends="chrome://mozapps/content/extensions/extensions.xml#addon-base">
<content>
<xul:hbox flex="1">
<xul:stack class="addonIconStack">
<xul:vbox pack="start" align="start">
<xul:image class="addonIcon" xbl:inherits="src=iconURL"/>
</xul:vbox>
<xul:vbox pack="end" align="end">
<xul:image class="updateBadge"/>
</xul:vbox>
<xul:vbox pack="end" align="start">
<xul:image class="notifyBadge"/>
</xul:vbox>
</xul:stack>
<xul:vbox flex="1">
<xul:hbox class="addon-name-version" xbl:inherits="name, version"/>
<xul:hbox>
<xul:description xbl:inherits="value=updateStatus" flex="1" crop="end"/>
</xul:hbox>
</xul:vbox>
</xul:hbox>
</content>
</binding>
<binding id="update-found" extends="chrome://mozapps/content/extensions/extensions.xml#addon-base">
<content>
<xul:hbox flex="1">
<xul:vbox pack="start" align="start">
<xul:image class="addonIcon" xbl:inherits="src=iconURL"/>
</xul:vbox>
<xul:vbox flex="1">
<xul:hbox class="addon-name-version" xbl:inherits="name, version"/>
<xul:hbox>
<xul:description xbl:inherits="value=updateAvailableMsg" flex="1" crop="end"/>
</xul:hbox>
</xul:vbox>
<xul:hbox pack="end" align="end">
<xul:checkbox anonid="includeUpdate" class="includeUpdate" checked="true"
label="&includeUpdate.label;" tooltiptext="&includeUpdate.tooltip;"
includeUpdateAccesskey="&includeUpdate.accesskey;" accesskey="&includeUpdate.accesskey;"/>
</xul:hbox>
</xul:hbox>
</content>
<implementation>
<constructor>
var updatedVersion = this.getAttribute('availableUpdateVersion');
var msg = this.parentNode._addonStrings.getFormattedString("updateAvailableMsg", [updatedVersion]);
this.setAttribute("updateAvailableMsg", msg);
</constructor>
</implementation>
<handlers>
<handler event="DOMMenuItemActive">
<![CDATA[
//
var children = this.parentNode.children;
for (var i = 0; i < children.length; ++i) {
var checkbox = document.getAnonymousElementByAttribute(children[i], "anonid", "includeUpdate");
if (checkbox.hasAttribute("accesskey"))
checkbox.removeAttribute("accesskey");
}
checkbox = document.getAnonymousElementByAttribute(this, "anonid", "includeUpdate");
checkbox.setAttribute("accesskey", checkbox.getAttribute("includeUpdateAccesskey"));
]]>
</handler>
</handlers>
</binding>
<binding id="install" extends="chrome://mozapps/content/extensions/extensions.xml#addon-base">
<content>
<xul:hbox flex="1">
<xul:vbox>
<xul:stack class="addonIcon-stack">
<xul:vbox pack="start" align="start">
<xul:image class="addonIcon" xbl:inherits="src=iconURL"/>
</xul:vbox>
</xul:stack>
</xul:vbox>
<xul:vbox flex="1">
<xul:hbox class="addon-name-version" xbl:inherits="name, version"/>
<xul:hbox class="addon-install-status" xbl:inherits="state"/>
</xul:vbox>
</xul:hbox>
</content>
</binding>
<binding id="addon-install-waiting">
<content>
<xul:label value="&installWaiting.label;" flex="1" crop="end"/>
</content>
</binding>
<binding id="addon-install-incompatibleUpdate">
<content>
<xul:label value="&installIncompatibleUpdate.label;" flex="1" crop="end"/>
</content>
</binding>
<binding id="addon-install-finishing">
<content>
<xul:label value="&installFinishing.label;" flex="1" crop="end"/>
</content>
</binding>
<binding id="addon-install-success">
<content>
<xul:label value="&installSuccess.label;" flex="1" crop="end"/>
</content>
</binding>
<binding id="addon-install-restart">
<content>
<xul:label value="&installSuccessRestart.label;" flex="1" crop="end"/>
</content>
</binding>
<binding id="install-downloading" extends="chrome://mozapps/content/extensions/extensions.xml#addon-base">
<content>
<xul:hbox flex="1">
<xul:vbox pack="start">
<xul:image class="extension-icon" xbl:inherits="src=image"
style="width: 32px; max-width: 32px; height: 32px; max-height: 32px;"/>
<xul:image class="addonIcon" xbl:inherits="src=iconURL"/>
</xul:vbox>
<xul:vbox pack="start" flex="1">
<xul:hbox>
<xul:label class="extension-item-name" xbl:inherits="value=name" crop="center"/>
<xul:label class="extension-item-version" xbl:inherits="value=version"/>
</xul:hbox>
<xul:vbox flex="1" class="addonTextBox">
<xul:hbox class="addon-name-version" xbl:inherits="name, version"/>
<xul:progressmeter class="extension-item-progress" xbl:inherits="value=progress"/>
<xul:label class="extension-item-status" xbl:inherits="value=status"/>
</xul:vbox>
</xul:hbox>
</content>
<implementation>
<field name="eventPrefix">"extension-"</field>
</binding>
<!-- based on preferences.xml paneButton -->
<binding id="viewbutton" extends="chrome://global/content/bindings/radio.xml#radio">
<resources>
<stylesheet src="chrome://mozapps/skin/extensions/extensions.css"/>
</resources>
<content>
<xul:image class="viewButtonIcon" xbl:inherits="src"/>
<xul:label class="viewButtonLabel" xbl:inherits="value=label"/>
</content>
<implementation implements="nsIAccessibleProvider">
<property name="accessible">
<getter>
<![CDATA[
var accService = Components.classes["@mozilla.org/accessibilityService;1"]
.getService(Components.interfaces.nsIAccessibilityService);
return accService.createXULListitemAccessible(this);
]]>
</getter>
</property>
</implementation>
</binding>
</bindings>
<!-- based on browser.xml browsermessage -->
<binding id="addonsmessage" extends="xul:hbox">
<resources>
<stylesheet src="chrome://mozapps/skin/extensions/extensions.css"/>
</resources>
<content align="center">
<xul:hbox align="center" flex="1">
<xul:image anonid="messageImage" class="messageImage"/>
<xul:description anonid="messageText" class="messageText" flex="1"/>
</xul:hbox>
<xul:button anonid="messageButton" class="messageButton"/>
<xul:spacer class="addonsmessage-spacer"/>
<xul:hbox hidden="true" anonid="messageClose" align="center" pack="end"
class="addonsmessage-closebutton-box">
<xul:toolbarbutton ondblclick="event.preventBubble();"
class="addonsmessage-close-button close-button"
tooltiptext="&closeMessage.tooltip;"
oncommand="this.parentNode.parentNode.hideMessage();"/>
</xul:hbox>
</content>
<implementation implements="nsIAccessibleProvider">
<property name="accessible">
<getter>
<![CDATA[
var accService = Components.classes["@mozilla.org/accessibilityService;1"]
.getService(Components.interfaces.nsIAccessibilityService);
return accService.createXULAlertAccessible(this);
]]>
</getter>
</property>
<method name="showMessage">
<parameter name="aIconURL"/>
<parameter name="aMessage"/>
<parameter name="aButtonLabel"/>
<parameter name="aButtonAccesskey"/>
<parameter name="aShowCloseButton"/>
<parameter name="aNotifyData"/>
<body>
<![CDATA[
if (!this.hidden) {
// Prevent duplicate messages.
for (var i = 0; i < this.queue.length; ++i) {
if (this.queue[i][1] == aMessage) {
this.queue.splice(i, 1);
break;
}
}
// Only add new messages to the queue
if (this.text != aMessage)
this.queue.push([this.image, this.text, this.buttonText,
this.buttonAccesskey, !this.closeButton.hidden,
this.notifyData]);
}
this.image = aIconURL;
this.text = aMessage;
this.buttonText = aButtonLabel;
this.buttonAccesskey = aButtonAccesskey;
this.hidden = false;
this.notifyData = aNotifyData ? aNotifyData : null;
this.closeButton = aShowCloseButton;
// Fire event for accessibility APIs
var event = document.createEvent("Events");
event.initEvent("AlertActive", true, true);
this.dispatchEvent(event);
]]>
</body>
</method>
<field name="notifyData">null</field>
<field name="queue">[]</field>
<method name="hideMessage">
<body>
<![CDATA[
this.hidden = true;
if (this.queue.length > 0) {
this.showMessage(this.queue[0][0], this.queue[0][1], this.queue[0][2],
this.queue[0][3], this.queue[0][4], this.queue[0][5]);
this.queue.splice(0, 1);
}
]]>
</body>
</method>
<field name="_imageElement">
document.getAnonymousElementByAttribute(this, "anonid", "messageImage");
</field>
<property name="image">
<getter>
<![CDATA[
return this._imageElement.getAttribute("src");
]]>
</getter>
<setter>
<![CDATA[
this._imageElement.setAttribute("src", val);
return val;
]]>
</setter>
</property>
<field name="_textElement">
document.getAnonymousElementByAttribute(this, "anonid", "messageText");
</field>
<field name="_text">
"";
</field>
<property name="text">
<getter>
<![CDATA[
return this._text;
]]>
</getter>
<setter>
<![CDATA[
this._text = val;
while (this._textElement.hasChildNodes())
this._textElement.removeChild(this._textElement.firstChild);
this._textElement.appendChild(document.createTextNode(val));
return val;
]]>
</setter>
</property>
<field name="_buttonElement">
document.getAnonymousElementByAttribute(this, "anonid", "messageButton");
</field>
<property name="buttonText">
<getter>
<![CDATA[
return this._buttonElement.label;
]]>
</getter>
<setter>
<![CDATA[
if (val) {
if (this._buttonElement.hasAttribute("style"))
this._buttonElement.removeAttribute("style");
this._buttonElement.label = val;
}
else {
if (this._buttonElement.hasAttribute("label"))
this._buttonElement.removeAttribute("label");
this._buttonElement.setAttribute("style", "max-width: 1px; visibility: hidden;");
}
return val;
]]>
</setter>
</property>
<property name="buttonAccesskey">
<getter>
<![CDATA[
return this._buttonElement.getAttribute("accesskey");
]]>
</getter>
<setter>
<![CDATA[
if (val)
this._buttonElement.setAttribute("accesskey", val);
else if (this._buttonElement.hasAttribute("accesskey"))
this._buttonElement.removeAttribute("accesskey");
return val;
]]>
</setter>
</property>
<property name="closeButton">
<getter>
<![CDATA[
return document.getAnonymousElementByAttribute(this, "anonid", "messageClose");
]]>
</getter>
<setter>
<![CDATA[
var elm = document.getAnonymousElementByAttribute(this, "anonid", "messageClose");
elm.hidden = !val;
return val;
]]>
</setter>
</property>
</implementation>
<handlers>
<handler event="command">
if (event.originalTarget.getAttribute("anonid") == "messageButton") {
var os = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
os.notifyObservers(null, "addons-message-notification", this.notifyData);
}
</handler>
</handlers>
</binding>
</bindings>

View File

@ -23,6 +23,7 @@
#
# Contributor(s):
# Ben Goodger <ben@bengoodger.com>
# Robert Strong <robert.bugzilla@gmail.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
@ -38,7 +39,7 @@
#
# ***** END LICENSE BLOCK *****
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://mozapps/content/extensions/extensions.css"?>
<?xml-stylesheet href="chrome://mozapps/skin/extensions/extensions.css"?>
@ -51,9 +52,11 @@
<window xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xhtml2="http://www.w3.org/TR/xhtml2"
xmlns:wairole="http://www.w3.org/2005/01/wai-rdf/GUIRoleTaxonomy#"
id="extensionsManager" windowtype="Extension:Manager"
orient="vertical" title="&extensions.title;" statictitle="&extensions.title;"
screenX="10" screenY="10"
orient="vertical" title="&addons.title;"
screenX="10" screenY="10" width="&em.width;" height="&em.height;"
persist="width height screenX screenY sizeMode"
onload="Startup();" onunload="Shutdown();"
onclose="return closeWindow(false);">
@ -71,10 +74,8 @@
</stringbundleset>
<keyset id="extensionsKeys">
<key id="key_close" key="&cmd.close.commandKey;" modifiers="accel" command="cmd_close"
oncommand="gExtensionsViewController.doCommand('cmd_close');"/>
<key id="key_close2" keycode="VK_ESCAPE" command="cmd_close"
oncommand="gExtensionsViewController.doCommand('cmd_close');"/>
<key id="key_close" key="&cmd.close.commandKey;" modifiers="accel" command="cmd_close"/>
<key id="key_close2" keycode="VK_ESCAPE" command="cmd_close"/>
<key id="key_about" key="&cmd.info.commandKey;" modifiers="accel" command="cmd_about"
oncommand="gExtensionsViewController.doCommand('cmd_about');"/>
<key id="key_options" key="&cmd.options.commandKey;" modifiers="accel" command="cmd_options"
@ -86,26 +87,28 @@
commandupdater="true"
oncommandupdate="gExtensionsViewController.onCommandUpdate();"
oncommand="gExtensionsViewController.doCommand(event.target.id);">
<command id="cmd_close"/>
<command id="cmd_options"/>
<command id="cmd_about"/>
<command id="cmd_homepage"/>
#ifndef MOZ_PHOENIX
<command id="cmd_install"/>
#endif
<command id="cmd_uninstall"/>
<command id="cmd_cancelUninstall"/>
<command id="cmd_update"/>
<command id="cmd_update_all"/>
<command id="cmd_checkUpdate"/>
<command id="cmd_includeUpdate"/>
<command id="cmd_installUpdate"/>
<command id="cmd_enable"/>
<command id="cmd_disable"/>
<command id="cmd_movetop"/>
<command id="cmd_moveup"/>
<command id="cmd_movedn"/>
<command id="cmd_useTheme"/>
</commandset>
<vbox id="contextMenuPalette" hidden="true">
<commandset id="globalCommands">
<command id="cmd_installFile" oncommand="installWithFilePicker();"/>
<command id="cmd_checkUpdatesAll" oncommand="checkUpdatesAll();"/>
<command id="cmd_installUpdatesAll" oncommand="installUpdatesAll();"/>
<command id="cmd_restartApp" oncommand="restartApp();"/>
<command id="cmd_close" oncommand="closeEM();"/>
</commandset>
<vbox id="addonContextMenuPalette" hidden="true">
<menuitem id="menuitem_useTheme" default="true" command="cmd_useTheme"
label="&cmd.useTheme.label;" accesskey="&cmd.useTheme.accesskey;"/>
<menuitem id="menuitem_options" default="true" command="cmd_options"
@ -117,149 +120,60 @@
<menuitem id="menuitem_homepage" command="cmd_homepage"
label="&cmd.homepage.label;" accesskey="&cmd.homepage.accesskey;"/>
<menuitem id="menuitem_about" command="cmd_about"
label="&cmd.about.label;" accesskey="&cmd.about.accesskey;"/>
label="&cmd.about2.label;" accesskey="&cmd.about.accesskey;"/>
<menuseparator id="menuseparator_1"/>
<menuitem id="menuitem_uninstall" command="cmd_uninstall"
label="&cmd.uninstall.label;" accesskey="&cmd.uninstall.accesskey;"/>
label="&cmd.uninstall.label;" accesskey="&cmd.uninstall2.accesskey;"/>
<menuitem id="menuitem_cancelUninstall" command="cmd_cancelUninstall"
label="&cmd.cancelUninstall.label;" accesskey="&cmd.cancelUninstall.accesskey;"/>
<menuitem id="menuitem_update" command="cmd_update"
label="&cmd.updateAddon.label;" accesskey="&cmd.updateAddon.accesskey;"/>
<menuitem id="menuitem_checkUpdate" command="cmd_checkUpdate"
label="&cmd.checkUpdate.label;" accesskey="&cmd.checkUpdate.accesskey;"/>
<menuitem id="menuitem_enable" command="cmd_enable"
label="&cmd.enable.label;" accesskey="&cmd.enable.accesskey;"/>
<menuitem id="menuitem_disable" command="cmd_disable"
label="&cmd.disable.label;" accesskey="&cmd.disable.accesskey;"/>
<menuseparator id="menuseparator_2"/>
<menuitem id="menuitem_moveTop" command="cmd_movetop"
label="&cmd.moveToTop.label;" accesskey="&cmd.moveToTop.accesskey;"/>
<menuitem id="menuitem_moveUp" command="cmd_moveup"
label="&cmd.moveUp.label;" accesskey="&cmd.moveUp.accesskey;"/>
<menuitem id="menuitem_moveDn" command="cmd_movedn"
label="&cmd.moveDn.label;" accesskey="&cmd.moveDn.accesskey;"/>
<menuitem id="menuitem_installUpdate" command="cmd_installUpdate"
label="&cmd.installUpdate.label;" accesskey="&cmd.installUpdate.accesskey;"/>
<menuitem id="menuitem_includeUpdate" command="cmd_includeUpdate"
label="&cmd.includeUpdate.label;" accesskey="&cmd.includeUpdate.accesskey;"
type="checkbox"/>
</vbox>
<popup id="extensionContextMenu" onpopupshowing="return buildContextMenu(event);"/>
<popup id="addonContextMenu" onpopupshowing="return buildContextMenu(event);"/>
<hbox flex="1">
<richlistbox id="extensionsView" flex="3" context="extensionContextMenu"
datasources="rdf:null" persist="last-selected"
<stack id="topStackBar">
<radiogroup id="viewGroup" xhtml2:role="wairole:list" persist="last-selected"
class="viewSelector chromeclass-toolbar" orient="horizontal"
onkeypress="onViewGroupKeypress();" onclick="onViewGroupClick();">
<radio id="extensions-view" label="&extensions.label;" oncommand="showView('extensions');" persist="last-selected"/>
<radio id="themes-view" label="&themes.label;" oncommand="showView('themes');" persist="last-selected"/>
<radio id="locales-view" label="&locales.label;" oncommand="showView('locales');" persist="last-selected"/>
<radio id="plugins-view" label="&plugins.label;" oncommand="showView('plugins');" persist="last-selected"/>
<radio id="updates-view" label="&update.label;" oncommand="showView('updates');"/>
<radio id="installs-view" label="&install.label;" oncommand="showView('installs');" hidden="true"/>
</radiogroup>
<vbox id="progressBox" hidden="true" class="viewSelector" flex="1">
<spacer flex="1"/>
<hbox>
<image class="addonThrobber"/>
<label id="progressStatus" value="Checking For Updates"/>
</hbox>
<progressmeter id="addonsProgress" class="extension-item-progress" flex="1"/>
<spacer flex="1"/>
</vbox>
</stack>
<addonsmessage id="addonsMsg" hidden="true"/>
<hbox id="extensionsBox" flex="1">
<richlistbox id="extensionsView" flex="1"
datasources="rdf:null" context="addonContextMenu"
ondragenter="nsDragAndDrop.dragEnter(event, gExtensionsDNDObserver);"
ondragover="nsDragAndDrop.dragOver(event, gExtensionsDNDObserver);"
ondragdrop="nsDragAndDrop.drop(event, gExtensionsDNDObserver);"
ondblclick="onViewDoubleClick(event);">
<template>
<rule>
<conditions>
<content uri="?uri"/>
<member container="?uri" child="?extension"/>
<triple subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#name"
object="?name"/>
<triple subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#version"
object="?version"/>
<triple id="typeCondition" subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#type"
object="2" parsetype="Integer"/>
</conditions>
<bindings>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#iconURL"
object="?icon"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#previewImage"
object="?previewImage"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#optionsURL"
object="?options-url"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#aboutURL"
object="?about-url"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#updateURL"
object="?update-url"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#disabled"
object="?disabled"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#compatible"
object="?compatible"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#blocklisted"
object="?blocklisted"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#blocklistDetailsURL"
object="?blocklistDetailsURL"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#homepageURL"
object="?homepage-url"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#description"
object="?description"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#displayDescription"
object="?displayDescription"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#locked"
object="?locked"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#internalName"
object="?internalName"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#downloadURL"
object="?downloadURL"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#state"
object="?state"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#progress"
object="?progress"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#status"
object="?status"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#hidden"
object="?hidden"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#opType"
object="?opType"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#incompatibleUpdate"
object="?incompatibleUpdate"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#availableUpdateURL"
object="?available-update-url"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#satisfiesDependencies"
object="?satisfiesDependencies"/>
<binding subject="?extension"
predicate="http://www.mozilla.org/2004/em-rdf#updateable"
object="?updateable"/>
</bindings>
<action>
<!-- XXXben - we could really use a variety of different templates
here to make each element not be so heavy. -->
<extension uri="?extension"
image="?icon" name="?name" version="?version"
description="?displayDescription" creator="?creator"
disabled="?disabled" locked="?locked"
compatible="?compatible" hidden="?hidden"
optionsURL="?options-url" homepageURL="?homepage-url"
aboutURL="?about-url" updateURL="?update-url"
availableUpdateURL="?available-update-url"
previewImage="?previewImage" internalName="?internalName"
opType="?opType" downloadURL="?downloadURL"
state="?state" progress="?progress" status="?status"
incompatibleUpdate="?incompatibleUpdate"
satisfiesDependencies="?satisfiesDependencies"
blocklisted="?blocklisted"
blocklistDetailsURL="?blocklistDetailsURL"
updateable="?updateable"/>
</action>
</rule>
</template>
</richlistbox>
<vbox flex="5" id="themePreviewArea" class="themePreviewArea" hidden="true">
ondblclick="onViewDoubleClick(event);"/>
<splitter id="themeSplitter" hidden="true" collapse="after" persist="state"/>
<vbox id="themePreviewArea" hidden="true" width="220" persist="width">
<deck id="previewImageDeck" flex="1">
<vbox id="noThemeSelected" pack="center" align="center">
<label class="previewText">&previewNoThemeSelected.label;</label>
@ -267,8 +181,7 @@
<vbox id="noPreviewImage" pack="center" align="center">
<label class="previewText">&previewNoPreviewImage.label;</label>
</vbox>
<vbox id="previewImageContainer" align="center" pack="center"
style="overflow: auto;">
<vbox id="previewImageContainer" align="center" pack="center">
<description>
<image id="previewImage"/>
</description>
@ -276,44 +189,37 @@
</deck>
</vbox>
</hbox>
<hbox>
<hbox id="commandBar" flex="1" align="center">
<hbox>
#ifndef MOZ_PHOENIX
<button id="installButton"
label="&cmd.install.label;" accesskey="&cmd.install.accesskey;" tooltiptext="&cmd.install.tooltip;"
command="cmd_install"/>
<separator class="commandBarSeparator"/>
#endif
<button id="uninstallButton"
label="&cmd.uninstall.label;" accesskey="&cmd.uninstall.accesskey;" tooltiptext="&cmd.uninstall.tooltip;"
command="cmd_uninstall"/>
<separator class="commandBarSeparator"/>
<button id="optionsButton" command="cmd_options"
#ifdef XP_WIN
label="&cmd.options.label;" accesskey="&cmd.options.accesskey;" tooltiptext="&cmd.options.tooltip;"/>
#else
label="&cmd.optionsUnix.label;" accesskey="&cmd.optionsUnix.accesskey;" tooltiptext="&cmd.optionsUnix.tooltip;"/>
#endif
<button id="useThemeButton" hidden="true"
label="&cmd.useTheme.label;" accesskey="&cmd.useTheme.accesskey;" tooltiptext="&cmd.useTheme.tooltip;"
command="cmd_useTheme"/>
<separator class="commandBarSeparator"/>
<button id="updateButton"
label="&cmd.update.label;" accesskey="&cmd.update.accesskey;" tooltiptext="&cmd.update.tooltip;"
command="cmd_update_all"/>
</hbox>
<vbox>
<hbox id="commandBarBottom" align="center">
<button id="installFileButton" label="&cmd.installFile.label;"
accesskey="&cmd.installFile.accesskey;"
tooltiptextaddons="&cmd.installFileAddon.tooltip;"
tooltiptextthemes="&cmd.installFileTheme.tooltip;"
command="cmd_installFile"/>
<button id="checkUpdatesAllButton" label="&cmd.checkUpdatesAll.label;"
accesskey="&cmd.checkUpdatesAll.accesskey;"
tooltiptextaddons="&cmd.checkUpdatesAllAddon.tooltip;"
tooltiptextthemes="&cmd.checkUpdatesAllTheme.tooltip;"
command="cmd_checkUpdatesAll"/>
<button id="installUpdatesAllButton" label="&cmd.installUpdatesAll.label;"
accesskey="&cmd.installUpdatesAll.accesskey;"
tooltiptext="&cmd.installUpdatesAll.tooltip;"
command="cmd_installUpdatesAll"/>
<spacer flex="1"/>
<separator class="commandBarSeparator"/>
<button id="restartAppButton" label="&cmd.restartApp.label;"
accesskey="&cmd.restartApp.accesskey;"
tooltiptext="&cmd.restartApp.tooltip;"
command="cmd_restartApp"/>
<label id="getMore" class="text-link"
valuethemes="&getMoreThemes.label;"
valueextensions="&getMoreExtensions.label;"
tooltiptextthemes="&getMoreThemes.tooltip;"
tooltiptextextensions="&getMoreExtensions.tooltip;"/>
</hbox>
<resizer id="windowResizer" dir="bottomright"/>
</hbox>
<hbox id="resizerBox" style="min-width:1px;">
<spacer flex="1"/>
<resizer dir="bottomright"/>
</hbox>
</vbox>
</window>

View File

@ -372,7 +372,7 @@ interface nsIExtensionManager : nsISupports
* interfaces for Gecko 1.8.1. After the 1.8.1 release this interface should
* not be used.
*/
[scriptable, uuid(126d544a-5f34-4277-a3bc-2785ee85a046)]
[scriptable, uuid(0fd5caa9-1ffc-42b1-aea1-3fbe73116070)]
interface nsIExtensionManager_MOZILLA_1_8_BRANCH : nsIExtensionManager
{
/**
@ -409,6 +409,19 @@ interface nsIExtensionManager_MOZILLA_1_8_BRANCH : nsIExtensionManager
* trigger this check from the additional timer used by blocklisting.
*/
void checkForBlocklistChanges();
/**
* Sorts addons of the specified type by the specified property in the
* Extensions Datasource container starting from the top of their container.
* If the addons are already sorted then no action is performed.
* @param type
* The nsIUpdateItem type of the items to sort.
* @param propertyName
* The RDF property name used for sorting.
* @param isAscending
* true to sort ascending and false to sort descending
*/
void sortTypeByProperty(in unsigned long type, in AString propertyName, in boolean isAscending);
};
/**

View File

@ -238,6 +238,10 @@ function EM_I(integer) {
return gRDF.GetIntLiteral(integer);
}
function EM_D(integer) {
return gRDF.GetDateLiteral(integer);
}
/**
* Gets a preference value, handling the case where there is no default.
* @param func
@ -1613,7 +1617,7 @@ Installer.prototype = {
zipReader.close();
var chromeDir = installLocation.getItemFile(id, DIR_CHROME);
try {
jarFile.copyTo(chromeDir, jarFile.fileName);
jarFile.copyTo(chromeDir, jarFile.leafName);
}
catch (e) {
LOG("extractThemeFiles: failed to copy theme JAR file to: " + chromeDir.path);
@ -3829,7 +3833,7 @@ ExtensionManager.prototype = {
var oldRes = gRDF.GetResource(oldPrefix + item.id);
// Disable the item if it was disabled in the version 1.0 extensions
// datasource.
if (oldExtensionsDS.GetTarget(oldRes, EM_R("disabled"), true))
if (oldExtensionsDS.GetTarget(oldRes, EM_R("isDisabled"), true))
ds.setItemProperty(item.id, EM_R("userDisabled"), EM_L("true"));
// app enable all items. If it is incompatible it will be app disabled
@ -3909,7 +3913,7 @@ ExtensionManager.prototype = {
continue;
}
// Suppress items that have been disabled by the user or the app.
if (ds.getItemProperty(item.id, "disabled") != "true")
if (ds.getItemProperty(item.id, "isDisabled") != "true")
activeItems.push({ id: item.id, location: installLocation });
}
@ -4608,8 +4612,6 @@ ExtensionManager.prototype = {
*/
installRequiresRestart: function(id, type) {
switch (type) {
case nsIUpdateItem.TYPE_EXTENSION:
return true;
case nsIUpdateItem.TYPE_THEME:
var internalName = this.datasource.getItemProperty(id, "internalName");
var needsRestart = false;
@ -4620,7 +4622,7 @@ ExtensionManager.prototype = {
needsRestart = internalName == gPref.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
return needsRestart;
}
return false;
return true;
},
/**
@ -4649,7 +4651,6 @@ ExtensionManager.prototype = {
availableUpdateVersion: null };
for (var p in props)
ds.setItemProperty(id, EM_R(p), props[p]);
ds.updateProperty(id, "displayDescription");
ds.updateProperty(id, "availableUpdateURL");
this._setOp(id, OP_NEEDS_INSTALL);
@ -4689,7 +4690,6 @@ ExtensionManager.prototype = {
availableUpdateVersion : null };
for (var p in props)
ds.setItemProperty(id, EM_R(p), props[p]);
ds.updateProperty(id, "displayDescription");
ds.updateProperty(id, "availableUpdateURL");
this._setOp(id, OP_NEEDS_UPGRADE);
@ -4843,47 +4843,34 @@ ExtensionManager.prototype = {
* The GUID of the item to uninstall.
*/
uninstallItem: function(id) {
var em = this;
/**
* Cleans up any staged xpis for this item when we uninstall. This fixes
* this scenario:
* 1 install Foo 1.0, and restart
* 2 install Foo 1.1,
* 3 without restarting, uninstall Foo 1.1
* 4 Foo is uninstalled but the staged XPI from the install operation in
* step 2 lingers, and is offered to the user on the next startup to
* be installed.
* @param id
* The GUID of the item to look for staged files for.
*/
function cleanUpPendingStageFile(id) {
var foundStageOp = false;
var stageOps = PendingOperations.getOperations(OP_NEEDS_UPGRADE);
stageOps = stageOps.concat(PendingOperations.getOperations(OP_NEEDS_INSTALL));
for (var i = 0; i < stageOps.length; ++i) {
if (stageOps[i].id == id) {
foundStageOp = true;
break;
}
}
if (foundStageOp) {
var location = em.getInstallLocation(id);
var stageFile = location.getStageFile(id);
if (stageFile)
location.removeFile(stageFile);
}
}
var ds = this.datasource;
var type = ds.getItemProperty(id, "type");
ds.updateDownloadState(PREFIX_ITEM_URI + id, null);
if (!ds.isDownloadItem(id)) {
cleanUpPendingStageFile(id);
this._setOp(id, OP_NEEDS_UNINSTALL);
var restartRequired = this.installRequiresRestart(id, type);
if (!restartRequired) {
this._finalizeUninstall(id);
this._updateManifests(restartRequired);
var opType = ds.getItemProperty(id, "opType");
var installLocation = this.getInstallLocation(id);
// Removes any staged xpis for this item.
if (opType == OP_NEEDS_UPGRADE || opType == OP_NEEDS_INSTALL) {
var stageFile = installLocation.getStageFile(id);
if (stageFile)
installLocation.removeFile(stageFile);
}
// Addons with an opType of OP_NEEDS_INSTALL only have a staged xpi file
// and are removed immediately since the uninstall can't be canceled.
if (opType == OP_NEEDS_INSTALL) {
ds.removeItemMetadata(id);
ds.removeItemFromContainer(id);
ds.updateVisibleList(id, null, true);
StartupCache.clearEntry(installLocation, id);
this._updateManifests(false);
}
else {
this._setOp(id, OP_NEEDS_UNINSTALL);
var type = ds.getItemProperty(id, "type");
var restartRequired = this.installRequiresRestart(id, type);
if (!restartRequired) {
this._finalizeUninstall(id);
this._updateManifests(restartRequired);
}
}
}
else {
@ -4916,6 +4903,10 @@ ExtensionManager.prototype = {
this._setOp(id, OP_NEEDS_ENABLE);
this._notifyAction(id, EM_ITEM_ENABLED);
}
else {
this._setOp(id, OP_NONE);
this._notifyAction(id, EM_ITEM_CANCEL);
}
},
/**
@ -4930,10 +4921,12 @@ ExtensionManager.prototype = {
StartupCache.put(location, id, op, true);
PendingOperations.addItem(op, { locationKey: location.name, id: id });
var ds = this.datasource;
if (op == OP_NEEDS_INSTALL || op == OP_NEEDS_UPGRADE)
ds.updateDownloadState(PREFIX_ITEM_URI + id, "success");
ds.updateProperty(id, "opType");
ds.updateProperty(id, "updateable");
ds.updateProperty(id, "satisfiesDependencies");
ds.updateProperty(id, "displayDescription");
var restartRequired = this.installRequiresRestart(id, ds.getItemProperty(id, "type"))
this._updateDependentItemsForID(id);
this._updateManifests(restartRequired);
@ -5011,7 +5004,6 @@ ExtensionManager.prototype = {
}
else {
ds.updateProperty(id, "satisfiesDependencies");
ds.updateProperty(id, "displayDescription");
this._updateDependentItemsForID(id);
}
},
@ -5079,7 +5071,6 @@ ExtensionManager.prototype = {
}
else {
ds.updateProperty(id, "satisfiesDependencies");
ds.updateProperty(id, "displayDescription");
this._updateDependentItemsForID(id);
}
},
@ -5124,7 +5115,6 @@ ExtensionManager.prototype = {
}
else {
ds.updateProperty(id, "satisfiesDependencies");
ds.updateProperty(id, "displayDescription");
this._updateDependentItemsForID(id);
}
},
@ -5169,7 +5159,6 @@ ExtensionManager.prototype = {
}
else {
ds.updateProperty(id, "satisfiesDependencies");
ds.updateProperty(id, "displayDescription");
this._updateDependentItemsForID(id);
}
},
@ -5235,7 +5224,6 @@ ExtensionManager.prototype = {
for (var i = 0; i < items.length; ++i) {
var id = items[i].id;
ds.updateProperty(id, "blocklisted");
ds.updateProperty(id, "blocklistDetailsURL");
var appDisabled = ds.getItemProperty(id, "appDisabled");
if ((appDisabled == "true" || appDisabled == OP_NEEDS_DISABLE) &&
ds.getItemProperty(id, "compatible") == "true" &&
@ -5333,6 +5321,21 @@ ExtensionManager.prototype = {
this.datasource.moveToIndexOf(movingID, destinationID);
},
/**
* Sorts addons of the specified type by the specified property starting from
* the top of their container. If the addons are already sorted then no action
* is performed.
* @param type
* The nsIUpdateItem type of the items to sort.
* @param propertyName
* The RDF property name used for sorting.
* @param isAscending
* true to sort ascending and false to sort descending
*/
sortTypeByProperty: function(type, propertyName, isAscending) {
this.datasource.sortTypeByProperty(type, propertyName, isAscending);
},
/////////////////////////////////////////////////////////////////////////////
// Downloads
_transactions: [],
@ -5348,6 +5351,9 @@ ExtensionManager.prototype = {
*/
_confirmCancelDownloadsOnQuit: function(subject) {
if (this._downloadCount > 0) {
// The observers will be notified again after this so set the download
// count to 0 to prevent this dialog from being displayed again.
this._downloadCount = 0;
var result;
#ifndef XP_MACOSX
result = this._confirmCancelDownloads(this._downloadCount,
@ -5386,8 +5392,8 @@ ExtensionManager.prototype = {
"dontGoOfflineButton");
if (!result)
this._cancelDownloads();
var PRBool = subject.QueryInterface(Components.interfaces.nsISupportsPRBool);
PRBool.data = result;
if (subject instanceof Components.interfaces.nsISupportsPRBool)
subject.data = result;
}
},
@ -5397,8 +5403,6 @@ ExtensionManager.prototype = {
_cancelDownloads: function() {
for (var i = 0; i < this._transactions.length; ++i)
gOS.notifyObservers(this._transactions[i], "xpinstall-progress", "cancel");
gOS.removeObserver(this, "offline-requested");
gOS.removeObserver(this, "quit-application-requested");
this._removeAllDownloads();
},
@ -5459,6 +5463,12 @@ ExtensionManager.prototype = {
* false when not called from chrome (e.g. web page)
*/
addDownloads: function(items, itemCount, fromChrome) {
var ds = this.datasource;
// Add observers only if they aren't already added for an active download
if (this._downloadCount == 0) {
gOS.addObserver(this, "offline-requested", false);
gOS.addObserver(this, "quit-application-requested", false);
}
this._downloadCount += itemCount;
var urls = [];
@ -5471,11 +5481,19 @@ ExtensionManager.prototype = {
this._transactions.push(txn);
urls.push(currItem.xpiURL);
hashes.push(currItem.xpiHash ? currItem.xpiHash : null);
// if this is an update remove the update metadata to prevent it from
// being updated during an install.
if (fromChrome) {
var id = currItem.id
ds.setItemProperty(id, EM_R("availableUpdateURL"), null);
ds.setItemProperty(id, EM_R("availableUpdateHash"), null);
ds.setItemProperty(id, EM_R("availableUpdateVersion"), null);
ds.updateProperty(id, "availableUpdateURL");
ds.updateProperty(id, "updateable");
}
var id = fromChrome ? PREFIX_ITEM_URI + currItem.id : currItem.xpiURL;
ds.updateDownloadState(id, "waiting");
}
// Kick off the download process for this transaction
gOS.addObserver(this, "offline-requested", false);
gOS.addObserver(this, "quit-application-requested", false);
if (fromChrome) {
// Initiate an install from chrome
@ -5532,16 +5550,19 @@ ExtensionManager.prototype = {
* ???
*/
onStateChange: function(transaction, addon, state, value) {
var url = addon.xpiURL;
if (!(url in this._progressData))
this._progressData[url] = { };
this._progressData[url].state = state;
for (var i = 0; i < this._updateListeners.length; ++i)
this._updateListeners[i].onStateChange(addon, state, value);
var ds = this.datasource;
var id = addon.id != addon.xpiURL ? PREFIX_ITEM_URI + addon.id : addon.xpiURL;
const nsIXPIProgressDialog = Components.interfaces.nsIXPIProgressDialog;
switch (state) {
case nsIXPIProgressDialog.DOWNLOAD_START:
ds.updateDownloadState(id, "downloading");
break;
case nsIXPIProgressDialog.INSTALL_START:
ds.updateDownloadState(id, "finishing");
ds.updateDownloadProgress(id, null);
break;
case nsIXPIProgressDialog.INSTALL_DONE:
--this._downloadCount;
this.removeDownload(addon.xpiURL);
@ -5551,31 +5572,25 @@ ExtensionManager.prototype = {
if (this._transactions[i].id == transaction.id) {
this._transactions.splice(i, 1);
delete transaction;
// Remove the observers when all transactions have completed.
if (this._transactions.length == 0) {
gOS.removeObserver(this, "offline-requested");
gOS.removeObserver(this, "quit-application-requested");
}
break;
}
}
break;
}
// If we're updating an installed item for which content is already built,
// update the "displayDescription" property so the restart now message is
// shown.
if (addon.id != addon.xpiURL) {
var ds = this.datasource;
ds.updateProperty(addon.id, "displayDescription");
ds.updateProperty(addon.id, "availableUpdateURL");
ds.updateProperty(addon.id, "updateable");
}
},
_progressData: { },
onProgress: function(addon, value, maxValue) {
for (var i = 0; i < this._updateListeners.length; ++i)
this._updateListeners[i].onProgress(addon, value, maxValue);
var url = addon.xpiURL;
if (!(url in this._progressData))
this._progressData[url] = { };
this._progressData[url].progress = Math.round((value / maxValue) * 100);
var id = addon.id != addon.xpiURL ? PREFIX_ITEM_URI + addon.id : addon.xpiURL;
var progress = Math.round((value / maxValue) * 100);
this.datasource.updateDownloadProgress(id, progress);
},
_updateListeners: [],
@ -5590,8 +5605,6 @@ ExtensionManager.prototype = {
removeUpdateListenerAt: function(index) {
this._updateListeners.splice(index, 1);
if (this._downloadCount != 0)
this.datasource.flushProgressInfo(this._progressData);
},
/**
@ -5714,7 +5727,7 @@ ItemDownloadTransaction.prototype = {
removeAllDownloads: function() {
for (var i = 0; i < this._downloads.length; ++i) {
var addon = this._downloads[i].addon;
this.removeDownload(addon.xpiURL, addon.type);
this.removeDownload(addon.xpiURL);
}
},
@ -6530,9 +6543,7 @@ ExtensionsDataSource.prototype = {
var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
var type = this.getItemProperty(id, "type");
// Skip this item if we're not seeking disabled items
if (!includeDisabled &&
(this.getItemProperty(id, "disabled") == "true" ||
this.getItemProperty(id, "appDisabled") == "true"))
if (!includeDisabled && this.getItemProperty(id, "isDisabled") == "true")
continue;
// If the id of this item matches one of the items potentially installed
@ -6643,7 +6654,7 @@ ExtensionsDataSource.prototype = {
var target = targets.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
var dependencyID = stringData(ds.GetTarget(target, idRes, true));
if (dependencyID == id) {
if (!includeDisabled && this.getItemProperty(dependentID, "disabled") == "true")
if (!includeDisabled && this.getItemProperty(dependentID, "isDisabled") == "true")
continue;
items.push(this.getItemForID(dependentID));
break;
@ -7144,7 +7155,6 @@ ExtensionsDataSource.prototype = {
}
this.updateProperty(id, "opType");
this.updateProperty(id, "updateable");
this.updateProperty(id, "displayDescription");
this.Flush();
},
@ -7199,6 +7209,21 @@ ExtensionsDataSource.prototype = {
*/
updateProperty: function(id, property) {
var item = getResourceForID(id);
this._updateProperty(item, property);
},
/**
* Notify views that this propery has changed (this is for properties that
* are implemented by this datasource rather than by the inner in-memory
* datasource and thus do not get free change handling). This allows updating
* properties for download items which don't have the em item prefix in there
( resource value. In most instances updateProperty should be used.
* @param item
* The item to update the property for.
* @param property
* The property (less EM_NS) to update.
*/
_updateProperty: function(item, property) {
var propertyResource = EM_R(property);
var value = this.GetTarget(item, propertyResource, true);
if (item && value) {
@ -7229,14 +7254,77 @@ ExtensionsDataSource.prototype = {
this.Flush();
},
/**
* Sorts addons of the specified type by the specified property starting from
* the top of their container. If the addons are already sorted then no action
* is performed.
* @param type
* The nsIUpdateItem type of the items to sort.
* @param propertyName
* The RDF property name used for sorting.
* @param isAscending
* true to sort ascending and false to sort descending
*/
sortTypeByProperty: function(type, propertyName, isAscending) {
var items = [];
var ctr = getContainer(this._inner, this._itemRoot);
var elements = ctr.GetElements();
// Base 0 ordinal for checking against the existing order after sorting
var ordinal = 0;
while (elements.hasMoreElements()) {
var item = elements.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
var itemType = this.getItemProperty(id, "type");
if (itemType & type) {
items.push({ item : item,
ordinal: ordinal,
sortkey: this.getItemProperty(id, propertyName).toLowerCase() });
ordinal++;
}
}
var direction = isAscending ? 1 : -1;
// Case insensitive sort
function compare(a, b) {
if (a.sortkey < b.sortkey) return (-1 * direction);
if (a.sortkey > b.sortkey) return (1 * direction);
return 0;
}
items.sort(compare);
// Check if there are any changes in the order of the items
var isDirty = false;
for (var i = 0; i < items.length; i++) {
if (items[i].ordinal != i) {
isDirty = true;
break;
}
}
// If there are no changes then early return to avoid the perf impact
if (!isDirty)
return;
// Reorder the items by moving them to the top of the container
this.beginUpdateBatch();
for (i = 0; i < items.length; i++) {
ctr.RemoveElement(items[i].item, true);
ctr.InsertElementAt(items[i].item, i + 1, true);
}
this.endUpdateBatch();
this.Flush();
},
/**
* Determines if an Item is an active download
* @param id
* The GUID of the item
* The ID of the item. This will be a uri scheme without the
* em item prefix so getProperty shouldn't be used.
* @returns true if the item is an active download, false otherwise.
*/
isDownloadItem: function(id) {
return this.getItemProperty(id, "downloadURL") != "";
var downloadURL = stringData(this.GetTarget(gRDF.GetResource(id), EM_R("downloadURL"), true));
return downloadURL && downloadURL != "";
},
/**
@ -7246,8 +7334,12 @@ ExtensionsDataSource.prototype = {
* downloaded.
*/
addDownload: function(addon) {
if (addon.id != addon.xpiURL)
// Updates have already been added to the datasource so we just update the
// download state.
if (addon.id != addon.xpiURL) {
this.updateDownloadState(PREFIX_ITEM_URI + addon.id, "waiting");
return;
}
var res = gRDF.GetResource(addon.xpiURL);
this._setProperty(this._inner, res, EM_R("name"), EM_L(addon.name));
this._setProperty(this._inner, res, EM_R("version"), EM_L(addon.version));
@ -7259,6 +7351,7 @@ ExtensionsDataSource.prototype = {
if (ctr.IndexOf(res) == -1)
ctr.AppendElement(res);
this.updateDownloadState(addon.xpiURL, "waiting");
this.Flush();
},
@ -7268,19 +7361,13 @@ ExtensionsDataSource.prototype = {
* @param name
* The display name of the item being checked
* @param url
* The URL string of the xpi file that has been staged. This is
* also used for installLocation to make this an independently
* managed item
* The URL string of the xpi file that has been staged.
* @param type
* The nsIUpdateItem type of the item
* @param version
* The version of the item
*/
addIncompatibleUpdateItem: function(name, url, type, version) {
// type must be TYPE_EXTENSION for a multi_xpi to display in the manager.
if (type == nsIUpdateItem.TYPE_MULTI_XPI)
type = nsIUpdateItem.TYPE_EXTENSION;
var iconURL = (type == nsIUpdateItem.TYPE_THEME) ? URI_GENERIC_ICON_THEME :
URI_GENERIC_ICON_XPINSTALL;
var extensionsStrings = BundleManager.getBundle(URI_EXTENSIONS_PROPERTIES);
@ -7300,6 +7387,7 @@ ExtensionsDataSource.prototype = {
if (ctr.IndexOf(res) == -1)
ctr.AppendElement(res);
this.updateDownloadState(url, "incompatibleUpdate");
this.Flush();
},
@ -7314,28 +7402,59 @@ ExtensionsDataSource.prototype = {
if (ctr.IndexOf(res) != -1)
ctr.RemoveElement(res, true);
this._cleanResource(res);
this.updateDownloadState(url, null);
this.Flush();
},
/**
* Write download progress info for a set of items to the Datasource
* @param data
* A JS Object containing progress information for a set of active
* downloads, hashed by URL. Each object has the following properties:
* "state" An integer value representing the download/install
* state.
* "progress" An integer value between 0 and 100 representing
* percentage complete
* A hash of RDF resource values (e.g. Add-on IDs or XPI URLs) that represent
* installation progress for a single browser session.
*/
flushProgressInfo: function(data) {
for (var url in data) {
var res = gRDF.GetResource(url);
this._setProperty(this._inner, res, EM_R("state"), EM_I(data[url].state));
this._setProperty(this._inner, res, EM_R("progress"), EM_I(data[url].progress));
_progressData: { },
/**
* Updates the install progress data for a given ID (e.g. Add-on IDs or
* XPI URLs).
* @param id
* The URL string of the active download to be removed
* @param state
* The current state in the installation process. If null the object
* is deleted from _progressData.
*/
updateDownloadState: function(id, state) {
if (!state) {
if (id in this._progressData)
delete this._progressData[id];
return;
}
this.Flush();
},
else {
if (!(id in this._progressData))
this._progressData[id] = { };
this._progressData[id].state = state;
}
var item = gRDF.GetResource(id);
this._updateProperty(item, "state");
},
updateDownloadProgress: function(id, progress) {
if (!progress) {
if (!(id in this._progressData))
return;
this._progressData[id].progress = null;
}
else {
if (!(id in this._progressData))
this.updateDownloadState(id, "downloading");
if (this._progressData[id].progress == progress)
return;
this._progressData[id].progress = progress;
}
var item = gRDF.GetResource(id);
this._updateProperty(item, "progress");
},
/**
* A GUID->location-key hash of items that are visible to the application.
* These are items that show up in the Extension/Themes etc UI. If there is
@ -7406,11 +7525,6 @@ ExtensionsDataSource.prototype = {
this._buildVisibleItemList();
},
/**
* A hash of Addon IDs that we are currently looking for updates to.
*/
_updateURLs: { },
/**
* See nsIExtensionManager.idl
*/
@ -7423,7 +7537,6 @@ ExtensionsDataSource.prototype = {
*/
onUpdateEnded: function() {
LOG("Datasource: Update Ended");
this._updateURLs = { };
},
/**
@ -7431,9 +7544,7 @@ ExtensionsDataSource.prototype = {
*/
onAddonUpdateStarted: function(addon) {
LOG("Datasource: Addon Update Started: " + addon.id);
this._updateURLs[addon.id] = addon.id;
this.updateProperty(addon.id, "availableUpdateURL");
this.updateProperty(addon.id, "displayDescription");
},
/**
@ -7441,7 +7552,6 @@ ExtensionsDataSource.prototype = {
*/
onAddonUpdateEnded: function(addon, status) {
LOG("Datasource: Addon Update Ended: " + addon.id + ", status: " + status);
this._updateURLs[addon.id] = status;
var url = null, hash = null, version = null;
var updateAvailable = status == nsIAddonUpdateCheckListener.STATUS_UPDATE;
if (updateAvailable) {
@ -7454,7 +7564,6 @@ ExtensionsDataSource.prototype = {
this.setItemProperty(addon.id, EM_R("availableUpdateHash"), hash);
this.setItemProperty(addon.id, EM_R("availableUpdateVersion"), version);
this.updateProperty(addon.id, "availableUpdateURL");
this.updateProperty(addon.id, "displayDescription");
},
/////////////////////////////////////////////////////////////////////////////
@ -7504,27 +7613,29 @@ ExtensionsDataSource.prototype = {
_rdfGet_iconURL: function(item, property) {
var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
var type = this.getItemProperty(id, "type");
if (type != -1 && type & nsIUpdateItem.TYPE_EXTENSION) {
var hasIconURL = this._inner.hasArcOut(item, property);
// If the download entry doesn't have a IconURL property, use a
// generic icon URL instead.
if (!hasIconURL || this.getItemProperty(id, "disabled") == "true")
return gRDF.GetResource(URI_GENERIC_ICON_XPINSTALL);
var iconURL = this._inner.GetTarget(item, property, true);
iconURL = iconURL.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
var uri = newURI(iconURL);
try {
var cr = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
.getService(Components.interfaces.nsIChromeRegistry);
cr.convertChromeURL(uri);
}
catch(e) {
// bogus URI, supply a generic icon.
return gRDF.GetResource(URI_GENERIC_ICON_XPINSTALL);
}
}
else if (type != -1 && type & nsIUpdateItem.TYPE_THEME)
if (type & nsIUpdateItem.TYPE_THEME)
return this._getThemeImageURL(item, "icon.png", URI_GENERIC_ICON_THEME);
if (inSafeMode())
return gRDF.GetResource(URI_GENERIC_ICON_XPINSTALL);
var hasIconURL = this._inner.hasArcOut(item, property);
// If the download entry doesn't have a IconURL property, use a
// generic icon URL instead.
if (!hasIconURL || this.getItemProperty(id, "isDisabled") == "true")
return gRDF.GetResource(URI_GENERIC_ICON_XPINSTALL);
var iconURL = this._inner.GetTarget(item, property, true);
iconURL = iconURL.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
try {
var uri = newURI(iconURL);
var cr = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
.getService(Components.interfaces.nsIChromeRegistry);
cr.convertChromeURL(uri);
}
catch(e) {
// bogus URI, supply a generic icon.
return gRDF.GetResource(URI_GENERIC_ICON_XPINSTALL);
}
return null;
},
@ -7544,21 +7655,19 @@ ExtensionsDataSource.prototype = {
*/
_rdfGet_aboutURL: function(item, property) {
var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
if (inSafeMode() || this.getItemProperty(id, "disabled") == "true" ||
if (inSafeMode() || this.getItemProperty(id, "isDisabled") == "true" ||
this.getItemProperty(id, "opType") == OP_NEEDS_UPGRADE)
return EM_L("");
return null;
},
_rdfGet_blocklistDetailsURL: function(item, property) {
_rdfGet_installDate: function(item, property) {
var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
if (this.getItemProperty(id, "blocklisted") == "false")
return null;
var url = getPref("getCharPref", PREF_BLOCKLIST_DETAILS_URL, "");
if (url)
return EM_L(url);
var key = this.getItemProperty(id, "installLocation");
if (key in StartupCache.entries && id in StartupCache.entries[key] &&
StartupCache.entries[key][id] && StartupCache.entries[key][id].mtime)
return EM_D(StartupCache.entries[key][id].mtime * 1000000);
return null;
},
@ -7568,10 +7677,14 @@ ExtensionsDataSource.prototype = {
_rdfGet_compatible: function(item, property) {
var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
var targetAppInfo = this.getTargetApplicationInfo(id, this);
if (!targetAppInfo)
if (!targetAppInfo) {
// When installing a new addon targetAppInfo does not exist yet
if (this.getItemProperty(id, "opType") == OP_NEEDS_INSTALL)
return EM_L("true");
return EM_L("false");
getVersionChecker();
}
getVersionChecker();
var appVersion = getPref("getCharPref", PREF_EM_APP_EXTENSIONS_VERSION,
gApp.version);
if (gVersionChecker.compare(targetAppInfo.maxVersion, appVersion) < 0 ||
@ -7624,9 +7737,32 @@ ExtensionsDataSource.prototype = {
return EM_L("false");
},
/**
* Get the em:state property (represents the current phase of an install).
*/
_rdfGet_state: function(item, property) {
var id = item.Value;
if (id in this._progressData)
return EM_L(this._progressData[id].state);
return null;
},
/**
* Get the em:progress property from the _progressData js object. By storing
* progress which is updated repeastedly during a download we avoid
* repeastedly writing it to the rdf file.
*/
_rdfGet_progress: function(item, property) {
var id = item.Value;
if (id in this._progressData)
return EM_I(this._progressData[id].progress);
return null;
},
/**
* Gets the em:availableUpdateURL - the URL to an XPI update package, if
* present, or a literal string "novalue" if there is no update XPI URL.
* present, or a literal string "none" if there is no update XPI URL.
* XXXrstrong we return none due to bug 331689
*/
_rdfGet_availableUpdateURL: function(item, property) {
var value = this._inner.GetTarget(item, property, true);
@ -7646,96 +7782,19 @@ ExtensionsDataSource.prototype = {
return EM_L("true");
return EM_L("false");
},
/**
* Get the em:displayDescription property (description that is displayed
* in the UI - not always the info description of the item - sometimes
* a message like "will be uninstalled after restart" etc)
*/
_rdfGet_displayDescription: function(item, property) {
var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
var extensionsStrings = BundleManager.getBundle(URI_EXTENSIONS_PROPERTIES);
var itemName = this.getItemProperty(id, "name");
var opType = this.getItemProperty(id, "opType");
function getLiteral(key, strings) {
if (strings)
return EM_L(extensionsStrings.formatStringFromName(key,
strings, strings.length));
return EM_L(extensionsStrings.GetStringFromName(key));
}
if (id in this._updateURLs && this._updateURLs[id]) {
switch (this._updateURLs[id]) {
case id:
return getLiteral("updatingMessage", [itemName]);
case nsIAddonUpdateCheckListener.STATUS_APP_MANAGED:
case nsIAddonUpdateCheckListener.STATUS_NO_UPDATE:
return getLiteral("updateNoUpdateMessage", [itemName]);
case nsIAddonUpdateCheckListener.STATUS_VERSIONINFO:
if (opType == OP_NEEDS_UPGRADE || opType == OP_NEEDS_INSTALL)
break;
return getLiteral("updateCompatibilityMessage", [itemName]);
case nsIAddonUpdateCheckListener.STATUS_FAILURE:
return getLiteral("updateErrorMessage", [itemName]);
case nsIAddonUpdateCheckListener.STATUS_DISABLED:
return getLiteral("updateDisabledMessage", [itemName]);
case nsIAddonUpdateCheckListener.STATUS_READ_ONLY:
return getLiteral("updateReadOnlyMessage");
case nsIAddonUpdateCheckListener.STATUS_NOT_MANAGED:
return getLiteral("updateNotManagedMessage", [BundleManager.appName]);
}
}
var node = this._inner.GetTarget(item, EM_R("availableUpdateURL"), true);
if (node) {
var version = this.getItemProperty(id, "availableUpdateVersion");
return getLiteral("updateAvailableMessage", [itemName, version]);
}
switch (opType) {
case OP_NEEDS_DISABLE:
if (this.getItemProperty(id, "blocklisted") == "true")
return getLiteral("restartBeforeDisableBlocklisted", [itemName, BundleManager.appName]);
return getLiteral("restartBeforeDisableMessage", [itemName, BundleManager.appName]);
case OP_NEEDS_ENABLE:
return getLiteral("restartBeforeEnableMessage", [itemName, BundleManager.appName]);
case OP_NEEDS_INSTALL:
return getLiteral("restartBeforeInstallMessage", [itemName, BundleManager.appName]);
case OP_NEEDS_UNINSTALL:
return getLiteral("restartBeforeUninstallMessage", [itemName, BundleManager.appName]);
case OP_NEEDS_UPGRADE:
return getLiteral("restartBeforeUpgradeMessage", [itemName, BundleManager.appName]);
}
if (this.getItemProperty(id, "appDisabled") == "true" &&
this.getItemProperty(id, "blocklisted") == "true")
return getLiteral("blocklistedDisabled", [BundleManager.appName, gApp.version]);
if (this.getItemProperty(id, "appDisabled") == "true" &&
this.getItemProperty(id, "compatible") != "true")
return getLiteral("incompatibleExtension", [BundleManager.appName, gApp.version]);
if (this.getItemProperty(id, "appDisabled") == "true" &&
this.getItemProperty(id, "satisfiesDependencies") == "false")
return getLiteral("needsDependenciesDisabled");
if (inSafeMode())
return getLiteral("disabledBySafeMode", [itemName, BundleManager.appName]);
// No special state for this item, so just use the "description" property.
return this.GetTarget(item, EM_R("description"), true);
},
/**
* Get the em:opType property (controls widget state for the EM UI)
* from the Startup Cache (e.g. extensions.cache)
* XXXrstrong we return none for OP_NONE due to bug 331689
*/
_rdfGet_opType: function(item, property) {
var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
var key = this.getItemProperty(id, "installLocation");
if (key in StartupCache.entries && id in StartupCache.entries[key] &&
StartupCache.entries[key][id])
StartupCache.entries[key][id] && StartupCache.entries[key][id].op != OP_NONE)
return EM_L(StartupCache.entries[key][id].op);
return EM_L(OP_NONE);
return EM_L("none");
},
/**
@ -7793,33 +7852,25 @@ ExtensionsDataSource.prototype = {
},
/**
* Get the em:disabled property. This will be true if the item has a
* Get the em:isDisabled property. This will be true if the item has a
* appDisabled or a userDisabled property that is true or OP_NEEDS_ENABLE.
*/
_rdfGet_disabled: function(item, property) {
_rdfGet_isDisabled: function(item, property) {
var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
if (this.getItemProperty(id, "userDisabled") == "true" ||
this.getItemProperty(id, "appDisabled") == "true" ||
this.getItemProperty(id, "userDisabled") == OP_NEEDS_ENABLE ||
this.getItemProperty(id, "appDisabled") == OP_NEEDS_ENABLE)
return EM_L("true");
// Migrate disabled in the extensions datasource to userDisabled or
// appDisabled as appropriate.
var oldDisabled = this._inner.GetTarget(item, property, true);
if (oldDisabled instanceof Components.interfaces.nsIRDFLiteral) {
this._inner.Unassert(item, property, oldDisabled);
if (this.getItemProperty(id, "compatible") == "true")
this.setItemProperty(id, EM_R("userDisabled"), EM_L("true"));
else
this.setItemProperty(id, EM_R("appDisabled"), EM_L("true"));
return EM_L("true");
}
return EM_L("false");
},
_rdfGet_addonID: function(item, property) {
var id = this._inner.GetTarget(item, EM_R("downloadURL"), true) ? item.Value :
stripPrefix(item.Value, PREFIX_ITEM_URI);
return EM_L(id);
},
/**
* Get the em:updateable property - this specifies whether the item is
* allowed to be updated
@ -7832,11 +7883,8 @@ ExtensionsDataSource.prototype = {
this.getItemProperty(id, "appManaged") == "true")
return EM_L("false");
try {
if (!gPref.getBoolPref(PREF_EM_ITEM_UPDATE_ENABLED.replace(/%UUID%/, id)))
return EM_L("false");
}
catch (e) { }
if (getPref("getBoolPref", (PREF_EM_ITEM_UPDATE_ENABLED.replace(/%UUID%/, id), false)) == true)
return EM_L("false");
var installLocation = InstallLocations.get(this.getInstallLocationKey(id));
if (!installLocation || !installLocation.canAccess)
@ -7902,14 +7950,6 @@ ExtensionsDataSource.prototype = {
return values.length > 0 ? values : null;
},
/**
* Get the em:name property (name of the item - template builder calls
* GetTargets on this one for some reason).
*/
_rdfGets_name: function(item, property) {
return this._getLocalizablePropertyValues(item, property);
},
/**
* Get the em:contributor property (contributors to the extension)
*/
@ -7925,9 +7965,17 @@ ExtensionsDataSource.prototype = {
return null;
var ary = null;
var getter = "_rdfGets_" + stripPrefix(property.Value, PREFIX_NS_EM);
var propertyName = stripPrefix(property.Value, PREFIX_NS_EM);
var getter = "_rdfGets_" + propertyName;
if (getter in this)
ary = this[getter](source, property);
else {
// The template builder calls GetTargets when single value properties
// are used in a triple.
getter = "_rdfGet_" + propertyName;
if (getter in this)
ary = [ this[getter](source, property) ];
}
return ary ? new ArrayEnumerator(ary)
: this._inner.GetTargets(source, property, truthValue);
@ -7952,6 +8000,10 @@ ExtensionsDataSource.prototype = {
HasAssertion: function(source, property, target, truthValue) {
if (!source || !property || !target)
return false;
var getter = "_rdfGet_" + stripPrefix(property.Value, PREFIX_NS_EM);
if (getter in this)
return this[getter](source, property) == target;
return this._inner.HasAssertion(source, property, target, truthValue);
},
@ -8178,10 +8230,10 @@ function stackTraceFunctionFormat(aFunctionName) {
var classDelimiter = aFunctionName.indexOf("_");
var className = aFunctionName.substr(0, classDelimiter);
if (!className)
className == "<global>";
className = "<global>";
var functionName = aFunctionName.substr(classDelimiter + 1, aFunctionName.length);
if (!functionName)
functionName == "<anonymous>";
functionName = "<anonymous>";
return className + "::" + functionName;
}

View File

@ -1,161 +1,393 @@
#extensionManager {
padding: 0;
background-color: ThreeDFace;
}
richlistbox {
-moz-appearance: none !important;
margin: 0;
padding: 0;
}
#extensionsView[state="themes"] {
margin: 8px 8px 3px 8px;
border: 1px solid #bebebe;
}
#extensionsView[state="extensions"] {
margin-bottom: 1px;
border-bottom: 1px solid #bebebe;
}
/* Extension Manager Command Bar */
#commandBar {
padding: 5px 8px 6px 8px;
min-width: 1px;
}
#commandBar button {
-moz-appearance: button-bevel;
min-width: 1px;
padding: 3px 6px;
margin: 0;
}
.commandBarSeparator {
width: 6px;
#extensionsBox {
padding: 5px 10px 0 10px;
min-width:1px;
}
#getMore {
text-align: right;
}
/* Extension List Items */
extension[selected="true"] {
background-color: Highlight;
#resizerBox {
margin-top: -12px;
}
extension {
padding: 10px;
min-height: 25px;
border-bottom: 1px dashed #C0C0C0;
#resizerBox resizer {
height: 10px;
max-height: 10px;
}
/* Command Bar */
#commandBarBottom {
margin: 10px 10px 10px 10px;
min-width: 1px;
}
#commandBarBottom button {
margin: 0;
-moz-margin-end: 5px;
}
extension[odd] {
background-color: #F3F3F3;
/* List Items */
richlistitem {
padding-top: 6px;
padding-bottom: 6px;
-moz-padding-start: 7px;
-moz-padding-end: 7px;
min-height: 25px;
border-bottom: 1px dotted #C0C0C0;
}
.extension-icon {
list-style-image: url("chrome://mozapps/skin/extensions/extensionItem.png");
richlistitem[isDisabled="true"] .addonIcon {
opacity: 0.3;
}
extension[disabled="true"] {
richlistitem[isDisabled="true"] {
color: GrayText;
background-image: none;
}
extension[disabled="true"][compatible="false"] .extension-item-description,
extension[blocklisted="true"] .extension-item-description,
extension[satisfiesDependencies="false"] .extension-item-description,
extension[incompatibleUpdate="true"] .extension-item-description {
color: #C77173;
richlistitem[selected="true"] {
background-color: -moz-Dialog;
color: -moz-DialogText;
}
extension[disabled="true"][selected="true"] {
background-image: url("chrome://mozapps/skin/shared/itemSelected.png");
richlistbox[focused] richlistitem[selected="true"] {
background-color: Highlight;
color: HighlightText;
}
extension[disabled="true"] .extension-icon, extension[opType="needs-disable"] .extension-icon {
opacity: 0.5;
richlistbox[focused] richlistitem[selected="true"][isDisabled="true"] {
background-image: url("chrome://mozapps/skin/extensions/itemDisabledFader.png");
}
extension[opType="needs-uninstall"] .extension-icon {
opacity: 0.2;
.descriptionWrap {
margin-bottom: 2px;
}
.extension-item-name {
richlistitem[selected="true"][opType="none"] .descriptionCrop {
display: none;
}
.addonName {
font-weight: bold;
}
.extension-item-description, .extension-item-creator {
color: #505050;
}
.extension-icon {
margin-right: 10px;
.addonIcon {
-moz-margin-end: 2px;
}
.previewText {
font-size: larger;
font-weight: bold;
color: #999;
color: ThreeDShadow;
text-align: center;
}
extension[itemType="theme"] {
padding: 7px 5px 7px 6px;
#themePreviewArea {
-moz-appearance: listbox;
overflow: auto;
width: 0px;
}
extension[itemType="theme"] .extension-icon {
margin-right: 3px;
.addonIcon {
width: 32px;
max-width: 32px;
height: 32px;
max-height: 32px;
}
.themePreviewArea {
margin: 8px 8px 3px 0px !important;
padding: 5px 5px 0px 5px;
border: 3px solid transparent;
-moz-border-top-colors: #9b9b9b #c8c8c8 #e1e1e1 ;
-moz-border-right-colors: #c4c4c4 #e1e1e1 #e4e4e4;
-moz-border-bottom-colors: #d6d6d6 #e2e2e2 #e4e4e4;
-moz-border-left-colors: #c4c4c4 #e1e1e1 #e4e4e4;
background: url("chrome://global/skin/10pct_transparent_grey.png") repeat !important;
-moz-border-radius: 3px;
}
extension[availableUpdateURL="none"] .extension-badge,
extension .extension-details-link {
display: none;
}
extension[blocklisted="true"][blocklistDetailsURL][availableUpdateURL="none"] .extension-details-link {
display: -moz-box;
}
extension[loading="true"] .extension-badge {
display: -moz-box;
richlistitem .updateBadge,
richlistitem .notifyBadge {
width: 16px;
height: 16px;
margin-bottom: -3px;
-moz-margin-end: -2px;
list-style-image: url("chrome://global/skin/throbber/Throbber-small.gif") !important;
list-style-image: url("chrome://mozapps/skin/extensions/notifyBadges.png");
}
.extension-badge {
display: -moz-box;
width: 16px;
height: 16px;
margin-bottom: -3px;
-moz-margin-end: -2px;
list-style-image: url("chrome://mozapps/skin/update/update.png");
richlistitem .updateBadge {
-moz-image-region: rect(0px 16px 16px 0px);
}
richlistitem .notifyBadge {
-moz-image-region: rect(0px 48px 16px 32px);
}
.extension-install-button-box {
margin: 0px;
richlistitem .updateBadge,
richlistitem .notifyBadge {
margin-bottom: -3px;
}
.throbber {
richlistitem .updateBadge {
-moz-margin-end: -2px;
}
richlistitem .notifyBadge {
-moz-margin-start: -2px;
}
richlistitem[availableUpdateURL="none"] .updateBadge,
.notifyBadge {
display: none;
}
richlistitem[compatible="false"] .notifyBadge,
richlistitem[blocklisted="true"] .notifyBadge,
richlistitem[satisfiesDependencies="false"] .notifyBadge {
display: -moz-box;
}
/* Selected Add-on buttons */
.selectedButtons {
margin-top: 4px;
}
.selectedButtons button {
margin-top: 0;
margin-bottom: 0;
}
.optionsButton, .useThemeButton {
-moz-margin-end: 0;
}
.enableButton, .disableButton {
-moz-margin-start: 5px;
-moz-margin-end: 0;
}
.uninstallButton, .cancelUninstallButton {
-moz-margin-start: 5px;
}
.enableHide,
.uninstallShow,
richlistitem[isDisabled="true"] .disableHide {
display: none;
}
richlistitem[opType="needs-uninstall"] .uninstallShow,
richlistitem[opType="needs-enable"] .enableShow,
richlistitem[opType="needs-disable"] .disableShow,
richlistitem[isDisabled="true"] .disableShow {
display: -moz-box;
}
richlistitem[opType="needs-uninstall"] .uninstallHide,
richlistitem[opType="needs-enable"] .enableHide,
richlistitem[opType="needs-disable"] .disableHide {
display: none;
}
richlistitem[type="2"] .themeButton,
richlistitem[type="8"] .themeButton,
richlistitem[type="16"] .themeButton,
richlistitem[type="4"] .optionsButton,
richlistitem[type="8"] .optionsButton,
richlistitem[type="16"] .optionsButton,
richlistitem[type="4"] .disableShow,
richlistitem[type="4"] .disableHide {
display: none;
}
/* Selected Add-on status messages and images */
richlistitem[compatible="true"] .incompatibleBox,
richlistitem[satisfiesDependencies="true"] .needsDependenciesBox,
richlistitem[blocklisted="false"] .blocklistedBox,
richlistitem[opType="needs-uninstall"] .blocklistedBox,
richlistitem[opType="needs-uninstall"] .incompatibleBox,
richlistitem[opType="needs-uninstall"] .needsDependenciesBox,
richlistitem[opType="needs-uninstall"] .blocklistedBox {
display: none;
}
richlistitem[opType="needs-uninstall"] .updateAvailableBox,
richlistitem[availableUpdateURL="none"] .updateAvailableBox {
display: none;
}
richlistitem[loading="true"] .updateBadge {
display: -moz-box;
width: 16px;
height: 16px;
list-style-image: url("chrome://global/skin/throbber/Throbber-small.gif") !important;
margin-bottom: -3px;
-moz-margin-end: -2px;
list-style-image: url("chrome://global/skin/throbber/Throbber-small.gif");
-moz-image-region: auto;
}
.addonThrobber {
-moz-margin-start: 5px;
width: 16px;
height: 16px;
list-style-image: url("chrome://global/skin/throbber/Throbber-small.gif");
}
.selectedStatusMsgs hbox {
margin-top: 2px;
margin-bottom: 2px;
}
.selectedStatusMsgs label {
font-weight: bold;
}
.selectedStatusMsgs label.text-link {
font-weight: normal;
border: none;
}
.needsInstall, .needsUninstall, .needsEnable, .needsDisable {
display: none;
}
richlistitem[opType="needs-install"] .needsInstall,
richlistitem[opType="needs-uninstall"] .needsUninstall,
richlistitem[opType="needs-enable"] .needsEnable,
richlistitem[opType="needs-disable"] .needsDisable {
display: -moz-box;
}
richlistitem[opType="needs-uninstall"] .updateBadge,
richlistitem[opType="needs-uninstall"] .notifyBadge {
display: none;
}
#progressBox {
padding: 5px 5px 5px 5px;
}
#topStackBar {
margin-bottom: 5px;
}
/* View buttons */
.viewSelector {
padding: 0 5px;
border-bottom: 1px solid #a3a3a3;
background: url("chrome://global/skin/toolbar/toolbar-pinstripe-overlay.png") repeat;
margin: 0;
}
#viewGroup radio {
border-right: 1px solid transparent;
border-left: 1px solid transparent;
padding: 3px 0 3px 0;
margin: 0;
-moz-appearance: none !important;
list-style-image: url("chrome://mozapps/skin/extensions/viewButtons.png");
}
#viewGroup radio[selected="true"] {
background-color: #DDDDDD;
background-image: none;
border-right: 1px solid #b9b9b9;
border-left: 1px solid #b9b9b9;
color: ButtonText !important;
}
.viewButtonIcon {
width: 32px;
height: 32px;
}
radio#extensions-view {
-moz-image-region: rect(0px, 32px, 32px, 0px)
}
radio#extensions-view:hover, radio#extensions-view[selected="true"] {
-moz-image-region: rect(32px, 32px, 64px, 0px)
}
radio#themes-view {
-moz-image-region: rect(0px, 64px, 32px, 32px)
}
radio#themes-view:hover, radio#themes-view[selected="true"] {
-moz-image-region: rect(32px, 64px, 64px, 32px)
}
radio#locales-view {
-moz-image-region: rect(0px, 96px, 32px, 64px)
}
radio#locales-view:hover, radio#locales-view[selected="true"] {
-moz-image-region: rect(32px, 96px, 64px, 64px)
}
radio#plugins-view {
-moz-image-region: rect(0px, 128px, 32px, 96px)
}
radio#plugins-view:hover, radio#plugins-view[selected="true"] {
-moz-image-region: rect(32px, 128px, 64px, 96px)
}
radio#updates-view {
-moz-image-region: rect(0px, 160px, 32px, 128px)
}
radio#updates-view:hover, radio#updates-view[selected="true"] {
-moz-image-region: rect(32px, 160px, 64px, 128px)
}
radio#installs-view {
-moz-image-region: rect(0px, 192px, 32px, 160px)
}
radio#installs-view:hover, radio#installs-view[selected="true"] {
-moz-image-region: rect(32px, 192px, 64px, 160px)
}
/* Update view checkbox */
.includeUpdate {
-moz-user-focus: none;
}
richlistitem[selected="true"] .includeUpdate {
-moz-user-focus: normal;
}
/* Notifcation Bar */
addonsmessage {
background-color: #E6E6E6;
border: 1px solid #C8C8C8;
-moz-border-radius: 7px;
margin: 0 10px 0 10px;
padding: 4px;
font: icon;
color: #505050;
}
.messageImage {
margin: 0px 6px 0px 2px;
}
.messageText {
margin: 0px 0px 0px 1px;
}
.messageButton {
font-weight: normal;
color: #000;
margin: 0px 4px 0px 8px;
}
.addonsmessage-close-button {
list-style-image: url("chrome://global/skin/icons/closetab.png") !important;
list-style-image: none;
border: none;
}
.addonsmessage-close-button:hover > .toolbarbutton-icon {
background-image: none !important;
}
.addonsmessage-close-button:hover:active {
list-style-image: url("chrome://global/skin/icons/closetab-active.png") !important;
}
.addonsmessage-close-button > .toolbarbutton-text {
display: none;
}
.addonsmessage-spacer {
width: 3px;
border-bottom-width: 0px;
}

View File

@ -10,7 +10,12 @@ classic.jar:
skin/classic/mozapps/downloads/unknownContentType.css (downloads/unknownContentType.css)
skin/classic/mozapps/downloads/downloads.xml (downloads/downloads.xml)
skin/classic/mozapps/extensions/extensionItem.png (extensions/extensionItem.png)
skin/classic/mozapps/extensions/itemDisabledFader.png (extensions/itemDisabledFader.png)
skin/classic/mozapps/extensions/itemEnabledFader.png (extensions/itemEnabledFader.png)
skin/classic/mozapps/extensions/notifyBadges.png (extensions/notifyBadges.png)
skin/classic/mozapps/extensions/question.png (extensions/question.png)
skin/classic/mozapps/extensions/themeGeneric.png (extensions/themeGeneric.png)
skin/classic/mozapps/extensions/viewButtons.png (extensions/viewButtons.png)
skin/classic/mozapps/extensions/about.css (extensions/about.css)
skin/classic/mozapps/extensions/extensions.css (extensions/extensions.css)
skin/classic/mozapps/extensions/update.css (extensions/update.css)

View File

@ -2,117 +2,113 @@
background-color: ThreeDFace;
}
/* Extension Manager Command Bar */
#commandBar {
padding: 0px 10px 5px 10px;
min-width: 1px;
}
#uninstallButton {
margin: 0px;
list-style-image: url("chrome://mozapps/skin/extensions/actionbuttons.png");
-moz-image-region: rect(0px, 21px, 21px, 0px) !important;
}
#uninstallButton[disabled="true"] {
list-style-image: url("chrome://mozapps/skin/extensions/actionbuttons.png");
-moz-image-region: rect(21px, 21px, 42px, 0px) !important;
}
#updateButton {
margin: 0px;
list-style-image: url("chrome://mozapps/skin/extensions/actionbuttons.png");
-moz-image-region: rect(0px, 42px, 21px, 21px) !important;
}
#updateButton[disabled="true"] {
list-style-image: url("chrome://mozapps/skin/extensions/actionbuttons.png");
-moz-image-region: rect(21px, 42px, 42px, 21px) !important;
}
#optionsButton {
margin: 0px;
list-style-image: url("chrome://mozapps/skin/extensions/actionbuttons.png");
-moz-image-region: rect(0px, 84px, 21px, 63px) !important;
}
#optionsButton[disabled="true"] {
list-style-image: url("chrome://mozapps/skin/extensions/actionbuttons.png");
-moz-image-region: rect(21px, 84px, 42px, 63px) !important;
}
#useThemeButton {
margin: 0px;
list-style-image: url("chrome://mozapps/skin/extensions/actionbuttons.png");
-moz-image-region: rect(0px, 63px, 21px, 42px) !important;
}
#useThemeButton[disabled="true"] {
list-style-image: url("chrome://mozapps/skin/extensions/actionbuttons.png");
-moz-image-region: rect(21px, 63px, 42px, 42px) !important;
}
#uninstallButton .button-icon,
#updateButton .button-icon,
#optionsButton .button-icon,
#useThemeButton .button-icon {
margin-top: 0px !important;
margin-bottom: 0px !important;
-moz-margin-start: 0px !important;
-moz-margin-end: 5px !important;
}
.commandBarSeparator {
-moz-margin-start: 5px;
#extensionsBox {
margin: 10px 10px 0px 10px;
min-width:1px;
}
#getMore {
text-align: right;
}
richlistbox {
#resizerBox {
margin-top: -12px;
}
#resizerBox resizer {
height: 10px;
max-height: 10px;
}
/* Command Bar */
#commandBarBottom {
margin: 10px 10px 5px 10px;
min-width: 1px;
}
/* Extension List Items */
extension[selected="true"] {
background-image: url("chrome://mozapps/skin/shared/itemSelected.png");
#commandBarBottom button {
margin: 0;
list-style-image: url("chrome://mozapps/skin/extensions/actionbuttons.png");
-moz-margin-end: 5px;
}
extension {
padding-top: 7px;
padding-bottom: 7px;
#commandBarBottom button .button-icon {
margin-top: 0px;
margin-bottom: 0px;
-moz-margin-start: 0px;
-moz-margin-end: 5px;
}
#installFileButton, #installUpdatesAllButton {
-moz-image-region: rect(0px, 84px, 21px, 63px);
}
#installFileButton[disabled="true"],
#installUpdatesAllButton[disabled="true"] {
-moz-image-region: rect(21px, 84px, 42px, 63px);
}
#checkUpdatesAllButton {
-moz-image-region: rect(0px, 63px, 21px, 42px);
}
#checkUpdatesAllButton[disabled="true"] {
-moz-image-region: rect(21px, 63px, 42px, 42px);
}
#restartAppButton {
-moz-image-region: rect(0px, 42px, 21px, 21px);
}
#restartAppButton[disabled="true"] {
-moz-image-region: rect(21px, 42px, 42px, 21px);
}
/* List Items */
richlistitem {
padding-top: 6px;
padding-bottom: 6px;
-moz-padding-start: 7px;
-moz-padding-end: 7px;
min-height: 25px;
border-bottom: 1px dotted #C0C0C0;
}
extension[disabled="true"] {
color: GrayText;
background-image: none;
}
extension[disabled="true"][compatible="false"] .extension-item-description,
extension[blocklisted="true"] .extension-item-description,
extension[satisfiesDependencies="false"] .extension-item-description,
extension[incompatibleUpdate="true"] .extension-item-description {
color: #C77173;
}
extension[disabled="true"][selected="true"] {
background-image: url("chrome://mozapps/skin/shared/itemSelected.png");
}
extension[disabled="true"] .extension-icon {
richlistitem[isDisabled="true"] .addonIcon {
opacity: 0.3;
}
.extension-item-name {
richlistitem[isDisabled="true"] {
color: GrayText;
}
richlistitem[selected="true"] {
background-color: -moz-Dialog;
color: -moz-DialogText;
}
richlistbox[focused] richlistitem[selected="true"] {
background-image: url("chrome://mozapps/skin/extensions/itemEnabledFader.png");
background-color: Highlight;
color: HighlightText;
}
richlistbox[focused] richlistitem[selected="true"][isDisabled="true"] {
background-image: url("chrome://mozapps/skin/extensions/itemDisabledFader.png");
}
.descriptionWrap {
margin-bottom: 2px;
}
richlistitem[selected="true"][opType="none"] .descriptionCrop {
display: none;
}
.addonName {
font-weight: bold;
}
.extension-icon {
.addonIcon {
-moz-margin-end: 2px;
}
@ -123,60 +119,310 @@ extension[disabled="true"] .extension-icon {
text-align: center;
}
extension[itemType="theme"] {
padding-top: 7px;
padding-bottom: 7px;
-moz-padding-start: 6px;
-moz-padding-end: 5px;
}
extension[itemType="theme"] .extension-icon {
-moz-margin-end: 3px;
}
.themePreviewArea {
#themePreviewArea {
-moz-appearance: listbox;
margin-top: 10px;
margin-bottom: 5px;
-moz-margin-start: 5px;
-moz-margin-end: 10px;
overflow: auto;
width: 0px;
}
extension[availableUpdateURL="none"] .extension-badge,
extension .extension-details-link {
display: none;
.addonIcon {
width: 32px;
max-width: 32px;
height: 32px;
max-height: 32px;
}
extension[blocklisted="true"][blocklistDetailsURL][availableUpdateURL="none"] .extension-details-link {
display: -moz-box;
}
extension[loading="true"] .extension-badge {
display: -moz-box;
richlistitem .updateBadge,
richlistitem .notifyBadge {
width: 16px;
height: 16px;
margin-bottom: -3px;
-moz-margin-end: -2px;
list-style-image: url("chrome://global/skin/throbber/Throbber-small.gif") !important;
list-style-image: url("chrome://mozapps/skin/extensions/notifyBadges.png");
}
.extension-badge {
display: -moz-box;
width: 16px;
height: 16px;
margin-bottom: -3px;
-moz-margin-end: -2px;
list-style-image: url("chrome://mozapps/skin/update/extensionalert.png");
richlistitem .updateBadge {
-moz-image-region: rect(0px 16px 16px 0px);
}
richlistitem .notifyBadge {
-moz-image-region: rect(0px 48px 16px 32px);
}
.extension-install-button-box {
margin: 0px;
richlistitem .updateBadge,
richlistitem .notifyBadge {
margin-bottom: -3px;
}
.throbber {
richlistitem .updateBadge {
-moz-margin-end: -2px;
}
richlistitem .notifyBadge {
-moz-margin-start: -2px;
}
richlistitem[availableUpdateURL="none"] .updateBadge,
.notifyBadge {
display: none;
}
richlistitem[compatible="false"] .notifyBadge,
richlistitem[blocklisted="true"] .notifyBadge,
richlistitem[satisfiesDependencies="false"] .notifyBadge {
display: -moz-box;
}
/* Selected Add-on buttons */
.selectedButtons {
margin-top: 4px;
}
.selectedButtons button {
margin-top: 0;
margin-bottom: 0;
}
.optionsButton, .useThemeButton {
-moz-margin-end: 0;
}
.enableButton, .disableButton {
-moz-margin-start: 5px;
-moz-margin-end: 0;
}
.uninstallButton, .cancelUninstallButton {
-moz-margin-start: 5px;
}
.enableHide,
.uninstallShow,
richlistitem[isDisabled="true"] .disableHide {
display: none;
}
richlistitem[opType="needs-uninstall"] .uninstallShow,
richlistitem[opType="needs-enable"] .enableShow,
richlistitem[opType="needs-disable"] .disableShow,
richlistitem[isDisabled="true"] .disableShow {
display: -moz-box;
}
richlistitem[opType="needs-uninstall"] .uninstallHide,
richlistitem[opType="needs-enable"] .enableHide,
richlistitem[opType="needs-disable"] .disableHide {
display: none;
}
richlistitem[type="2"] .themeButton,
richlistitem[type="8"] .themeButton,
richlistitem[type="16"] .themeButton,
richlistitem[type="4"] .optionsButton,
richlistitem[type="8"] .optionsButton,
richlistitem[type="16"] .optionsButton,
richlistitem[type="4"] .disableShow,
richlistitem[type="4"] .disableHide {
display: none;
}
/* Selected Add-on status messages and images */
richlistitem[compatible="true"] .incompatibleBox,
richlistitem[satisfiesDependencies="true"] .needsDependenciesBox,
richlistitem[blocklisted="false"] .blocklistedBox,
richlistitem[opType="needs-uninstall"] .blocklistedBox,
richlistitem[opType="needs-uninstall"] .incompatibleBox,
richlistitem[opType="needs-uninstall"] .needsDependenciesBox,
richlistitem[opType="needs-uninstall"] .blocklistedBox {
display: none;
}
richlistitem[opType="needs-uninstall"] .updateAvailableBox,
richlistitem[availableUpdateURL="none"] .updateAvailableBox {
display: none;
}
richlistitem[loading="true"] .updateBadge {
display: -moz-box;
width: 16px;
height: 16px;
list-style-image: url("chrome://global/skin/throbber/Throbber-small.gif") !important;
margin-bottom: -3px;
-moz-margin-end: -2px;
list-style-image: url("chrome://global/skin/throbber/Throbber-small.gif");
-moz-image-region: auto;
}
.addonThrobber {
-moz-margin-start: 5px;
width: 16px;
height: 16px;
list-style-image: url("chrome://global/skin/throbber/Throbber-small.gif");
}
.selectedStatusMsgs hbox {
margin-top: 2px;
margin-bottom: 2px;
}
.selectedStatusMsgs label {
font-weight: bold;
}
.selectedStatusMsgs label.text-link {
font-weight: normal;
border: none;
}
.needsInstall, .needsUninstall, .needsEnable, .needsDisable {
display: none;
}
richlistitem[opType="needs-install"] .needsInstall,
richlistitem[opType="needs-uninstall"] .needsUninstall,
richlistitem[opType="needs-enable"] .needsEnable,
richlistitem[opType="needs-disable"] .needsDisable {
display: -moz-box;
}
richlistitem[opType="needs-uninstall"] .updateBadge,
richlistitem[opType="needs-uninstall"] .notifyBadge {
display: none;
}
#progressBox {
padding: 5px 5px 5px 5px;
}
/* View buttons */
.viewSelector {
border-bottom: 2px groove ThreeDFace;
margin: 0px;
-moz-padding-start: 10px;
background-color: -moz-Field;
color: -moz-FieldText;
}
#viewGroup radio {
-moz-appearance: none;
margin: 0px 1px 0px 1px;
padding: 1px 3px 1px 3px;
min-width: 4.5em;
list-style-image: url("chrome://mozapps/skin/extensions/viewButtons.png");
}
#viewGroup radio:hover {
background-color: #E0E8F6;
color: black;
}
#viewGroup radio[selected="true"] {
background-color: #C1D2EE;
color: black;
}
.viewButtonIcon {
width: 32px;
height: 32px;
}
radio#extensions-view {
-moz-image-region: rect(0px, 32px, 32px, 0px)
}
radio#extensions-view:hover, radio#extensions-view[selected="true"] {
-moz-image-region: rect(32px, 32px, 64px, 0px)
}
radio#themes-view {
-moz-image-region: rect(0px, 64px, 32px, 32px)
}
radio#themes-view:hover, radio#themes-view[selected="true"] {
-moz-image-region: rect(32px, 64px, 64px, 32px)
}
radio#locales-view {
-moz-image-region: rect(0px, 96px, 32px, 64px)
}
radio#locales-view:hover, radio#locales-view[selected="true"] {
-moz-image-region: rect(32px, 96px, 64px, 64px)
}
radio#plugins-view {
-moz-image-region: rect(0px, 128px, 32px, 96px)
}
radio#plugins-view:hover, radio#plugins-view[selected="true"] {
-moz-image-region: rect(32px, 128px, 64px, 96px)
}
radio#updates-view {
-moz-image-region: rect(0px, 160px, 32px, 128px)
}
radio#updates-view:hover, radio#updates-view[selected="true"] {
-moz-image-region: rect(32px, 160px, 64px, 128px)
}
radio#installs-view {
-moz-image-region: rect(0px, 192px, 32px, 160px)
}
radio#installs-view:hover, radio#installs-view[selected="true"] {
-moz-image-region: rect(32px, 192px, 64px, 160px)
}
/* Update view checkbox */
.includeUpdate {
-moz-user-focus: none;
}
richlistitem[selected="true"] .includeUpdate {
-moz-user-focus: normal;
}
/* Notifcation Bar */
addonsmessage {
background-color: InfoBackground;
border-bottom: 1px solid ThreeDDarkShadow;
color: InfoText;
padding: 3px;
}
.messageImage {
width: 16px;
height: 16px;
border: 1px solid transparent;
}
.messageText {
-moz-margin-start: 5px;
}
.messageButton {
margin: 0px 5px 0px 5px;
}
.addonsmessage-close-button > .toolbarbutton-icon {
-moz-margin-end: 0px !important;
}
.addonsmessage-close-button {
list-style-image: url("chrome://global/skin/icons/close.png");
-moz-appearance: none;
-moz-image-region: rect(0px, 16px, 16px, 0px);
-moz-margin-start: 2px;
margin-top: 0px;
border: none !important;
padding: 0px;
opacity: 1.0;
}
.addonsmessage-close-button:hover {
-moz-image-region: rect(0px, 32px, 16px, 16px);
opacity: 1.0;
}
.addonsmessage-close-button:hover:active {
-moz-image-region: rect(0px, 48px, 16px, 32px);
opacity: 1.0;
}
.addonsmessage-spacer {
width: 3px;
border-bottom-width: 0px;
}

View File

@ -12,8 +12,13 @@ classic.jar:
skin/classic/mozapps/extensions/about.css (extensions/about.css)
skin/classic/mozapps/extensions/actionbuttons.png (extensions/actionbuttons.png)
skin/classic/mozapps/extensions/extensions.css (extensions/extensions.css)
skin/classic/mozapps/extensions/itemDisabledFader.png (extensions/itemDisabledFader.png)
skin/classic/mozapps/extensions/itemEnabledFader.png (extensions/itemEnabledFader.png)
skin/classic/mozapps/extensions/notifyBadges.png (extensions/notifyBadges.png)
skin/classic/mozapps/extensions/question.png (extensions/question.png)
skin/classic/mozapps/extensions/update.css (extensions/update.css)
skin/classic/mozapps/extensions/themeGeneric.png (extensions/themeGeneric.png)
skin/classic/mozapps/extensions/viewButtons.png (extensions/viewButtons.png)
skin/classic/mozapps/plugins/missingPlugin.css (plugins/missingPlugin.css)
skin/classic/mozapps/plugins/pluginInstallerWizard.css (plugins/pluginInstallerWizard.css)
skin/classic/mozapps/profile/profileicon.png (profile/profileicon.png)

View File

@ -55,8 +55,8 @@ pref("intl.charset.default", "chrome://global-platform/locale/intl.properties")
pref("intl.menuitems.alwaysappendaccesskeys","chrome://global/locale/intl.properties");
pref("intl.menuitems.insertseparatorbeforeaccesskeys","chrome://global/locale/intl.properties");
pref("xpinstall.dialog.confirm", "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul");
pref("xpinstall.dialog.progress.chrome", "chrome://mozapps/content/extensions/extensions.xul?type=extensions");
pref("xpinstall.dialog.progress.skin", "chrome://mozapps/content/extensions/extensions.xul?type=themes");
pref("xpinstall.dialog.progress.type.chrome", "Extension:Manager-extensions");
pref("xpinstall.dialog.progress.type.skin", "Extension:Manager-themes");
pref("xpinstall.dialog.progress.chrome", "chrome://mozapps/content/extensions/extensions.xul?view=installs");
pref("xpinstall.dialog.progress.skin", "chrome://mozapps/content/extensions/extensions.xul?view=installs");
pref("xpinstall.dialog.progress.type.chrome", "Extension:Manager");
pref("xpinstall.dialog.progress.type.skin", "Extension:Manager");
pref("xpinstall.enabled", true);