Bug 297903: Extension updates should link to further information. r=robstrong

This commit is contained in:
dtownsend@oxymoronical.com 2007-09-05 18:20:11 -07:00
Родитель a53939f649
Коммит f3b6251d9f
9 изменённых файлов: 340 добавлений и 27 удалений

Просмотреть файл

@ -76,6 +76,12 @@
<!ENTITY cmd.installUpdate.label "Install Update"> <!ENTITY cmd.installUpdate.label "Install Update">
<!ENTITY cmd.installUpdate.accesskey "I"> <!ENTITY cmd.installUpdate.accesskey "I">
<!ENTITY cmd.installUpdate.tooltip "Install an update for this Add-on"> <!ENTITY cmd.installUpdate.tooltip "Install an update for this Add-on">
<!ENTITY cmd.showUpdateInfo.label "Show Information">
<!ENTITY cmd.showUpdateInfo.accesskey "S">
<!ENTITY cmd.showUpdateInfo.tooltip "Show more information about these updates">
<!ENTITY cmd.hideUpdateInfo.label "Hide Information">
<!ENTITY cmd.hideUpdateInfo.accesskey "H">
<!ENTITY cmd.hideUpdateInfo.tooltip "Hide information about these updates">
<!-- The selected add-on's cancel action button label --> <!-- The selected add-on's cancel action button label -->
<!ENTITY cancel.label "Cancel"> <!ENTITY cancel.label "Cancel">
<!ENTITY cancel.accesskey "C"> <!ENTITY cancel.accesskey "C">
@ -114,6 +120,9 @@
<!ENTITY previewNoThemeSelected.label "No Theme Selected"> <!ENTITY previewNoThemeSelected.label "No Theme Selected">
<!ENTITY previewNoPreviewImage.label "This Theme does not have a Preview Image"> <!ENTITY previewNoPreviewImage.label "This Theme does not have a Preview Image">
<!ENTITY moreInfo.label "More Information"> <!ENTITY moreInfo.label "More Information">
<!ENTITY infoNoAddonSelected.label "No Update Selected">
<!ENTITY infoNoUpdateInfo.label "This update does not have any additional information">
<!ENTITY infoUpdateInfoError.label "There was an error loading the information about this update">
<!ENTITY updateSuccess.label "Update completed successfully."> <!ENTITY updateSuccess.label "Update completed successfully.">
<!ENTITY installSuccess.label "Install completed successfully."> <!ENTITY installSuccess.label "Install completed successfully.">

Просмотреть файл

@ -22,7 +22,8 @@
# Ben Goodger <ben@mozilla.org> # Ben Goodger <ben@mozilla.org>
# Robert Strong <robert.bugzilla@gmail.com> # Robert Strong <robert.bugzilla@gmail.com>
# Dão Gottwald <dao@design-noir.de> # Dão Gottwald <dao@design-noir.de>
# # Dave Townsend <dtownsend@oxymoronical.com>
#
# Alternatively, the contents of this file may be used under the terms of # 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 # either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
@ -78,10 +79,11 @@ const PREF_EM_LAST_SELECTED_SKIN = "extensions.lastSelectedSkin";
const PREF_GENERAL_SKINS_SELECTEDSKIN = "general.skins.selectedSkin"; const PREF_GENERAL_SKINS_SELECTEDSKIN = "general.skins.selectedSkin";
const PREF_UPDATE_NOTIFYUSER = "extensions.update.notifyUser"; const PREF_UPDATE_NOTIFYUSER = "extensions.update.notifyUser";
const RDFURI_ITEM_ROOT = "urn:mozilla:item:root"; const RDFURI_ITEM_ROOT = "urn:mozilla:item:root";
const PREFIX_ITEM_URI = "urn:mozilla:item:"; const PREFIX_ITEM_URI = "urn:mozilla:item:";
const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#"; const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#";
const kXULNSURI = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; const kXULNSURI = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const XMLURI_PARSE_ERROR = "http://www.mozilla.org/newlayout/xml/parsererror.xml"
const OP_NONE = ""; const OP_NONE = "";
const OP_NEEDS_INSTALL = "needs-install"; const OP_NEEDS_INSTALL = "needs-install";
@ -315,6 +317,7 @@ function showView(aView) {
bindingList = [ ["aboutURL", "?aboutURL"], bindingList = [ ["aboutURL", "?aboutURL"],
["availableUpdateURL", "?availableUpdateURL"], ["availableUpdateURL", "?availableUpdateURL"],
["availableUpdateVersion", "?availableUpdateVersion"], ["availableUpdateVersion", "?availableUpdateVersion"],
["availableUpdateInfo", "?availableUpdateInfo"],
["blocklisted", "?blocklisted"], ["blocklisted", "?blocklisted"],
["homepageURL", "?homepageURL"], ["homepageURL", "?homepageURL"],
["iconURL", "?iconURL"], ["iconURL", "?iconURL"],
@ -406,6 +409,8 @@ function showView(aView) {
document.getElementById("continueDialogButton").hidden = !showContinue; document.getElementById("continueDialogButton").hidden = !showContinue;
document.getElementById("themePreviewArea").hidden = !isThemes; document.getElementById("themePreviewArea").hidden = !isThemes;
document.getElementById("themeSplitter").hidden = !isThemes; document.getElementById("themeSplitter").hidden = !isThemes;
document.getElementById("showUpdateInfoButton").hidden = aView != "updates";
document.getElementById("hideUpdateInfoButton").hidden = true;
AddonsViewBuilder.updateView(types, "richlistitem", bindingList, null); AddonsViewBuilder.updateView(types, "richlistitem", bindingList, null);
@ -1111,24 +1116,146 @@ function onAddonSelect(aEvent)
if (!document.getElementById("themePreviewArea").hidden) { if (!document.getElementById("themePreviewArea").hidden) {
var previewImageDeck = document.getElementById("previewImageDeck"); var previewImageDeck = document.getElementById("previewImageDeck");
var previewImage = document.getElementById("previewImage"); if (gView == "themes") {
if (!gExtensionsView.selectedItem) { var previewImage = document.getElementById("previewImage");
previewImageDeck.setAttribute("selectedIndex", "0"); if (!gExtensionsView.selectedItem) {
if (previewImage.hasAttribute("src")) previewImageDeck.selectedIndex = 0;
previewImage.removeAttribute("src");
}
else {
var url = gExtensionsView.selectedItem.getAttribute("previewImage");
if (url) {
previewImageDeck.setAttribute("selectedIndex", "2");
previewImage.setAttribute("src", url);
}
else {
previewImageDeck.setAttribute("selectedIndex", "1");
if (previewImage.hasAttribute("src")) if (previewImage.hasAttribute("src"))
previewImage.removeAttribute("src"); previewImage.removeAttribute("src");
} }
else {
var url = gExtensionsView.selectedItem.getAttribute("previewImage");
if (url) {
previewImageDeck.selectedIndex = 2;
previewImage.setAttribute("src", url);
}
else {
previewImageDeck.selectedIndex = 1;
if (previewImage.hasAttribute("src"))
previewImage.removeAttribute("src");
}
}
} }
else if (gView == "updates") {
UpdateInfoLoader.cancelLoad();
if (!gExtensionsView.selectedItem)
previewImageDeck.selectedIndex = 3;
else if (!gExtensionsView.selectedItem.hasAttribute("availableUpdateInfo"))
previewImageDeck.selectedIndex = 4;
else
UpdateInfoLoader.loadInfo(gExtensionsView.selectedItem.getAttribute("availableUpdateInfo"));
}
}
}
/**
* Manages the retrieval of update information and the xsl stylesheet
* used to format the inforation into chrome.
*/
var UpdateInfoLoader = {
_stylesheet: null,
_styleRequest: null,
_infoDocument: null,
_infoRequest: null,
// Called once both stylesheet and info requests have completed
displayInfo: function()
{
var processor = Components.classes["@mozilla.org/document-transformer;1?type=xslt"]
.createInstance(Components.interfaces.nsIXSLTProcessor);
processor.flags |= Components.interfaces.nsIXSLTProcessorPrivate.DISABLE_ALL_LOADS;
processor.importStylesheet(this._stylesheet);
var fragment = processor.transformToFragment(this._infoDocument, document);
document.getElementById("infoDisplay").appendChild(fragment);
document.getElementById("previewImageDeck").selectedIndex = 7;
},
onStylesheetLoaded: function(event)
{
var request = event.target;
this._styleRequest = null;
this._stylesheet = request.responseXML;
if (!this._stylesheet ||
this._stylesheet.documentElement.namespaceURI == XMLURI_PARSE_ERROR ||
(request.status != 200 && request.status != 0)) {
// The stylesheet load failing is a bad sign
document.getElementById("previewImageDeck").selectedIndex = 6;
return;
}
if (this._infoDocument)
this.displayInfo();
},
onInfoLoaded: function(event)
{
var request = event.target;
this._infoRequest = null;
this._infoDocument = request.responseXML;
if (!this._infoDocument ||
this._infoDocument.documentElement.namespaceURI == XMLURI_PARSE_ERROR ||
(request.status != 200 && request.status != 0)) {
// Should attempt to parse request.responseText with the html parser
document.getElementById("previewImageDeck").selectedIndex = 6;
return;
}
if (this._stylesheet)
this.displayInfo();
},
onError: function(event)
{
if (event.request == this._infoRequest)
this._infoRequest = null;
else // Means the stylesheet load has failed which is pretty bad news
this.cancelRequest();
document.getElementById("previewImageDeck").selectedIndex = 6;
},
loadInfo: function(url)
{
this.cancelLoad();
this._infoDocument = null;
document.getElementById("previewImageDeck").selectedIndex = 5;
var display = document.getElementById("infoDisplay");
while (display.lastChild)
display.removeChild(display.lastChild);
this._infoRequest = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Components.interfaces.nsIXMLHttpRequest);
this._infoRequest.open("GET", url, true);
var self = this;
this._infoRequest.onerror = function(event) { self.onError(event); };
this._infoRequest.onload = function(event) { self.onInfoLoaded(event); };
this._infoRequest.send(null);
// We may have the stylesheet cached from a previous load, or may still be
// loading it.
if (this._stylesheet || this._styleRequest)
return;
this._styleRequest = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Components.interfaces.nsIXMLHttpRequest);
this._styleRequest.open("GET", "chrome://mozapps/content/extensions/updateinfo.xsl", true);
this._styleRequest.overrideMimeType("text/xml");
this._styleRequest.onerror = function(event) { self.onError(event); };
this._styleRequest.onload = function(event) { self.onStylesheetLoaded(event); };
this._styleRequest.send(null);
},
cancelLoad: function()
{
// Leave the stylesheet loader running, there's a good chance we'll need it
if (this._infoRequest)
this._infoRequest.abort();
this._infoRequest = null;
} }
} }
@ -1531,6 +1658,24 @@ function updateGlobalCommands() {
setElementDisabledByID("cmd_installFile", disableInstallFile); setElementDisabledByID("cmd_installFile", disableInstallFile);
} }
function showUpdateInfo()
{
document.getElementById("themePreviewArea").hidden = false;
document.getElementById("themeSplitter").hidden = false;
document.getElementById("showUpdateInfoButton").hidden = true;
document.getElementById("hideUpdateInfoButton").hidden = false;
onAddonSelect();
}
function hideUpdateInfo()
{
UpdateInfoLoader.cancelLoad();
document.getElementById("themePreviewArea").hidden = true;
document.getElementById("themeSplitter").hidden = true;
document.getElementById("showUpdateInfoButton").hidden = false;
document.getElementById("hideUpdateInfoButton").hidden = true;
}
function checkUpdatesAll() { function checkUpdatesAll() {
if (isOffline("offlineUpdateMsg")) if (isOffline("offlineUpdateMsg"))
return; return;

Просмотреть файл

@ -481,12 +481,12 @@
<xul:hbox> <xul:hbox>
<xul:description xbl:inherits="value=updateAvailableMsg" flex="1" crop="end"/> <xul:description xbl:inherits="value=updateAvailableMsg" flex="1" crop="end"/>
</xul:hbox> </xul:hbox>
<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:vbox> </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> </xul:hbox>
</content> </content>

Просмотреть файл

@ -110,6 +110,8 @@
<command id="cmd_restartApp" oncommand="restartApp();"/> <command id="cmd_restartApp" oncommand="restartApp();"/>
<command id="cmd_continue" oncommand="closeEM();" disabled="true"/> <command id="cmd_continue" oncommand="closeEM();" disabled="true"/>
<command id="cmd_close" oncommand="closeEM();"/> <command id="cmd_close" oncommand="closeEM();"/>
<command id="cmd_showUpdateInfo" oncommand="showUpdateInfo();"/>
<command id="cmd_hideUpdateInfo" oncommand="hideUpdateInfo();"/>
</commandset> </commandset>
<vbox id="addonContextMenuPalette" hidden="true"> <vbox id="addonContextMenuPalette" hidden="true">
@ -193,6 +195,20 @@
<image id="previewImage"/> <image id="previewImage"/>
</description> </description>
</vbox> </vbox>
<vbox id="infoNoAddonSelected" align="center" pack="center">
<label class="previewText">&infoNoAddonSelected.label;</label>
</vbox>
<vbox id="infoNoUpdateInfo" align="center" pack="center">
<label class="previewText">&infoNoUpdateInfo.label;</label>
</vbox>
<vbox id="infoLoadingInfo" align="center" pack="center">
<image class="addonThrobber"/>
</vbox>
<vbox id="infoUpdateInfoError" align="center" pack="center">
<label class="previewText">&infoUpdateInfoError.label;</label>
</vbox>
<vbox id="infoDisplay">
</vbox>
</deck> </deck>
</vbox> </vbox>
</hbox> </hbox>
@ -208,6 +224,14 @@
accesskey="&cmd.installUpdatesAll.accesskey;" accesskey="&cmd.installUpdatesAll.accesskey;"
tooltiptext="&cmd.installUpdatesAll.tooltip;" tooltiptext="&cmd.installUpdatesAll.tooltip;"
command="cmd_installUpdatesAll"/> command="cmd_installUpdatesAll"/>
<button id="showUpdateInfoButton" label="&cmd.showUpdateInfo.label;"
accesskey="&cmd.showUpdateInfo.accesskey;"
tooltiptext="&cmd.showUpdateInfo.tooltip;"
command="cmd_showUpdateInfo"/>
<button id="hideUpdateInfoButton" label="&cmd.hideUpdateInfo.label;"
accesskey="&cmd.hideUpdateInfo.accesskey;"
tooltiptext="&cmd.hideUpdateInfo.tooltip;"
command="cmd_hideUpdateInfo"/>
<button id="checkUpdatesAllButton" label="&cmd.checkUpdatesAll.label;" <button id="checkUpdatesAllButton" label="&cmd.checkUpdatesAll.label;"
accesskey="&cmd.checkUpdatesAll.accesskey;" accesskey="&cmd.checkUpdatesAll.accesskey;"
tooltiptextaddons="&cmd.checkUpdatesAllAddon.tooltip;" tooltiptextaddons="&cmd.checkUpdatesAllAddon.tooltip;"

Просмотреть файл

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="text()">
</xsl:template>
<xsl:template match="text()" mode="list">
</xsl:template>
<xsl:template match="text()" mode="text">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="xhtml:script" mode="text">
</xsl:template>
<xsl:template match="xhtml:b|xhtml:i|xhtml:em|xhtml:strong" mode="text">
<xsl:copy><xsl:apply-templates mode="text"/></xsl:copy>
</xsl:template>
<xsl:template match="xhtml:h1|xhtml:h2|xhtml:h3|xhtml:p">
<xsl:copy><xsl:apply-templates mode="text"/></xsl:copy>
</xsl:template>
<xsl:template match="xhtml:li" mode="list">
<xsl:copy><xsl:apply-templates mode="text"/></xsl:copy>
</xsl:template>
<xsl:template match="xhtml:ul|xhtml:ol">
<xsl:copy><xsl:apply-templates mode="list"/></xsl:copy>
</xsl:template>
<xsl:template match="/">
<xhtml:body><xsl:apply-templates/></xhtml:body>
</xsl:template>
</xsl:stylesheet>

Просмотреть файл

@ -3,6 +3,7 @@ toolkit.jar:
* content/mozapps/extensions/extensions.xul (content/extensions.xul) * content/mozapps/extensions/extensions.xul (content/extensions.xul)
* content/mozapps/extensions/extensions.js (content/extensions.js) * content/mozapps/extensions/extensions.js (content/extensions.js)
* content/mozapps/extensions/extensions.xml (content/extensions.xml) * content/mozapps/extensions/extensions.xml (content/extensions.xml)
content/mozapps/extensions/updateinfo.xsl (content/updateinfo.xsl)
content/mozapps/extensions/extensions.css (content/extensions.css) content/mozapps/extensions/extensions.css (content/extensions.css)
* content/mozapps/extensions/about.xul (content/about.xul) * content/mozapps/extensions/about.xul (content/about.xul)
* content/mozapps/extensions/about.js (content/about.js) * content/mozapps/extensions/about.js (content/about.js)

Просмотреть файл

@ -4480,7 +4480,8 @@ ExtensionManager.prototype = {
type : EM_I(type), type : EM_I(type),
availableUpdateURL : null, availableUpdateURL : null,
availableUpdateHash : null, availableUpdateHash : null,
availableUpdateVersion: null }; availableUpdateVersion: null,
availableUpdateInfo : null };
for (var p in props) for (var p in props)
ds.setItemProperty(id, EM_R(p), props[p]); ds.setItemProperty(id, EM_R(p), props[p]);
ds.updateProperty(id, "availableUpdateURL"); ds.updateProperty(id, "availableUpdateURL");
@ -4520,7 +4521,8 @@ ExtensionManager.prototype = {
newVersion : EM_L(getManifestProperty(installManifest, "version")), newVersion : EM_L(getManifestProperty(installManifest, "version")),
availableUpdateURL : null, availableUpdateURL : null,
availableUpdateHash : null, availableUpdateHash : null,
availableUpdateVersion : null }; availableUpdateVersion : null,
availableUpdateInfo : null };
for (var p in props) for (var p in props)
ds.setItemProperty(id, EM_R(p), props[p]); ds.setItemProperty(id, EM_R(p), props[p]);
ds.updateProperty(id, "availableUpdateURL"); ds.updateProperty(id, "availableUpdateURL");
@ -5392,6 +5394,7 @@ ExtensionManager.prototype = {
ds.setItemProperty(id, EM_R("availableUpdateURL"), null); ds.setItemProperty(id, EM_R("availableUpdateURL"), null);
ds.setItemProperty(id, EM_R("availableUpdateHash"), null); ds.setItemProperty(id, EM_R("availableUpdateHash"), null);
ds.setItemProperty(id, EM_R("availableUpdateVersion"), null); ds.setItemProperty(id, EM_R("availableUpdateVersion"), null);
ds.setItemProperty(id, EM_R("availableUpdateInfo"), null);
ds.updateProperty(id, "availableUpdateURL"); ds.updateProperty(id, "availableUpdateURL");
ds.updateProperty(id, "updateable"); ds.updateProperty(id, "updateable");
} }
@ -6474,6 +6477,15 @@ RDFItemUpdater.prototype = {
appID); appID);
if (this._updater._isValidUpdate(aLocalItem, updatedItem)) { if (this._updater._isValidUpdate(aLocalItem, updatedItem)) {
if (aUpdateCheckType == nsIExtensionManager.UPDATE_CHECK_NEWVERSION) {
var infourl = this._getPropertyFromResource(aDataSource, targetApp,
"updateInfoURL");
if (infourl)
infourl = EM_L(infourl);
this._updater._emDS.setItemProperty(aLocalItem.id,
EM_R("availableUpdateInfo"),
infourl);
}
if (appID == this._updater._appID) { if (appID == this._updater._appID) {
// App takes precedence over toolkit. If we found the app, bail out. // App takes precedence over toolkit. If we found the app, bail out.
return updatedItem; return updatedItem;

Просмотреть файл

@ -284,3 +284,45 @@ radio#installs-view:hover, radio#installs-view[selected="true"] {
richlistitem[selected="true"] .includeUpdate { richlistitem[selected="true"] .includeUpdate {
-moz-user-focus: normal; -moz-user-focus: normal;
} }
#infoDisplay {
overflow-y: auto;
}
#infoDisplay body {
padding: 5px;
}
#infoDisplay h1,
#infoDisplay h2,
#infoDisplay h3 {
text-align: left;
font-weight: bold;
margin: 0 0 0.7em 0;
}
#infoDisplay h1 {
font-size: 150%;
}
#infoDisplay h2 {
font-size: 125%;
}
#infoDisplay h3 {
font-size: 100%;
}
#infoDisplay ol,
#infoDisplay ul {
margin: 0 0 0.7em 0;
}
#infoDisplay li {
text-align: left;
}
#infoDisplay p {
text-align: justify;
margin: 0 0 0.7em 0;
}

Просмотреть файл

@ -48,7 +48,7 @@ margin-top: -12px;
-moz-image-region: rect(21px, 84px, 42px, 63px); -moz-image-region: rect(21px, 84px, 42px, 63px);
} }
#checkUpdatesAllButton { #checkUpdatesAllButton, #showUpdateInfoButton, #hideUpdateInfoButton {
-moz-image-region: rect(0px, 63px, 21px, 42px); -moz-image-region: rect(0px, 63px, 21px, 42px);
} }
#checkUpdatesAllButton[disabled="true"] { #checkUpdatesAllButton[disabled="true"] {
@ -351,3 +351,45 @@ radio#installs-view:hover, radio#installs-view[selected="true"] {
richlistitem[selected="true"] .includeUpdate { richlistitem[selected="true"] .includeUpdate {
-moz-user-focus: normal; -moz-user-focus: normal;
} }
#infoDisplay {
overflow-y: auto;
}
#infoDisplay body {
padding: 5px;
}
#infoDisplay h1,
#infoDisplay h2,
#infoDisplay h3 {
text-align: left;
font-weight: bold;
margin: 0 0 0.7em 0;
}
#infoDisplay h1 {
font-size: 150%;
}
#infoDisplay h2 {
font-size: 125%;
}
#infoDisplay h3 {
font-size: 100%;
}
#infoDisplay ol,
#infoDisplay ul {
margin: 0 0 0.7em 0;
}
#infoDisplay li {
text-align: left;
}
#infoDisplay p {
text-align: justify;
margin: 0 0 0.7em 0;
}