commit 3b8cae90376092d4926d59c23be2cf7e3b9559db Author: Sukhbir Singh sukhbir@torproject.org Date: Wed Jul 13 13:09:10 2016 -0400
Use the about dialog from Firefox
In addition to copying aboutDialog.xul and making related modifications to the CSS path (changing "browser" to "instantbird"), this patch also applies the changes from trac #5698 which has custom settings for Tor Browser. --- projects/instantbird/about-logo.png | Bin 0 -> 6681 bytes projects/instantbird/about-logo@2x.png | Bin 0 -> 13886 bytes projects/instantbird/about-wordmark.png | Bin 0 -> 3754 bytes projects/instantbird/aboutDialog-appUpdater.js | 557 +++++++++++++++++++++++++ projects/instantbird/aboutDialog-jar.patch | 12 + projects/instantbird/aboutDialog.css | 91 ++++ projects/instantbird/aboutDialog.dtd | 127 ++++++ projects/instantbird/aboutDialog.js | 69 +++ projects/instantbird/aboutDialog.xul | 192 +++++++++ projects/instantbird/branding-aboutDialog.css | 48 +++ projects/instantbird/branding/jar.patch | 11 + projects/instantbird/build | 11 +- projects/instantbird/config | 11 + 13 files changed, 1127 insertions(+), 2 deletions(-)
diff --git a/projects/instantbird/about-logo.png b/projects/instantbird/about-logo.png new file mode 100644 index 0000000..c6e4c49 Binary files /dev/null and b/projects/instantbird/about-logo.png differ diff --git a/projects/instantbird/about-logo@2x.png b/projects/instantbird/about-logo@2x.png new file mode 100644 index 0000000..99d626e Binary files /dev/null and b/projects/instantbird/about-logo@2x.png differ diff --git a/projects/instantbird/about-wordmark.png b/projects/instantbird/about-wordmark.png new file mode 100644 index 0000000..52923b6 Binary files /dev/null and b/projects/instantbird/about-wordmark.png differ diff --git a/projects/instantbird/aboutDialog-appUpdater.js b/projects/instantbird/aboutDialog-appUpdater.js new file mode 100644 index 0000000..66db02a --- /dev/null +++ b/projects/instantbird/aboutDialog-appUpdater.js @@ -0,0 +1,557 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Note: this file is included in aboutDialog.xul if MOZ_UPDATER is defined. + +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); +Components.utils.import("resource://gre/modules/DownloadUtils.jsm"); +Components.utils.import("resource://gre/modules/AddonManager.jsm"); + +XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils", + "resource://gre/modules/UpdateUtils.jsm"); + +var gAppUpdater; + +function onUnload(aEvent) { + if (gAppUpdater.isChecking) + gAppUpdater.checker.stopChecking(Components.interfaces.nsIUpdateChecker.CURRENT_CHECK); + // Safe to call even when there isn't a download in progress. + gAppUpdater.removeDownloadListener(); + gAppUpdater = null; +} + + +function appUpdater() +{ + this.updateDeck = document.getElementById("updateDeck"); + + // Hide the update deck when there is already an update window open to avoid + // syncing issues between them. + if (Services.wm.getMostRecentWindow("Update:Wizard")) { + this.updateDeck.hidden = true; + return; + } + + XPCOMUtils.defineLazyServiceGetter(this, "aus", + "@mozilla.org/updates/update-service;1", + "nsIApplicationUpdateService"); + XPCOMUtils.defineLazyServiceGetter(this, "checker", + "@mozilla.org/updates/update-checker;1", + "nsIUpdateChecker"); + XPCOMUtils.defineLazyServiceGetter(this, "um", + "@mozilla.org/updates/update-manager;1", + "nsIUpdateManager"); + + this.bundle = Services.strings. + createBundle("chrome://browser/locale/browser.properties"); + + let manualURL = Services.urlFormatter.formatURLPref("app.update.url.manual"); + let manualLink = document.getElementById("manualLink"); + manualLink.value = manualURL; + manualLink.href = manualURL; + document.getElementById("failedLink").href = manualURL; + + if (this.updateDisabledAndLocked) { + this.selectPanel("adminDisabled"); + return; + } + + if (this.isPending || this.isApplied) { + this.selectPanel("apply"); + return; + } + + if (this.aus.isOtherInstanceHandlingUpdates) { + this.selectPanel("otherInstanceHandlingUpdates"); + return; + } + + if (this.isDownloading) { + this.startDownload(); + // selectPanel("downloading") is called from setupDownloadingUI(). + return; + } + + // Honor the "Never check for updates" option by not only disabling background + // update checks, but also in the About dialog, by presenting a + // "Check for updates" button. + // If updates are found, the user is then asked if he wants to "Update to <version>". + if (!this.updateEnabled) { + this.selectPanel("checkForUpdates"); + return; + } + + // That leaves the options + // "Check for updates, but let me choose whether to install them", and + // "Automatically install updates". + // In both cases, we check for updates without asking. + // In the "let me choose" case, we ask before downloading though, in onCheckComplete. + this.checkForUpdates(); +} + +appUpdater.prototype = +{ + // true when there is an update check in progress. + isChecking: false, + + // true when there is an update already staged / ready to be applied. + get isPending() { + if (this.update) { + return this.update.state == "pending" || + this.update.state == "pending-service"; + } + return this.um.activeUpdate && + (this.um.activeUpdate.state == "pending" || + this.um.activeUpdate.state == "pending-service"); + }, + + // true when there is an update already installed in the background. + get isApplied() { + if (this.update) + return this.update.state == "applied" || + this.update.state == "applied-service"; + return this.um.activeUpdate && + (this.um.activeUpdate.state == "applied" || + this.um.activeUpdate.state == "applied-service"); + }, + + // true when there is an update download in progress. + get isDownloading() { + if (this.update) + return this.update.state == "downloading"; + return this.um.activeUpdate && + this.um.activeUpdate.state == "downloading"; + }, + + // true when updating is disabled by an administrator. + get updateDisabledAndLocked() { + return !this.updateEnabled && + Services.prefs.prefIsLocked("app.update.enabled"); + }, + + // true when updating is enabled. + get updateEnabled() { + try { + return Services.prefs.getBoolPref("app.update.enabled"); + } + catch (e) { } + return true; // Firefox default is true + }, + + // true when updating in background is enabled. + get backgroundUpdateEnabled() { + return this.updateEnabled && + gAppUpdater.aus.canStageUpdates; + }, + + // true when updating is automatic. + get updateAuto() { + try { + return Services.prefs.getBoolPref("app.update.auto"); + } + catch (e) { } + return true; // Firefox default is true + }, + + /** + * Sets the panel of the updateDeck. + * + * @param aChildID + * The id of the deck's child to select, e.g. "apply". + */ + selectPanel: function(aChildID) { + let panel = document.getElementById(aChildID); + + let button = panel.querySelector("button"); + if (button) { + if (aChildID == "downloadAndInstall") { + let updateVersion = gAppUpdater.update.displayVersion; + button.label = this.bundle.formatStringFromName("update.downloadAndInstallButton.label", [updateVersion], 1); + button.accessKey = this.bundle.GetStringFromName("update.downloadAndInstallButton.accesskey"); + } + this.updateDeck.selectedPanel = panel; + if (!document.commandDispatcher.focusedElement || // don't steal the focus + document.commandDispatcher.focusedElement.localName == "button") // except from the other buttons + button.focus(); + + } else { + this.updateDeck.selectedPanel = panel; + } + }, + + /** + * Check for updates + */ + checkForUpdates: function() { + this.selectPanel("checkingForUpdates"); + this.isChecking = true; + this.checker.checkForUpdates(this.updateCheckListener, true); + // after checking, onCheckComplete() is called + }, + + /** + * Check for addon compat, or start the download right away + */ + doUpdate: function() { + // skip the compatibility check if the update doesn't provide appVersion, + // or the appVersion is unchanged, e.g. nightly update + if (!this.update.appVersion || + Services.vc.compare(gAppUpdater.update.appVersion, + Services.appinfo.version) == 0) { + this.startDownload(); + } else { + this.checkAddonCompatibility(); + } + }, + + /** + * Handles oncommand for the "Restart to Update" button + * which is presented after the download has been downloaded. + */ + buttonRestartAfterDownload: function() { + if (!this.isPending && !this.isApplied) + return; + + // Notify all windows that an application quit has been requested. + let cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"]. + createInstance(Components.interfaces.nsISupportsPRBool); + Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart"); + + // Something aborted the quit process. + if (cancelQuit.data) + return; + + let appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]. + getService(Components.interfaces.nsIAppStartup); + + // If already in safe mode restart in safe mode (bug 327119) + if (Services.appinfo.inSafeMode) { + appStartup.restartInSafeMode(Components.interfaces.nsIAppStartup.eAttemptQuit); + return; + } + + appStartup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit | + Components.interfaces.nsIAppStartup.eRestart); + }, + + /** + * Handles oncommand for the "Apply Update…" button + * which is presented if we need to show the billboard or license. + */ + buttonApplyBillboard: function() { + const URI_UPDATE_PROMPT_DIALOG = "chrome://mozapps/content/update/updates.xul"; + var ary = null; + ary = Components.classes["@mozilla.org/supports-array;1"]. + createInstance(Components.interfaces.nsISupportsArray); + ary.AppendElement(this.update); + var openFeatures = "chrome,centerscreen,dialog=no,resizable=no,titlebar,toolbar=no"; + Services.ww.openWindow(null, URI_UPDATE_PROMPT_DIALOG, "", openFeatures, ary); + window.close(); // close the "About" window; updates.xul takes over. + }, + + /** + * Implements nsIUpdateCheckListener. The methods implemented by + * nsIUpdateCheckListener are in a different scope from nsIIncrementalDownload + * to make it clear which are used by each interface. + */ + updateCheckListener: { + /** + * See nsIUpdateService.idl + */ + onCheckComplete: function(aRequest, aUpdates, aUpdateCount) { + gAppUpdater.isChecking = false; + gAppUpdater.update = gAppUpdater.aus. + selectUpdate(aUpdates, aUpdates.length); + if (!gAppUpdater.update) { + gAppUpdater.selectPanel("noUpdatesFound"); + return; + } + + if (gAppUpdater.update.unsupported) { + if (gAppUpdater.update.detailsURL) { + let unsupportedLink = document.getElementById("unsupportedLink"); + unsupportedLink.href = gAppUpdater.update.detailsURL; + } + gAppUpdater.selectPanel("unsupportedSystem"); + return; + } + + if (!gAppUpdater.aus.canApplyUpdates) { + gAppUpdater.selectPanel("manualUpdate"); + return; + } + + // Firefox no longer displays a license for updates and the licenseURL + // check is just in case a distibution does. + if (gAppUpdater.update.billboardURL || gAppUpdater.update.licenseURL) { + gAppUpdater.selectPanel("applyBillboard"); + return; + } + + if (gAppUpdater.updateAuto) // automatically download and install + gAppUpdater.doUpdate(); + else // ask + gAppUpdater.selectPanel("downloadAndInstall"); + }, + + /** + * See nsIUpdateService.idl + */ + onError: function(aRequest, aUpdate) { + // Errors in the update check are treated as no updates found. If the + // update check fails repeatedly without a success the user will be + // notified with the normal app update user interface so this is safe. + gAppUpdater.isChecking = false; + gAppUpdater.selectPanel("noUpdatesFound"); + }, + + /** + * See nsISupports.idl + */ + QueryInterface: function(aIID) { + if (!aIID.equals(Components.interfaces.nsIUpdateCheckListener) && + !aIID.equals(Components.interfaces.nsISupports)) + throw Components.results.NS_ERROR_NO_INTERFACE; + return this; + } + }, + + /** + * Checks the compatibility of add-ons for the application update. + */ + checkAddonCompatibility: function() { + try { + var hotfixID = Services.prefs.getCharPref(PREF_EM_HOTFIX_ID); + } + catch (e) { } + + var self = this; + AddonManager.getAllAddons(function(aAddons) { + self.addons = []; + self.addonsCheckedCount = 0; + aAddons.forEach(function(aAddon) { + // Protect against code that overrides the add-ons manager and doesn't + // implement the isCompatibleWith or the findUpdates method. + if (!("isCompatibleWith" in aAddon) || !("findUpdates" in aAddon)) { + let errMsg = "Add-on doesn't implement either the isCompatibleWith " + + "or the findUpdates method!"; + if (aAddon.id) + errMsg += " Add-on ID: " + aAddon.id; + Components.utils.reportError(errMsg); + return; + } + + // If an add-on isn't appDisabled and isn't userDisabled then it is + // either active now or the user expects it to be active after the + // restart. If that is the case and the add-on is not installed by the + // application and is not compatible with the new application version + // then the user should be warned that the add-on will become + // incompatible. If an addon's type equals plugin it is skipped since + // checking plugins compatibility information isn't supported and + // getting the scope property of a plugin breaks in some environments + // (see bug 566787). The hotfix add-on is also ignored as it shouldn't + // block the user from upgrading. + try { + if (aAddon.type != "plugin" && aAddon.id != hotfixID && + !aAddon.appDisabled && !aAddon.userDisabled && + aAddon.scope != AddonManager.SCOPE_APPLICATION && + aAddon.isCompatible && + !aAddon.isCompatibleWith(self.update.appVersion, + self.update.platformVersion)) + self.addons.push(aAddon); + } + catch (e) { + Components.utils.reportError(e); + } + }); + self.addonsTotalCount = self.addons.length; + if (self.addonsTotalCount == 0) { + self.startDownload(); + return; + } + + self.checkAddonsForUpdates(); + }); + }, + + /** + * Checks if there are updates for add-ons that are incompatible with the + * application update. + */ + checkAddonsForUpdates: function() { + this.addons.forEach(function(aAddon) { + aAddon.findUpdates(this, AddonManager.UPDATE_WHEN_NEW_APP_DETECTED, + this.update.appVersion, + this.update.platformVersion); + }, this); + }, + + /** + * See XPIProvider.jsm + */ + onCompatibilityUpdateAvailable: function(aAddon) { + for (var i = 0; i < this.addons.length; ++i) { + if (this.addons[i].id == aAddon.id) { + this.addons.splice(i, 1); + break; + } + } + }, + + /** + * See XPIProvider.jsm + */ + onUpdateAvailable: function(aAddon, aInstall) { + if (!Services.blocklist.isAddonBlocklisted(aAddon, + this.update.appVersion, + this.update.platformVersion)) { + // Compatibility or new version updates mean the same thing here. + this.onCompatibilityUpdateAvailable(aAddon); + } + }, + + /** + * See XPIProvider.jsm + */ + onUpdateFinished: function(aAddon) { + ++this.addonsCheckedCount; + + if (this.addonsCheckedCount < this.addonsTotalCount) + return; + + if (this.addons.length == 0) { + // Compatibility updates or new version updates were found for all add-ons + this.startDownload(); + return; + } + + this.selectPanel("applyBillboard"); + }, + + /** + * Starts the download of an update mar. + */ + startDownload: function() { + if (!this.update) + this.update = this.um.activeUpdate; + this.update.QueryInterface(Components.interfaces.nsIWritablePropertyBag); + this.update.setProperty("foregroundDownload", "true"); + + this.aus.pauseDownload(); + let state = this.aus.downloadUpdate(this.update, false); + if (state == "failed") { + this.selectPanel("downloadFailed"); + return; + } + + this.setupDownloadingUI(); + }, + + /** + * Switches to the UI responsible for tracking the download. + */ + setupDownloadingUI: function() { + this.downloadStatus = document.getElementById("downloadStatus"); + this.downloadStatus.value = + DownloadUtils.getTransferTotal(0, this.update.selectedPatch.size); + this.selectPanel("downloading"); + this.aus.addDownloadListener(this); + }, + + removeDownloadListener: function() { + if (this.aus) { + this.aus.removeDownloadListener(this); + } + }, + + /** + * See nsIRequestObserver.idl + */ + onStartRequest: function(aRequest, aContext) { + }, + + /** + * See nsIRequestObserver.idl + */ + onStopRequest: function(aRequest, aContext, aStatusCode) { + switch (aStatusCode) { + case Components.results.NS_ERROR_UNEXPECTED: + if (this.update.selectedPatch.state == "download-failed" && + (this.update.isCompleteUpdate || this.update.patchCount != 2)) { + // Verification error of complete patch, informational text is held in + // the update object. + this.removeDownloadListener(); + this.selectPanel("downloadFailed"); + break; + } + // Verification failed for a partial patch, complete patch is now + // downloading so return early and do NOT remove the download listener! + break; + case Components.results.NS_BINDING_ABORTED: + // Do not remove UI listener since the user may resume downloading again. + break; + case Components.results.NS_OK: + this.removeDownloadListener(); + if (this.backgroundUpdateEnabled) { + this.selectPanel("applying"); + let update = this.um.activeUpdate; + let self = this; + Services.obs.addObserver(function (aSubject, aTopic, aData) { + // Update the UI when the background updater is finished + let status = aData; + if (status == "applied" || status == "applied-service" || + status == "pending" || status == "pending-service") { + // If the update is successfully applied, or if the updater has + // fallen back to non-staged updates, show the "Restart to Update" + // button. + self.selectPanel("apply"); + } else if (status == "failed") { + // Background update has failed, let's show the UI responsible for + // prompting the user to update manually. + self.selectPanel("downloadFailed"); + } else if (status == "downloading") { + // We've fallen back to downloading the full update because the + // partial update failed to get staged in the background. + // Therefore we need to keep our observer. + self.setupDownloadingUI(); + return; + } + Services.obs.removeObserver(arguments.callee, "update-staged"); + }, "update-staged", false); + } else { + this.selectPanel("apply"); + } + break; + default: + this.removeDownloadListener(); + this.selectPanel("downloadFailed"); + break; + } + }, + + /** + * See nsIProgressEventSink.idl + */ + onStatus: function(aRequest, aContext, aStatus, aStatusArg) { + }, + + /** + * See nsIProgressEventSink.idl + */ + onProgress: function(aRequest, aContext, aProgress, aProgressMax) { + this.downloadStatus.value = + DownloadUtils.getTransferTotal(aProgress, aProgressMax); + }, + + /** + * See nsISupports.idl + */ + QueryInterface: function(aIID) { + if (!aIID.equals(Components.interfaces.nsIProgressEventSink) && + !aIID.equals(Components.interfaces.nsIRequestObserver) && + !aIID.equals(Components.interfaces.nsISupports)) + throw Components.results.NS_ERROR_NO_INTERFACE; + return this; + } +}; diff --git a/projects/instantbird/aboutDialog-jar.patch b/projects/instantbird/aboutDialog-jar.patch new file mode 100644 index 0000000..91f13bf --- /dev/null +++ b/projects/instantbird/aboutDialog-jar.patch @@ -0,0 +1,12 @@ +diff --git a/im/content/jar.mn b/im/content/jar.mn +--- a/im/content/jar.mn ++++ b/im/content/jar.mn +@@ -10,6 +10,8 @@ + #endif + content/instantbird/aboutDialog.css + * content/instantbird/aboutDialog.xul ++ content/instantbird/aboutDialog.js ++ content/instantbird/aboutDialog-appUpdater.js + content/instantbird/aboutPanel.xml + content/instantbird/account.js + content/instantbird/accounts.css diff --git a/projects/instantbird/aboutDialog.css b/projects/instantbird/aboutDialog.css new file mode 100644 index 0000000..a065c8e --- /dev/null +++ b/projects/instantbird/aboutDialog.css @@ -0,0 +1,91 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#aboutDialog { + width: 620px; +} + +#rightBox { + background-image: url("chrome://branding/content/about-wordmark.png"); + background-position: left top; + background-repeat: no-repeat; + /* padding-top creates room for the wordmark */ + padding-top: 38px; + margin-top:20px; +} + +#rightBox:-moz-locale-dir(rtl) { + background-position: 100% 0; +} + +#bottomBox > hbox:not(#newBottom) { + display: none; +} + +#version { + font-weight: bold; + margin-top: 10px; + -moz-margin-start: 0; + -moz-user-select: text; + -moz-user-focus: normal; + cursor: text; +} + +#version:-moz-locale-dir(rtl) { + direction: ltr; + text-align: right; + margin-right: 0; +} + +#distribution, +#distributionId { + display: none; + margin-top: 0; + margin-bottom: 0; +} + +.text-blurb { + margin-bottom: 10px; + -moz-margin-start: 0; + -moz-padding-start: 0; +} + +#updateButton, +#updateDeck > hbox > label { + -moz-margin-start: 0; + -moz-padding-start: 0; +} + +.update-throbber { + width: 16px; + min-height: 16px; + -moz-margin-end: 3px; + list-style-image: url("chrome://global/skin/icons/loading_16.png"); +} + +.text-link, +.text-link:focus { + margin: 0px; + padding: 0px; +} + +.bottom-link, +.bottom-link:focus { + text-align: center; + margin: 0 40px; +} + +#currentChannel { + margin: 0; + padding: 0; + font-weight: bold; +} + +#trademarkTor { + font-size: xx-small; + text-align: center; + color: #999999; + margin-top: 10px; + margin-bottom: 10px; +} diff --git a/projects/instantbird/aboutDialog.dtd b/projects/instantbird/aboutDialog.dtd new file mode 100644 index 0000000..1562ebc --- /dev/null +++ b/projects/instantbird/aboutDialog.dtd @@ -0,0 +1,127 @@ +<!-- This Source Code Form is subject to the terms of the Mozilla Public + - License, v. 2.0. If a copy of the MPL was not distributed with this + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> +<!ENTITY aboutDialog.title "About &brandFullName;"> + +<!-- LOCALIZATION NOTE (update.checkForUpdatesButton.*, update.updateButton.*, update.applyButtonBillboard.*): +# Only one button is present at a time. +# The button when displayed is located directly under the Firefox version in +# the about dialog (see bug 596813 for screenshots). +--> +<!ENTITY update.checkForUpdatesButton.label "Check for updates"> +<!ENTITY update.checkForUpdatesButton.accesskey "C"> +<!ENTITY update.updateButton.label2 "Restart &brandShortName; to Update"> +<!ENTITY update.updateButton.accesskey "R"> +<!ENTITY update.applyButtonBillboard.label "Apply Update…"> +<!ENTITY update.applyButtonBillboard.accesskey "A"> + + +<!-- LOCALIZATION NOTE (warningDesc.version): This is a warning about the experimental nature of Nightly and Aurora builds. It is only shown in those versions. --> +<!ENTITY warningDesc.version "&brandShortName; is experimental and may be unstable."> +<!-- LOCALIZATION NOTE (warningDesc.telemetryDesc): This is a notification that Nightly/Aurora builds automatically send Telemetry data back to Mozilla. It is only shown in those versions. "It" refers to brandShortName. --> +<!ENTITY warningDesc.telemetryDesc "It automatically sends information about performance, hardware, usage and customizations back to &vendorShortName; to help make &brandShortName; better."> + +<!-- LOCALIZATION NOTE (community.exp.*) This paragraph is shown in "experimental" builds, i.e. Nightly and Aurora builds, instead of the other "community.*" strings below. --> +<!ENTITY community.exp.start ""> +<!-- LOCALIZATION NOTE (community.exp.mozillaLink): This is a link title that links to http://www.mozilla.org/. --> +<!ENTITY community.exp.mozillaLink "&vendorShortName;"> +<!ENTITY community.exp.middle " is a "> +<!-- LOCALIZATION NOTE (community.exp.creditslink): This is a link title that links to about:credits. --> +<!ENTITY community.exp.creditsLink "global community"> +<!ENTITY community.exp.end " working together to keep the Web open, public and accessible to all."> + +<!ENTITY community.start2 "&brandShortName; is designed by "> +<!-- LOCALIZATION NOTE (community.mozillaLink): This is a link title that links to http://www.mozilla.org/. --> +<!ENTITY community.mozillaLink "&vendorShortName;"> +<!ENTITY community.middle2 ", a "> +<!-- LOCALIZATION NOTE (community.creditsLink): This is a link title that links to about:credits. --> +<!ENTITY community.creditsLink "global community"> +<!ENTITY community.end3 " working together to keep the Web open, public and accessible to all."> + +<!ENTITY helpus.start "Want to help? "> +<!-- LOCALIZATION NOTE (helpus.donateLink): This is a link title that links to https://sendto.mozilla.org/page/contribute/Give-Now?source=mozillaorg_default_footer&ref=firefox_about&utm_campaign=firefox_about&utm_source=firefox&utm_medium=referral&utm_content=20140929_FireFoxAbout. --> +<!ENTITY helpus.donateLink "Make a donation"> +<!ENTITY helpus.middle " or "> +<!-- LOCALIZATION NOTE (helpus.getInvolvedLink): This is a link title that links to http://www.mozilla.org/contribute/. --> +<!ENTITY helpus.getInvolvedLink "get involved!"> +<!ENTITY helpus.end ""> + +<!-- LOCALIZATION NOTE (bottomLinks.license): This is a link title that links to about:license. --> +<!ENTITY bottomLinks.license "Licensing Information"> + +<!-- LOCALIZATION NOTE (bottomLinks.rights): This is a link title that links to about:rights. --> +<!ENTITY bottomLinks.rights "End-User Rights"> + +<!-- LOCALIZATION NOTE (bottomLinks.privacy): This is a link title that links to https://www.mozilla.org/legal/privacy/. --> +<!ENTITY bottomLinks.privacy "Privacy Policy"> + +<!-- LOCALIZATION NOTE (update.checkingForUpdates): try to make the localized text short (see bug 596813 for screenshots). --> +<!ENTITY update.checkingForUpdates "Checking for updates…"> +<!-- LOCALIZATION NOTE (update.noUpdatesFound): try to make the localized text short (see bug 596813 for screenshots). --> +<!ENTITY update.noUpdatesFound "&brandShortName; is up to date"> +<!-- LOCALIZATION NOTE (update.adminDisabled): try to make the localized text short (see bug 596813 for screenshots). --> +<!ENTITY update.adminDisabled "Updates disabled by your system administrator"> +<!-- LOCALIZATION NOTE (update.otherInstanceHandlingUpdates): try to make the localized text short --> +<!ENTITY update.otherInstanceHandlingUpdates "&brandShortName; is being updated by another instance"> + +<!-- LOCALIZATION NOTE (update.failed.start,update.failed.linkText,update.failed.end): + update.failed.start, update.failed.linkText, and update.failed.end all go into + one line with linkText being wrapped in an anchor that links to a site to download + the latest version of Firefox (e.g. http://www.firefox.com). As this is all in + one line, try to make the localized text short (see bug 596813 for screenshots). --> +<!ENTITY update.failed.start "Update failed. "> +<!ENTITY update.failed.linkText "Download the latest version"> +<!ENTITY update.failed.end ""> + +<!-- LOCALIZATION NOTE (update.manual.start,update.manual.end): update.manual.start and update.manual.end + all go into one line and have an anchor in between with text that is the same as the link to a site + to download the latest version of Firefox (e.g. http://www.firefox.com). As this is all in one line, + try to make the localized text short (see bug 596813 for screenshots). --> +<!ENTITY update.manual.start "Updates available at "> +<!ENTITY update.manual.end ""> + +<!-- LOCALIZATION NOTE (update.unsupported.start,update.unsupported.linkText,update.unsupported.end): + update.unsupported.start, update.unsupported.linkText, and + update.unsupported.end all go into one line with linkText being wrapped in + an anchor that links to a site to provide additional information regarding + why the system is no longer supported. As this is all in one line, try to + make the localized text short (see bug 843497 for screenshots). --> +<!ENTITY update.unsupported.start "You can not perform further updates on this system. "> +<!ENTITY update.unsupported.linkText "Learn more"> +<!ENTITY update.unsupported.end ""> + +<!-- LOCALIZATION NOTE (update.downloading.start,update.downloading.end): update.downloading.start and + update.downloading.end all go into one line, with the amount downloaded inserted in between. As this + is all in one line, try to make the localized text short (see bug 596813 for screenshots). The — is + the "em dash" (long dash). + example: Downloading update — 111 KB of 13 MB --> +<!ENTITY update.downloading.start "Downloading update — "> +<!ENTITY update.downloading.end ""> + +<!ENTITY update.applying "Applying update…"> + +<!-- LOCALIZATION NOTE (channel.description.start,channel.description.end): channel.description.start and + channel.description.end create one sentence, with the current channel label inserted in between. + example: You are currently on the _Stable_ update channel. --> +<!ENTITY channel.description.start "You are currently on the "> +<!ENTITY channel.description.end " update channel. "> + +<!ENTITY project.start "&brandShortName; is developed by "> +<!-- LOCALIZATION NOTE (project.tpoLink): This is a link title that links to https://www.torproject.org --> +<!ENTITY project.tpoLink "the &vendorShortName;"> +<!ENTITY project.end ", a nonprofit working to defend your privacy and freedom online."> + +<!ENTITY help.start "Want to help? "> +<!-- LOCALIZATION NOTE (help.donate): This is a link title that links to https://www.torproject.org/donate/donate.html.en --> +<!ENTITY help.donateLink "Donate"> +<!ENTITY help.or " or "> +<!-- LOCALIZATION NOTE (help.getInvolvedLink): This is a link title that links to https://www.torproject.org/getinvolved/volunteer.html.en --> +<!ENTITY help.getInvolvedLink "get involved"> +<!ENTITY help.end "!"> +<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to https://www.torproject.org/docs/trademark-faq.html.en --> +<!ENTITY bottomLinks.questions "Questions?"> +<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to https://www.torproject.org/getinvolved/relays --> +<!ENTITY bottomLinks.grow "Help the Tor Network Grow!"> +<!-- LOCALIZATION NOTE (bottom.questions): This is a link title that links to about:license --> +<!ENTITY bottomLinks.license "Licensing Information"> +<!ENTITY tor.TrademarkStatement "'Tor' and the 'Onion Logo' are registered trademarks of the Tor Project, Inc."> diff --git a/projects/instantbird/aboutDialog.js b/projects/instantbird/aboutDialog.js new file mode 100644 index 0000000..55043af --- /dev/null +++ b/projects/instantbird/aboutDialog.js @@ -0,0 +1,69 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Services = object with smart getters for common XPCOM services +Components.utils.import("resource://gre/modules/Services.jsm"); +Components.utils.import("resource://gre/modules/AppConstants.jsm"); + +const PREF_EM_HOTFIX_ID = "extensions.hotfix.id"; + +function init(aEvent) +{ + if (aEvent.target != document) + return; + + try { + var distroId = Services.prefs.getCharPref("distribution.id"); + if (distroId) { + var distroVersion = Services.prefs.getCharPref("distribution.version"); + + var distroIdField = document.getElementById("distributionId"); + distroIdField.value = distroId + " - " + distroVersion; + distroIdField.style.display = "block"; + + try { + // This is in its own try catch due to bug 895473 and bug 900925. + var distroAbout = Services.prefs.getComplexValue("distribution.about", + Components.interfaces.nsISupportsString); + var distroField = document.getElementById("distribution"); + distroField.value = distroAbout; + distroField.style.display = "block"; + } + catch (ex) { + // Pref is unset + Components.utils.reportError(ex); + } + } + } + catch (e) { + // Pref is unset + } + + // Include the build ID and display warning if this is an "a#" (nightly or aurora) build + let version = Services.appinfo.version; + if (/a\d+$/.test(version)) { + let buildID = Services.appinfo.appBuildID; + let buildDate = buildID.slice(0,4) + "-" + buildID.slice(4,6) + "-" + buildID.slice(6,8); + document.getElementById("version").textContent += " (" + buildDate + ")"; + document.getElementById("experimental").hidden = false; + document.getElementById("communityDesc").hidden = true; + } + + if (AppConstants.MOZ_UPDATER) { + gAppUpdater = new appUpdater(); + + let defaults = Services.prefs.getDefaultBranch(""); + let channelLabel = document.getElementById("currentChannel"); + let currentChannelText = document.getElementById("currentChannelText"); + channelLabel.value = UpdateUtils.UpdateChannel; + if (/^release($|-)/.test(channelLabel.value)) + currentChannelText.hidden = true; + } + + if (AppConstants.platform == "macosx") { + // it may not be sized at this point, and we need its width to calculate its position + window.sizeToContent(); + window.moveTo((screen.availWidth / 2) - (window.outerWidth / 2), screen.availHeight / 5); + } +} diff --git a/projects/instantbird/aboutDialog.xul b/projects/instantbird/aboutDialog.xul new file mode 100644 index 0000000..642dce4 --- /dev/null +++ b/projects/instantbird/aboutDialog.xul @@ -0,0 +1,192 @@ +<?xml version="1.0"?> <!-- -*- Mode: HTML -*- --> + +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> +<?xml-stylesheet href="chrome://instantbird/content/aboutDialog.css" type="text/css"?> +<?xml-stylesheet href="chrome://branding/content/aboutDialog.css" type="text/css"?> + +<!DOCTYPE window [ +<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" > +%brandDTD; +<!ENTITY % aboutDialogDTD SYSTEM "chrome://instantbird/locale/aboutDialog.dtd" > +%aboutDialogDTD; +]> + +#ifdef XP_MACOSX +<?xul-overlay href="chrome://instantbird/content/macBrowserOverlay.xul"?> +#endif + +<window xmlns:html="http://www.w3.org/1999/xhtml" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + id="aboutDialog" + windowtype="Browser:About" + onload="init(event);" +#ifdef MOZ_UPDATER + onunload="onUnload(event);" +#endif +#ifdef XP_MACOSX + inwindowmenu="false" +#else + title="&aboutDialog.title;" +#endif + role="dialog" + aria-describedby="version distribution distributionId communityDesc contributeDesc trademark" + > + + <script type="application/javascript" src="chrome://instantbird/content/aboutDialog.js"/> +#ifdef MOZ_UPDATER + <script type="application/javascript" src="chrome://instantbird/content/aboutDialog-appUpdater.js"/> +#endif + <vbox id="aboutDialogContainer"> + <hbox id="clientBox"> + <vbox id="leftBox" flex="1"/> + <vbox id="rightBox" flex="1"> +#expand <label id="version">__MOZ_APP_VERSION_DISPLAY__</label> + <label id="distribution" class="text-blurb"/> + <label id="distributionId" class="text-blurb"/> + + <vbox id="detailsBox"> + <vbox id="updateBox"> +#ifdef MOZ_UPDATER + <deck id="updateDeck" orient="vertical"> + <hbox id="checkForUpdates" align="center"> + <button id="checkForUpdatesButton" align="start" + label="&update.checkForUpdatesButton.label;" + accesskey="&update.checkForUpdatesButton.accesskey;" + oncommand="gAppUpdater.checkForUpdates();"/> + <spacer flex="1"/> + </hbox> + <hbox id="downloadAndInstall" align="center"> + <button id="downloadAndInstallButton" align="start" + oncommand="gAppUpdater.doUpdate();"/> + <!-- label and accesskey will be filled by JS --> + <spacer flex="1"/> + </hbox> + <hbox id="apply" align="center"> + <button id="updateButton" align="start" + label="&update.updateButton.label2;" + accesskey="&update.updateButton.accesskey;" + oncommand="gAppUpdater.buttonRestartAfterDownload();"/> + <spacer flex="1"/> + </hbox> + <hbox id="applyBillboard" align="center"> + <button id="applyButtonBillboard" align="start" + label="&update.applyButtonBillboard.label;" + accesskey="&update.applyButtonBillboard.accesskey;" + oncommand="gAppUpdater.buttonApplyBillboard();"/> + <spacer flex="1"/> + </hbox> + <hbox id="checkingForUpdates" align="center"> + <image class="update-throbber"/><label>&update.checkingForUpdates;</label> + </hbox> + <hbox id="downloading" align="center"> + <image class="update-throbber"/><label>&update.downloading.start;</label><label id="downloadStatus"/><label>&update.downloading.end;</label> + </hbox> + <hbox id="applying" align="center"> + <image class="update-throbber"/><label>&update.applying;</label> + </hbox> + <hbox id="downloadFailed" align="center"> + <label>&update.failed.start;</label><label id="failedLink" class="text-link">&update.failed.linkText;</label><label>&update.failed.end;</label> + </hbox> + <hbox id="adminDisabled" align="center"> + <label>&update.adminDisabled;</label> + </hbox> + <hbox id="noUpdatesFound" align="center"> + <label>&update.noUpdatesFound;</label> + </hbox> + <hbox id="otherInstanceHandlingUpdates" align="center"> + <label>&update.otherInstanceHandlingUpdates;</label> + </hbox> + <hbox id="manualUpdate" align="center"> + <label>&update.manual.start;</label><label id="manualLink" class="text-link"/><label>&update.manual.end;</label> + </hbox> + <hbox id="unsupportedSystem" align="center"> + <label>&update.unsupported.start;</label><label id="unsupportedLink" class="text-link">&update.unsupported.linkText;</label><label>&update.unsupported.end;</label> + </hbox> + </deck> +#endif + <description class="text-blurb" id="projectDesc"> + &project.start; + <label class="text-link" + href="https://www.torproject.org/%22%3E + &project.tpoLink; + </label>&project.end; + </description> + <description class="text-blurb" id="helpDesc"> + &help.start; + <label class="text-link" + href="https://www.torproject.org/donate/donate.html.en%22%3E + &help.donateLink; + </label> + &help.or; + <label class="text-link" + href="https://www.torproject.org/getinvolved/volunteer.html.en%22%3E + &help.getInvolvedLink; + </label>&help.end; + </description> + </vbox> + +#ifdef MOZ_UPDATER + <description class="text-blurb" id="currentChannelText"> + &channel.description.start;<label id="currentChannel"/>&channel.description.end; + </description> +#endif + <vbox id="experimental" hidden="true"> + <description class="text-blurb" id="warningDesc"> + &warningDesc.version; +#ifdef MOZ_TELEMETRY_ON_BY_DEFAULT + &warningDesc.telemetryDesc; +#endif + </description> + <description class="text-blurb" id="communityExperimentalDesc"> + &community.exp.start;<label class="text-link" href="http://www.mozilla.org/">&community.exp.mozillaLink;</label>&community.exp.middle;<label class="text-link" href="about:credits">&community.exp.creditsLink;</label>&community.exp.end; + </description> + </vbox> + <description class="text-blurb" id="communityDesc"> + &community.start2;<label class="text-link" href="http://www.mozilla.org/">&community.mozillaLink;</label>&community.middle2;<label class="text-link" href="about:credits">&community.creditsLink;</label>&community.end3; + </description> + <description class="text-blurb" id="contributeDesc"> + &helpus.start;<label class="text-link" href="https://sendto.mozilla.org/page/contribute/Give-Now?source=mozillaorg_default_footer&ref=firefox_about&utm_campaign=firefox_about&tm_source=firefox&tm_medium=referral&utm_content=20140929_FireFoxAbout">&helpus.donateLink;</label>&helpus.middle;<label class="text-link" href="http://www.mozilla.org/contribute/">&helpus.getInvolvedLink;</label>&helpus.end; + </description> + </vbox> + </vbox> + </hbox> + <vbox id="bottomBox"> + <hbox pack="center"> + <label class="text-link bottom-link" href="about:license">&bottomLinks.license;</label> + <label class="text-link bottom-link" href="about:rights">&bottomLinks.rights;</label> + <label class="text-link bottom-link" href="https://www.mozilla.org/privacy/">&bottomLinks.privacy;</label> + </hbox> + <description id="trademark">&trademarkInfo.part1;</description> + </vbox> + <hbox id="newBottom" pack="center" position="1"> + <label class="text-link bottom-link" + href="https://www.torproject.org/docs/faq.html.en%22%3E + &bottomLinks.questions; + </label> + <label class="text-link bottom-link" + href="https://www.torproject.org/getinvolved/relays%22%3E + &bottomLinks.grow; + </label> + <label class="text-link bottom-link" + href="about:license"> + &bottomLinks.license; + </label> + </hbox> + <description id="trademarkTor" insertafter="trademark"> + &tor.TrademarkStatement; + </description> + + </vbox> + + <keyset> + <key keycode="VK_ESCAPE" oncommand="window.close();"/> + </keyset> + +#ifdef XP_MACOSX +#include browserMountPoints.inc +#endif +</window> diff --git a/projects/instantbird/branding-aboutDialog.css b/projects/instantbird/branding-aboutDialog.css new file mode 100644 index 0000000..9a3c04e --- /dev/null +++ b/projects/instantbird/branding-aboutDialog.css @@ -0,0 +1,48 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#clientBox { + background-color: #F7F7F7; + color: #222222; +} + +#leftBox { + background-image: url("chrome://branding/content/about-logo.png"); + background-position: right top; + background-repeat: no-repeat; + background-size: 180px; + /* min-width and min-height create room for the logo */ + min-width: 210px; + min-height: 210px; + margin-top: 20px; + -moz-margin-start: 30px; +} + + +@media (min-resolution: 2dppx) { + #leftBox { + background-image: url("chrome://branding/content/about-logo@2x.png"); + } +} + +#rightBox { + margin-left: 30px; + margin-right: 30px; +} + +#updateDeck > hbox > label:not([class="text-link"]) { + color: #909090; +} + +#trademark { + display: none; +} + +#contributeDesc { + display: none; +} + +#communityDesc { + display: none; +} diff --git a/projects/instantbird/branding/jar.patch b/projects/instantbird/branding/jar.patch new file mode 100644 index 0000000..7254d77 --- /dev/null +++ b/projects/instantbird/branding/jar.patch @@ -0,0 +1,11 @@ +diff --git a/im/branding/messenger/jar.mn b/im/branding/messenger/jar.mn +--- a/im/branding/messenger/jar.mn ++++ b/im/branding/messenger/jar.mn +@@ -8,3 +8,7 @@ + content/branding/about-footer.png (content/about-footer.png) + content/branding/about.png (content/about.png) + content/branding/icon64.png (content/icon64.png) ++ content/branding/aboutDialog.css (content/aboutDialog.css) ++ content/branding/about-logo.png (content/about-logo.png) ++ content/branding/about-logo@2x.png (content/about-logo@2x.png) ++ content/branding/about-wordmark.png (content/about-wordmark.png) diff --git a/projects/instantbird/build b/projects/instantbird/build index 7c4c211..1b8b058 100644 --- a/projects/instantbird/build +++ b/projects/instantbird/build @@ -69,9 +69,16 @@ cp $rootdir/branding/default.ico im/branding/messenger/windows/ cp $rootdir/branding/instantbird.ico im/branding/messenger/ cp $rootdir/branding/instantbird.icns im/branding/messenger/
-cp $rootdir/branding/about.png im/branding/messenger/content/ +cp $rootdir/about-logo.png im/branding/messenger/content/ +cp $rootdir/about-logo@2x.png im/branding/messenger/content/ +cp $rootdir/about-wordmark.png im/branding/messenger/content/
-echo '<!ENTITY tmVersion "[% c('var/tormessenger_version') %]">' >> im/locales/en-US/chrome/instantbird/aboutDialog.dtd +cp $rootdir/branding-aboutDialog.css im/branding/messenger/content/aboutDialog.css + +rm im/content/aboutDialog* + +cp $rootdir/aboutDialog* im/content/ +cp $rootdir/aboutDialog.dtd im/locales/en-US/chrome/instantbird/aboutDialog.dtd
cd mozilla if ls -1 $rootdir/*.mozpatch > /dev/null 2>&1 diff --git a/projects/instantbird/config b/projects/instantbird/config index bd8b4f1..324afd7 100644 --- a/projects/instantbird/config +++ b/projects/instantbird/config @@ -94,7 +94,18 @@ input_files: - filename: branding/name.patch - filename: branding/instantbird.icns - filename: branding/credits.patch + - filename: branding/jar.patch - filename: branding/about.png + - filename: aboutDialog.xul + - filename: aboutDialog.js + - filename: aboutDialog-appUpdater.js + - filename: aboutDialog-jar.patch + - filename: aboutDialog.css + - filename: aboutDialog.dtd + - filename: about-logo.png + - filename: about-logo@2x.png + - filename: about-wordmark.png + - filename: branding-aboutDialog.css - filename: branding/osx.patch enable: '[% c("var/osx") %]' - filename: bug-1218193.patch