Add support for optional license to updates. This allows for updates to inform the user of license changes with included components and force them to agree before they can update the software. Also add a 'View installed updates' button to the preferences panel

This commit is contained in:
ben%bengoodger.com 2005-06-10 21:27:24 +00:00
parent 04fadef34d
commit a2e6013f30
9 changed files with 227 additions and 21 deletions

View File

@ -82,6 +82,9 @@
<preference id="pref.update.disable_button.update_app"
name="pref.update.disable_button.update_app"
type="bool"/>
<preference id="pref.update.disable_button.show_updates"
name="pref.update.disable_button.show_updates"
type="bool"/>
<preference id="pref.update.disable_button.update_addons"
name="pref.update.disable_button.update_addons"
type="bool"/>
@ -166,8 +169,11 @@
<separator class="thin"/>
<hbox>
<button label="&checkNow.label;" accesskey="&appCheckNow.accesskey;"
oncommand="gAdvancedPane.checkForUpdates(Components.interfaces.nsIUpdateItem.TYPE_APP);"
oncommand="gAdvancedPane.checkForUpdates();"
preference="pref.update.disable_button.update_app"/>
<button label="&showUpdates.label;" accesskey="&showUpdates.accesskey;"
oncommand="gAdvancedPane.showUpdates();"
preference="pref.update.disable_button.show_updates"/>
</hbox>
</vbox>
</vbox>

View File

@ -26,6 +26,12 @@
<!ENTITY upgrade.evangelism "It is strongly recommended that you upgrade &brandShortName;
as soon as possible by clicking Download &amp; Install &#0187;.">
<!ENTITY license.title "License Agreement">
<!ENTITY license.intro "To install this update you must agree to this license agreement.
Please read it carefully:">
<!ENTITY license.instructions "If you agree to the terms of this agreement, click I Agree
below to continue installing this update.">
<!ENTITY downloading.intro "The following updates are being/have been installed:">
<!ENTITY showCompletedUpdates.label "Show old updates in this list">
<!ENTITY showCompletedUpdates.accesskey "o">

View File

@ -7,3 +7,6 @@ verificationError=%S could not confirm the integrity of the update package.
app.update.url=http://localhost/updates-test-1.xml
app.update.manual.url=http://www.mozilla.org/update
errorsPageHeader=Update Failed
IAgreeLabel=I Agree
license404Error=The license file could not be found. Please contact the distributor.
downloadingLicense=Downloading license text...

View File

@ -4,6 +4,7 @@ wizard[description=""] .wizard-header-description {
display: none;
}
wizard[currentpageid="license"] .wizard-buttons,
wizard[currentpageid="errors"] .wizard-buttons {
display: -moz-box;
}
@ -54,6 +55,29 @@ link:focus {
border: 1px dotted black;
}
license {
-moz-binding: url("chrome://mozapps/content/update/updates.xml#license");
display: -moz-deck;
margin-top: 1px;
margin-bottom: 2px;
-moz-margin-start: 6px;
-moz-margin-end: 5px;
-moz-appearance: listbox;
padding-bottom: 1px;
}
.loadingBox {
padding: 3px 5px 3px 5px;
}
.licenseLoadingThrobber {
margin-top: 3px;
}
.licenseLoadingThrobber[state="loading"] {
list-style-image: url("chrome://global/skin/throbber/Throbber-small.gif");
}
.licenseLoadingThrobber[state="error"] {
list-style-image: url("chrome://global/skin/icons/notfound.png");
}
#updateName {
font-weight: bold;
font-size: x-large;

View File

@ -51,6 +51,8 @@ function LOG(string) {
var gUpdates = {
update: null,
updateStrings: null,
brandStrings: null,
onClose: function() {
var objects = {
checking: gCheckingPage,
@ -66,6 +68,9 @@ var gUpdates = {
this.update = window.arguments[0];
document.documentElement.advance();
}
this.updateStrings = document.getElementById("updateStrings");
this.brandStrings = document.getElementById("brandStrings");
},
advanceToErrorPage: function(currentPage, reason) {
@ -81,14 +86,17 @@ var gUpdates = {
var errorLinkLabel = document.getElementById("errorLinkLabel");
errorLinkLabel.value = manualURL.data;
var updateStrings = document.getElementById("updateStrings");
var pageTitle = updateStrings.getString("errorsPageHeader");
var pageTitle = this.updateStrings.getString("errorsPageHeader");
var errorPage = document.getElementById("errors");
errorPage.setAttribute("label", pageTitle);
document.documentElement.setAttribute("label", pageTitle);
document.documentElement.advance();
},
set headerVisible(visible) {
document.documentElement.setAttribute("label", visible ? " " : "");
}
}
var gCheckingPage = {
@ -108,6 +116,8 @@ var gCheckingPage = {
var aus = Components.classes["@mozilla.org/updates/update-service;1"]
.getService(Components.interfaces.nsIApplicationUpdateService);
this._checker = aus.checkForUpdates(this.updateListener);
gUpdates.headerVisible = true;
},
/**
@ -166,17 +176,15 @@ var gUpdatesAvailablePage = {
_incompatibleItems: null,
onPageShow: function() {
var updateStrings = document.getElementById("updateStrings");
var brandStrings = document.getElementById("brandStrings");
var brandName = brandStrings.getString("brandShortName");
var updateName = updateStrings.getFormattedString("updateName",
[brandName, gUpdates.update.version]);
var brandName = gUpdates.brandStrings.getString("brandShortName");
var updateName = gUpdates.updateStrings.getFormattedString("updateName",
[brandName, gUpdates.update.version]);
var updateNameElement = document.getElementById("updateName");
updateNameElement.value = updateName;
var displayType = updateStrings.getString("updateType_" + gUpdates.update.type);
var displayType = gUpdates.updateStrings.getString("updateType_" + gUpdates.update.type);
var updateTypeElement = document.getElementById("updateType");
updateTypeElement.setAttribute("type", gUpdates.update.type);
var intro = updateStrings.getFormattedString("introType_" + gUpdates.update.type, [brandName]);
var intro = gUpdates.updateStrings.getFormattedString("introType_" + gUpdates.update.type, [brandName]);
while (updateTypeElement.hasChildNodes())
updateTypeElement.removeChild(updateTypeElement.firstChild);
updateTypeElement.appendChild(document.createTextNode(intro));
@ -199,6 +207,15 @@ var gUpdatesAvailablePage = {
var dlButton = document.getElementById("download-button");
dlButton.focus();
gUpdates.headerVisible = false;
},
onInstallNow: function() {
var nextPageID = gUpdates.update.licenseurl ? "license" : "downloading";
var updatesfound = document.getElementById("updatesfound");
updatesfound.setAttribute("next", nextPageID);
document.documentElement.advance();
},
showIncompatibleItems: function() {
@ -207,6 +224,32 @@ var gUpdatesAvailablePage = {
}
};
var gLicensePage = {
_licenseContent: null,
onPageShow: function() {
this._licenseContent = document.getElementById("licenseContent");
var nextButton = document.documentElement.getButton("next");
nextButton.disabled = true;
nextButton.label = gUpdates.updateStrings.getString("IAgreeLabel");
document.documentElement.getButton("back").disabled = true;
document.documentElement.getButton("next").focus();
this._licenseContent.addEventListener("load", this.onLicenseLoad, false);
this._licenseContent.url = gUpdates.update.licenseurl;
gUpdates.headerVisible = true;
},
onLicenseLoad: function() {
document.documentElement.getButton("next").disabled = false;
},
onClose: function() {
this._licenseContent.stopDownloading();
}
};
var gDownloadingPage = {
onPageShow: function() {
// Build the UI for the active download
@ -234,6 +277,7 @@ var gDownloadingPage = {
// Build the UI for previously installed updates
// ...
gUpdates.headerVisible = false;
},
_paused: false,
@ -307,10 +351,8 @@ var gDownloadingPage = {
},
showVerificationError: function() {
var updateStrings = document.getElementById("updateStrings");
var brandStrings = document.getElementById("brandStrings");
var brandName = brandStrings.getString("brandShortName");
var verificationError = updateStrings.getFormattedString("verificationError", [brandName]);
var brandName = gUpdates.brandStrings.getString("brandShortName");
var verificationError = gUpdates.updateStrings.getFormattedString("verificationError", [brandName]);
var downloadingPage = document.getElementById("downloading");
// gUpdates.advanceToErrorPage(downloadingPage, verificationError);
},
@ -332,6 +374,8 @@ var gErrorsPage = {
document.documentElement.getButton("back").disabled = true;
document.documentElement.getButton("cancel").disabled = true;
document.documentElement.getButton("finish").focus();
gUpdates.headerVisible = true;
}
};

View File

@ -85,5 +85,117 @@
</implementation>
</binding>
<binding id="license">
<content>
<xul:vbox flex="1" class="loadingBox">
<xul:hbox align="start">
<xul:image class="licenseLoadingThrobber" xbl:inherits="state"/>
<xul:vbox flex="1">
<xul:description flex="1" class="licenseLoadingMessage" crop="right"/>
</xul:vbox>
</xul:hbox>
</xul:vbox>
<xul:vbox flex="1">
<xul:browser class="licenseContent" flex="1"/>
</xul:vbox>
<xul:stringbundle anonid="strings"
src="chrome://mozapps/locale/update/updates.properties"/>
</content>
<implementation>
<constructor>
if (this.hasAttribute("url"))
this.url = this.getAttribute("url");
</constructor>
<field name="_request">null</field>
<field name="_message">
document.getAnonymousElementByAttribute(this, "class", "licenseLoadingMessage");
</field>
<field name="_content">
document.getAnonymousElementByAttribute(this, "class", "licenseContent");
</field>
<field name="_strings">
document.getAnonymousElementByAttribute(this, "anonid", "strings");
</field>
<method name="_setMessageValue">
<parameter name="value"/>
<body><![CDATA[
while (this._message.hasChildNodes())
this._message.removeChild(this._message.firstChild);
this._message.appendChild(document.createTextNode(value));
]]></body>
</method>
<method name="onError">
<parameter name="event"/>
<body><![CDATA[
var status = this._request.status;
var statusText = this._request.statusText
LOG("license.onError: error during load, status code = " + status +
", message: " + statusText);
if (status == 404)
statusText = this._strings.getString("license404Error");
this._setMessageValue(statusText);
this.setAttribute("state", "error");
]]></body>
</method>
<method name="onLoad">
<parameter name="event"/>
<body><![CDATA[
LOG("license.onLoad: request completed downloading document");
this.setAttribute("selectedIndex", "1");
var doc = this._content.contentWindow.document;
doc.documentElement.innerHTML = this._request.responseText;
var e = document.createEvent("Events");
e.initEvent("load", false, true);
this.dispatchEvent(e);
]]></body>
</method>
<method name="onProgress">
<parameter name="event"/>
<body><![CDATA[
LOG("license.onProgress: download progress: " + event.position + "/" + event.totalSize);
]]></body>
</method>
<property name="url">
<getter><![CDATA[
return this.getAttribute("url");
]]></getter>
<setter><![CDATA[
this.setAttribute("url", val);
this._request = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Components.interfaces.nsIXMLHttpRequest);
this._request.open("GET", val, true);
this._request.setRequestHeader("Cache-Control", "no-cache");
var self = this;
this._request.onerror = function(event) { self.onError(event); };
this._request.onload = function(event) { self.onLoad(event); };
this._request.onprogress = function(event) { self.onProgress(event); };
this.setAttribute("state", "loading");
this._setMessageValue(this._strings.getString("downloadingLicense"));
LOG("license.set_url: sending request to " + val);
this._request.send(null);
]]></setter>
</property>
<method name="stopDownloading">
<body><![CDATA[
const READY_STATE_COMPLETED = 4
if (this._request &&
this._request.readyState != READY_STATE_COMPLETED)
this._request.abort();
]]></body>
</method>
</implementation>
</binding>
</bindings>

View File

@ -113,15 +113,20 @@
<separator flex="1"/>
<button id="download-button"
label="&download.label;" accesskey="&download.accesskey;"
oncommand="document.documentElement.advance()"/>
oncommand="gUpdatesAvailablePage.onInstallNow();"/>
</hbox>
</vbox>
</vbox>
<!--
<hbox pack="end">
<resizer dir="bottomright"/>
</hbox>
-->
</wizardpage>
<wizardpage id="license" pageid="license" next="downloading"
onpageshow="gLicensePage.onPageShow();" class="content"
label="&license.title;">
<label>&license.intro;</label>
<separator class="thin"/>
<license id="licenseContent" flex="1"/>
<separator class="thin"/>
<label>&license.instructions;</label>
</wizardpage>
<wizardpage id="downloading" pageid="downloading" next="finished"

View File

@ -86,6 +86,10 @@ interface nsIUpdate : nsISupports
*
*/
attribute AString detailsurl;
/**
*
*/
attribute AString licenseurl;
/**
* Whether or not the update being downloaded is a complete replacement of

View File

@ -644,11 +644,12 @@ UpdatePatch.prototype = {
* Update
* Implements nsIUpdate
*/
function Update(type, version, extensionversion, detailsurl, patches) {
function Update(type, version, extensionversion, detailsurl, licenseurl, patches) {
this.type = type;
this.version = version;
this.extensionversion = extensionversion;
this.detailsurl = detailsurl;
this.licenseurl = licenseurl;
this.isCompleteUpdate = false;
this._patches = patches;
}
@ -704,6 +705,7 @@ function ParseUpdateNode(node) {
node.getAttribute("version"),
node.getAttribute("extensionversion"),
node.getAttribute("detailsurl"),
node.getAttribute("licenseurl"),
patches);
}