mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
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:
parent
04fadef34d
commit
a2e6013f30
@ -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>
|
||||
|
@ -26,6 +26,12 @@
|
||||
<!ENTITY upgrade.evangelism "It is strongly recommended that you upgrade &brandShortName;
|
||||
as soon as possible by clicking Download & Install ».">
|
||||
|
||||
<!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">
|
||||
|
@ -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...
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user