tor-commits
Threads by month
- ----- 2025 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
July 2016
- 21 participants
- 1271 discussions

[tor-messenger-build/updater] Fix typo in Firefox-update-process-bug-4234.mozpatch
by sukhbir@torproject.org 29 Jul '16
by sukhbir@torproject.org 29 Jul '16
29 Jul '16
commit b61a35f82e5b19420a532c7970dc28c11870fd1f
Author: Sukhbir Singh <sukhbir(a)torproject.org>
Date: Mon Jul 18 17:34:44 2016 -0400
Fix typo in Firefox-update-process-bug-4234.mozpatch
---
projects/instantbird/Firefox-update-process-bug-4234.mozpatch | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/projects/instantbird/Firefox-update-process-bug-4234.mozpatch b/projects/instantbird/Firefox-update-process-bug-4234.mozpatch
index a02d80b..8df0b37 100644
--- a/projects/instantbird/Firefox-update-process-bug-4234.mozpatch
+++ b/projects/instantbird/Firefox-update-process-bug-4234.mozpatch
@@ -265,7 +265,7 @@ index 38df30e..e9fb038 100644
dnl ========================================================
+dnl Tor Additions
+dnl ========================================================
-+MOZ_ARG_WITH_STRING(eor-browser-version,
++MOZ_ARG_WITH_STRING(tor-browser-version,
+[ --with-tor-browser-version=VERSION
+ Set Tor Browser version, e.g., 4.0b1],
+ TOR_BROWSER_VERSION="$withval")
1
0

[tor-messenger-build/updater] Update preferences.patch to enable automatic updates
by sukhbir@torproject.org 29 Jul '16
by sukhbir@torproject.org 29 Jul '16
29 Jul '16
commit 034689db110dc139bc912c6d16a378504a032296
Author: Sukhbir Singh <sukhbir(a)torproject.org>
Date: Thu Jul 14 12:18:57 2016 -0400
Update preferences.patch to enable automatic updates
---
projects/instantbird/preferences.patch | 77 +++++++++++++++++-----------------
1 file changed, 38 insertions(+), 39 deletions(-)
diff --git a/projects/instantbird/preferences.patch b/projects/instantbird/preferences.patch
index 1d49421..270dbe1 100644
--- a/projects/instantbird/preferences.patch
+++ b/projects/instantbird/preferences.patch
@@ -35,31 +35,39 @@ diff --git a/im/app/profile/all-instantbird.js b/im/app/profile/all-instantbird.
pref("font.default.x-western", "sans-serif");
pref("font.default.x-unicode", "sans-serif");
-@@ -115,12 +115,12 @@
- pref("accessibility.typeaheadfind.flashBar", 1);
-
- // Whether or not app updates are enabled
--pref("app.update.enabled", true);
-+pref("app.update.enabled", false);
-
- // This preference turns on app.update.mode and allows automatic download and
- // install to take place. We use a separate boolean toggle for this to make
- // the UI easier to construct.
--pref("app.update.auto", true);
-+pref("app.update.auto", false);
-
- // Defines how the Application Update Service notifies the user about updates:
- //
-@@ -138,7 +138,7 @@
-
- // If set to true, the Update Service will apply updates in the background
- // when it finishes downloading them.
--pref("app.update.staging.enabled", true);
-+pref("app.update.staging.enabled", false);
+@@ -142,26 +142,23 @@
// Update service URL:
// You do not need to use all the %VAR% parameters. Use what you need, %PRODUCT%,%VERSION%,%BUILD_ID%,%CHANNEL% for example
-@@ -202,7 +202,7 @@
+-pref("app.update.url", "https://update.instantbird.org/1/%PRODUCT%/%VERSION%/%BUILD_ID%/%BUILD_TARG…");
++pref("app.update.url", "https://www.torproject.org/dist/tormessenger/update_2/%CHANNEL%/%BUILD_TARG…");
+
+ // URL user can browse to manually if for some reason all update installation
+ // attempts fail.
+-pref("app.update.url.manual", "http://www.instantbird.com/download.html");
++pref("app.update.url.manual", "https://www.torproject.org/download/download-easy.html");
+
+ // A default value for the "More information about this update" link
+ // supplied in the "An update is available" page of the update wizard.
+-pref("app.update.url.details", "http://www.instantbird.com/");
+-
+-// User-settable override to app.update.url for testing purposes.
+-//pref("app.update.url.override", "");
++pref("app.update.url.details", "https://trac.torproject.org/projects/tor/wiki/doc/TorMessenger");
+
+ // Interval: Time between checks for a new version (in seconds)
+ // default=1 day
+-pref("app.update.interval", 86400);
++pref("app.update.interval", 43200);
+
+ // Interval: Time before prompting the user to download a new version that
+ // is available (in seconds) default=1 day
+-pref("app.update.nagTimer.download", 86400);
++pref("app.update.nagTimer.download", 3600);
+
+ // Interval: Time before prompting the user to restart to install the latest
+ // download (in seconds) default=30 minutes
+@@ -202,7 +199,7 @@
pref("browser.search.order.2", "chrome://instantbird/locale/region.properties");
// send ping to the server to update
@@ -68,20 +76,7 @@ diff --git a/im/app/profile/all-instantbird.js b/im/app/profile/all-instantbird.
// disable logging for the search service update system by default
pref("browser.search.update.log", false);
-@@ -222,10 +222,10 @@
- pref("extensions.logging.enabled", false);
- pref("general.skins.selectedSkin", "classic/1.0");
-
--pref("extensions.update.enabled", true);
-+pref("extensions.update.enabled", false);
- pref("extensions.update.interval", 86400);
- pref("extensions.update.url", "https://addons.instantbird.org/services/update.php?reqVersion=%REQ_VERSION%…");
--pref("extensions.update.autoUpdateDefault", true);
-+pref("extensions.update.autoUpdateDefault", false);
-
- // Preferences for the Get Add-ons pane
- pref("extensions.getAddons.cache.enabled", false);
-@@ -245,9 +245,9 @@
+@@ -245,9 +242,9 @@
pref("extensions.getMoreProtocolsURL", "https://add-ons.instantbird.org/%LOCALE%/%APP%/%VERSION%/protocols/");
// suppress external-load warning for standard browser schemes
@@ -94,7 +89,7 @@ diff --git a/im/app/profile/all-instantbird.js b/im/app/profile/all-instantbird.
// don't load links inside Instantbird
pref("network.protocol-handler.expose-all", false);
-@@ -262,7 +262,7 @@
+@@ -262,10 +259,10 @@
pref("network.protocol-handler.expose.javascript", true);
// 0-Accept, 1-dontAcceptForeign, 2-dontUse
@@ -102,8 +97,12 @@ diff --git a/im/app/profile/all-instantbird.js b/im/app/profile/all-instantbird.
+pref("network.cookie.cookieBehavior", 1);
// The breakpad report server to link to in about:crashes
- pref("breakpad.reportURL", "http://crash-stats.instantbird.com/report/index/");
-@@ -300,14 +300,70 @@
+-pref("breakpad.reportURL", "http://crash-stats.instantbird.com/report/index/");
++pref("breakpad.reportURL", "https://crash-stats.instantbird.com/report/index/");
+
+ // We have an Error Console menu item by default so let's display chrome errors
+ pref("javascript.options.showInConsole", true);
+@@ -300,14 +297,70 @@
// 3 at the end of the tabstrip
pref("browser.tabs.closeButtons", 1);
1
0
commit d4f35015683bedf07194f3982e080641eb0ff27f
Author: Sukhbir Singh <sukhbir(a)torproject.org>
Date: Mon Jul 18 12:40:15 2016 -0400
Add patch for #14631
---
...Improve-profile-access-bug-14631-first.mozpatch | 246 +++++++++++++++++++++
...mprove-profile-access-bug-14631-second.mozpatch | 182 +++++++++++++++
2 files changed, 428 insertions(+)
diff --git a/projects/instantbird/Improve-profile-access-bug-14631-first.mozpatch b/projects/instantbird/Improve-profile-access-bug-14631-first.mozpatch
new file mode 100644
index 0000000..7a9ad68
--- /dev/null
+++ b/projects/instantbird/Improve-profile-access-bug-14631-first.mozpatch
@@ -0,0 +1,246 @@
+commit 5aae044b37579dc1c95b195084bcfcdaed352545
+Author: Kathy Brade <brade(a)pearlcrescent.com>
+Date: Tue Feb 24 13:50:23 2015 -0500
+
+ Bug 14631: Improve profile access error messages.
+
+ Instead of always reporting that the profile is locked, display specific
+ messages for "access denied" and "read-only file system".
+
+diff --git a/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties b/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties
+index adac95a..3cf48ff 100644
+--- a/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties
++++ b/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties
+@@ -12,6 +12,11 @@ restartMessageUnlocker=%S is already running, but is not responding. The old %S
+ restartMessageNoUnlockerMac=A copy of %S is already open. Only one copy of %S can be open at a time.
+ restartMessageUnlockerMac=A copy of %S is already open. The running copy of %S will quit in order to open this one.
+
++# LOCALIZATION NOTE (profileProblemTitle, profileReadOnly, profileReadOnlyMac, profileAccessDenied): Messages displayed when the browser profile cannot be accessed or written to. %S is the application name.
++profileProblemTitle=%S Profile Problem
++profileReadOnly=You cannot run %S from a read-only file system. Please copy %S to another location before trying to use it.
++profileReadOnlyMac=You cannot run %S from a read-only file system. Please copy %S to your Desktop or Applications folder before trying to use it.
++profileAccessDenied=%S does not have permission to access the profile. Please adjust your file system permissions and try again.
+ # Profile manager
+ # LOCALIZATION NOTE (profileTooltip): First %S is the profile name, second %S is the path to the profile folder.
+ profileTooltip=Profile: '%S' - Path: '%S'
+diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp
+index da73cd5..d82f303 100644
+--- a/toolkit/xre/nsAppRunner.cpp
++++ b/toolkit/xre/nsAppRunner.cpp
+@@ -1913,6 +1913,14 @@ static nsresult LaunchChild(nsINativeAppSupport* aNative,
+ return NS_ERROR_LAUNCHED_CHILD_PROCESS;
+ }
+
++enum ProfileStatus {
++ PROFILE_STATUS_OK,
++ PROFILE_STATUS_ACCESS_DENIED,
++ PROFILE_STATUS_READ_ONLY,
++ PROFILE_STATUS_IS_LOCKED,
++ PROFILE_STATUS_OTHER_ERROR
++};
++
+ static const char kProfileProperties[] =
+ "chrome://mozapps/locale/profile/profileSelection.properties";
+
+@@ -1951,9 +1959,9 @@ private:
+ } // namespace
+
+ static ReturnAbortOnError
+-ProfileLockedDialog(nsIFile* aProfileDir, nsIFile* aProfileLocalDir,
+- nsIProfileUnlocker* aUnlocker,
+- nsINativeAppSupport* aNative, nsIProfileLock* *aResult)
++ProfileErrorDialog(nsIFile* aProfileDir, nsIFile* aProfileLocalDir,
++ ProfileStatus aStatus, nsIProfileUnlocker* aUnlocker,
++ nsINativeAppSupport* aNative, nsIProfileLock* *aResult)
+ {
+ nsresult rv;
+
+@@ -1980,18 +1988,31 @@ ProfileLockedDialog(nsIFile* aProfileDir, nsIFile* aProfileLocalDir,
+
+ nsXPIDLString killMessage;
+ #ifndef XP_MACOSX
+- sb->FormatStringFromName(aUnlocker ? MOZ_UTF16("restartMessageUnlocker")
+- : MOZ_UTF16("restartMessageNoUnlocker"),
+- params, 2, getter_Copies(killMessage));
++ static const char16_t kRestartUnlocker[] = MOZ_UTF16("restartMessageUnlocker");
++ static const char16_t kRestartNoUnlocker[] = MOZ_UTF16("restartMessageNoUnlocker");
++ static const char16_t kReadOnly[] = MOZ_UTF16("profileReadOnly");
+ #else
+- sb->FormatStringFromName(aUnlocker ? MOZ_UTF16("restartMessageUnlockerMac")
+- : MOZ_UTF16("restartMessageNoUnlockerMac"),
+- params, 2, getter_Copies(killMessage));
++ static const char16_t kRestartUnlocker[] = MOZ_UTF16("restartMessageUnlockerMac");
++ static const char16_t kRestartNoUnlocker[] = MOZ_UTF16("restartMessageNoUnlockerMac");
++ static const char16_t kReadOnly[] = MOZ_UTF16("profileReadOnlyMac");
+ #endif
++ static const char16_t kAccessDenied[] = MOZ_UTF16("profileAccessDenied");
++
++ const char16_t *errorKey = aUnlocker ? kRestartUnlocker
++ : kRestartNoUnlocker;
++ if (PROFILE_STATUS_READ_ONLY == aStatus)
++ errorKey = kReadOnly;
++ else if (PROFILE_STATUS_ACCESS_DENIED == aStatus)
++ errorKey = kAccessDenied;
++ sb->FormatStringFromName(errorKey, params, 2, getter_Copies(killMessage));
++
++ const char16_t *titleKey = ((PROFILE_STATUS_READ_ONLY == aStatus) ||
++ (PROFILE_STATUS_ACCESS_DENIED == aStatus))
++ ? MOZ_UTF16("profileProblemTitle")
++ : MOZ_UTF16("restartTitle");
+
+ nsXPIDLString killTitle;
+- sb->FormatStringFromName(MOZ_UTF16("restartTitle"),
+- params, 1, getter_Copies(killTitle));
++ sb->FormatStringFromName(titleKey, params, 1, getter_Copies(killTitle));
+
+ if (!killMessage || !killTitle)
+ return NS_ERROR_FAILURE;
+@@ -2092,8 +2113,9 @@ ProfileMissingDialog(nsINativeAppSupport* aNative)
+ }
+
+ static nsresult
+-ProfileLockedDialog(nsIToolkitProfile* aProfile, nsIProfileUnlocker* aUnlocker,
+- nsINativeAppSupport* aNative, nsIProfileLock* *aResult)
++ProfileErrorDialog(nsIToolkitProfile* aProfile, ProfileStatus aStatus,
++ nsIProfileUnlocker* aUnlocker, nsINativeAppSupport* aNative,
++ nsIProfileLock* *aResult)
+ {
+ nsCOMPtr<nsIFile> profileDir;
+ nsresult rv = aProfile->GetRootDir(getter_AddRefs(profileDir));
+@@ -2109,8 +2131,8 @@ ProfileLockedDialog(nsIToolkitProfile* aProfile, nsIProfileUnlocker* aUnlocker,
+ rv = aProfile->GetLocalDir(getter_AddRefs(profileLocalDir));
+ if (NS_FAILED(rv)) return rv;
+
+- return ProfileLockedDialog(profileDir, profileLocalDir, aUnlocker, aNative,
+- aResult);
++ return ProfileErrorDialog(profileDir, profileLocalDir, aStatus, aUnlocker,
++ aNative, aResult);
+ }
+
+ static const char kProfileManagerURL[] =
+@@ -2275,6 +2297,53 @@ SetCurrentProfileAsDefault(nsIToolkitProfileService* aProfileSvc,
+ return rv;
+ }
+
++// Check for write permission to the profile directory by trying to create a
++// new file (after ensuring that no file with the same name exists).
++static ProfileStatus CheckProfileWriteAccess(nsIFile* aProfileDir)
++{
++#if defined(XP_UNIX)
++ NS_NAMED_LITERAL_STRING(writeTestFileName, ".parentwritetest");
++#else
++ NS_NAMED_LITERAL_STRING(writeTestFileName, "parent.writetest");
++#endif
++
++ nsCOMPtr<nsIFile> writeTestFile;
++ nsresult rv = aProfileDir->Clone(getter_AddRefs(writeTestFile));
++ if (NS_SUCCEEDED(rv))
++ rv = writeTestFile->Append(writeTestFileName);
++
++ if (NS_SUCCEEDED(rv)) {
++ bool doesExist = false;
++ rv = writeTestFile->Exists(&doesExist);
++ if (NS_SUCCEEDED(rv) && doesExist)
++ rv = writeTestFile->Remove(true);
++ }
++
++ if (NS_SUCCEEDED(rv)) {
++ rv = writeTestFile->Create(nsIFile::NORMAL_FILE_TYPE, 0666);
++ (void)writeTestFile->Remove(true);
++ }
++
++ ProfileStatus status = NS_SUCCEEDED(rv) ? PROFILE_STATUS_OK
++ : PROFILE_STATUS_OTHER_ERROR;
++ if (NS_ERROR_FILE_ACCESS_DENIED == rv)
++ status = PROFILE_STATUS_ACCESS_DENIED;
++ else if (NS_ERROR_FILE_READ_ONLY == rv)
++ status = PROFILE_STATUS_READ_ONLY;
++
++ return status;
++}
++
++static ProfileStatus CheckProfileWriteAccess(nsIToolkitProfile* aProfile)
++{
++ nsCOMPtr<nsIFile> profileDir;
++ nsresult rv = aProfile->GetRootDir(getter_AddRefs(profileDir));
++ if (NS_FAILED(rv))
++ return PROFILE_STATUS_OTHER_ERROR;
++
++ return CheckProfileWriteAccess(profileDir);
++}
++
+ static bool gDoMigration = false;
+ static bool gDoProfileReset = false;
+
+@@ -2410,13 +2479,18 @@ SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, n
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
++ ProfileStatus status = CheckProfileWriteAccess(lf);
++ if (PROFILE_STATUS_OK != status)
++ return ProfileErrorDialog(lf, lf, status, nullptr, aNative, aResult);
++
+ // If a profile path is specified directory on the command line, then
+ // assume that the temp directory is the same as the given directory.
+ rv = NS_LockProfilePath(lf, lf, getter_AddRefs(unlocker), aResult);
+ if (NS_SUCCEEDED(rv))
+ return rv;
+
+- return ProfileLockedDialog(lf, lf, unlocker, aNative, aResult);
++ return ProfileErrorDialog(lf, lf, PROFILE_STATUS_IS_LOCKED, unlocker,
++ aNative, aResult);
+ }
+
+ ar = CheckArg("createprofile", true, &arg);
+@@ -2501,6 +2575,10 @@ SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, n
+ gDoProfileReset = false;
+ }
+
++ ProfileStatus status = CheckProfileWriteAccess(profile);
++ if (PROFILE_STATUS_OK != status)
++ return ProfileErrorDialog(profile, status, nullptr, aNative, aResult);
++
+ nsCOMPtr<nsIProfileUnlocker> unlocker;
+ rv = profile->Lock(getter_AddRefs(unlocker), aResult);
+ if (NS_SUCCEEDED(rv)) {
+@@ -2509,7 +2587,8 @@ SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, n
+ return NS_OK;
+ }
+
+- return ProfileLockedDialog(profile, unlocker, aNative, aResult);
++ return ProfileErrorDialog(profile, PROFILE_STATUS_IS_LOCKED, unlocker,
++ aNative, aResult);
+ }
+
+ if (CanShowProfileManager()) {
+@@ -2589,7 +2668,8 @@ SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, n
+ nsCOMPtr<nsIProfileUnlocker> unlocker;
+ rv = profile->Lock(getter_AddRefs(unlocker), &tempProfileLock);
+ if (NS_FAILED(rv))
+- return ProfileLockedDialog(profile, unlocker, aNative, &tempProfileLock);
++ return ProfileErrorDialog(profile, PROFILE_STATUS_IS_LOCKED,
++ unlocker, aNative, &tempProfileLock);
+ }
+
+ nsCOMPtr<nsIToolkitProfile> newProfile;
+@@ -2600,6 +2680,10 @@ SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, n
+ gDoProfileReset = false;
+ }
+
++ ProfileStatus status = CheckProfileWriteAccess(profile);
++ if (PROFILE_STATUS_OK != status)
++ return ProfileErrorDialog(profile, status, nullptr, aNative, aResult);
++
+ // If you close Firefox and very quickly reopen it, the old Firefox may
+ // still be closing down. Rather than immediately showing the
+ // "Firefox is running but is not responding" message, we spend a few
+@@ -2625,7 +2709,8 @@ SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, n
+ PR_Sleep(kLockRetrySleepMS);
+ } while (TimeStamp::Now() - start < TimeDuration::FromSeconds(kLockRetrySeconds));
+
+- return ProfileLockedDialog(profile, unlocker, aNative, aResult);
++ return ProfileErrorDialog(profile, PROFILE_STATUS_IS_LOCKED, unlocker,
++ aNative, aResult);
+ }
+ }
+
diff --git a/projects/instantbird/Improve-profile-access-bug-14631-second.mozpatch b/projects/instantbird/Improve-profile-access-bug-14631-second.mozpatch
new file mode 100644
index 0000000..3e59cd5
--- /dev/null
+++ b/projects/instantbird/Improve-profile-access-bug-14631-second.mozpatch
@@ -0,0 +1,182 @@
+commit 303992b0684036f6f23d1ca7f76b360930f510db
+Author: Kathy Brade <brade(a)pearlcrescent.com>
+Date: Fri Feb 27 10:38:40 2015 -0500
+
+ Bug 14631: Improve profile access error msgs (strings).
+
+ To allow for localization, get profile-related error strings from Torbutton.
+ Use app display name ("Tor Browser") in profile-related error alerts.
+
+diff --git a/toolkit/xre/moz.build b/toolkit/xre/moz.build
+index d8127a6..3e6a3b6 100644
+--- a/toolkit/xre/moz.build
++++ b/toolkit/xre/moz.build
+@@ -116,8 +116,8 @@ FINAL_LIBRARY = 'xul'
+ if CONFIG['MOZ_GL_DEFAULT_PROVIDER'] == 'GLX':
+ DEFINES['USE_GLX_TEST'] = True
+
+-for var in ('MOZ_APP_NAME', 'MOZ_APP_BASENAME', 'MOZ_APP_VERSION', 'OS_TARGET',
+- 'MOZ_WIDGET_TOOLKIT'):
++for var in ('MOZ_APP_NAME', 'MOZ_APP_BASENAME', 'MOZ_APP_DISPLAYNAME',
++ 'MOZ_APP_VERSION', 'OS_TARGET', 'MOZ_WIDGET_TOOLKIT'):
+ DEFINES[var] = '"%s"' % CONFIG[var]
+
+ if CONFIG['MOZ_UPDATER'] and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android':
+diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp
+index d82f303..a7c7d75 100644
+--- a/toolkit/xre/nsAppRunner.cpp
++++ b/toolkit/xre/nsAppRunner.cpp
+@@ -1913,6 +1913,104 @@ static nsresult LaunchChild(nsINativeAppSupport* aNative,
+ return NS_ERROR_LAUNCHED_CHILD_PROCESS;
+ }
+
++static nsresult
++GetOverrideStringBundleForLocale(nsIStringBundleService* aSBS,
++ const char* aTorbuttonURI, const char* aLocale,
++ nsIStringBundle* *aResult)
++{
++ NS_ENSURE_ARG(aSBS);
++ NS_ENSURE_ARG(aTorbuttonURI);
++ NS_ENSURE_ARG(aLocale);
++ NS_ENSURE_ARG(aResult);
++
++ const char* kFormatStr = "jar:%s!/chrome/locale/%s/torbutton.properties";
++ nsPrintfCString strBundleURL(kFormatStr, aTorbuttonURI, aLocale);
++ nsresult rv = aSBS->CreateBundle(strBundleURL.get(), aResult);
++ NS_ENSURE_SUCCESS(rv, rv);
++
++ // To ensure that we have a valid string bundle, try to retrieve a string
++ // that we know exists.
++ nsXPIDLString val;
++ rv = (*aResult)->GetStringFromName(MOZ_UTF16("profileProblemTitle"),
++ getter_Copies(val));
++ if (!NS_SUCCEEDED(rv))
++ *aResult = nullptr; // No good. Discard it.
++
++ return rv;
++}
++
++static void
++GetOverrideStringBundle(nsIStringBundleService* aSBS, nsIStringBundle* *aResult)
++{
++ if (!aSBS || !aResult)
++ return;
++
++ *aResult = nullptr;
++
++ // Build Torbutton file URI string by starting from the profiles directory.
++ nsXREDirProvider* dirProvider = nsXREDirProvider::GetSingleton();
++ if (!dirProvider)
++ return;
++
++ bool persistent = false; // ignored
++ nsCOMPtr<nsIFile> profilesDir;
++ nsresult rv = dirProvider->GetFile(NS_APP_USER_PROFILES_ROOT_DIR, &persistent,
++ getter_AddRefs(profilesDir));
++ if (NS_FAILED(rv))
++ return;
++
++ // Create file URI, extract as string, and append Torbutton xpi relative path.
++ nsCOMPtr<nsIURI> uri;
++ nsAutoCString uriString;
++ if (NS_FAILED(NS_NewFileURI(getter_AddRefs(uri), profilesDir)) ||
++ NS_FAILED(uri->GetSpec(uriString))) {
++ return;
++ }
++
++ uriString.Append("profile.default/extensions/torbutton(a)torproject.org.xpi");
++
++ nsCString userAgentLocale;
++ if (!NS_SUCCEEDED(Preferences::GetCString("general.useragent.locale",
++ &userAgentLocale))) {
++ return;
++ }
++
++ rv = GetOverrideStringBundleForLocale(aSBS, uriString.get(),
++ userAgentLocale.get(), aResult);
++ if (NS_FAILED(rv)) {
++ // Try again using base locale, e.g., "en" vs. "en-US".
++ int16_t offset = userAgentLocale.FindChar('-', 1);
++ if (offset > 0) {
++ nsAutoCString shortLocale(Substring(userAgentLocale, 0, offset));
++ rv = GetOverrideStringBundleForLocale(aSBS, uriString.get(),
++ shortLocale.get(), aResult);
++ }
++ }
++}
++
++static nsresult
++GetFormattedString(nsIStringBundle* aOverrideBundle,
++ nsIStringBundle* aMainBundle,
++ const char16_t* aName,
++ const char16_t** aParams, uint32_t aLength,
++ char16_t* *aResult)
++{
++ NS_ENSURE_ARG(aName);
++ NS_ENSURE_ARG(aResult);
++
++ nsresult rv = NS_ERROR_FAILURE;
++ if (aOverrideBundle) {
++ rv = aOverrideBundle->FormatStringFromName(aName, aParams, aLength,
++ aResult);
++ }
++
++ // If string was not found in override bundle, use main (browser) bundle.
++ if (NS_FAILED(rv) && aMainBundle)
++ rv = aMainBundle->FormatStringFromName(aName, aParams, aLength, aResult);
++
++ return rv;
++}
++
+ enum ProfileStatus {
+ PROFILE_STATUS_OK,
+ PROFILE_STATUS_ACCESS_DENIED,
+@@ -1983,7 +2081,10 @@ ProfileErrorDialog(nsIFile* aProfileDir, nsIFile* aProfileLocalDir,
+ sbs->CreateBundle(kProfileProperties, getter_AddRefs(sb));
+ NS_ENSURE_TRUE_LOG(sbs, NS_ERROR_FAILURE);
+
+- NS_ConvertUTF8toUTF16 appName(gAppData->name);
++ nsCOMPtr<nsIStringBundle> overrideSB;
++ GetOverrideStringBundle(sbs, getter_AddRefs(overrideSB));
++
++ NS_ConvertUTF8toUTF16 appName(MOZ_APP_DISPLAYNAME);
+ const char16_t* params[] = {appName.get(), appName.get()};
+
+ nsXPIDLString killMessage;
+@@ -1998,21 +2099,23 @@ ProfileErrorDialog(nsIFile* aProfileDir, nsIFile* aProfileLocalDir,
+ #endif
+ static const char16_t kAccessDenied[] = MOZ_UTF16("profileAccessDenied");
+
+- const char16_t *errorKey = aUnlocker ? kRestartUnlocker
++ const char16_t* errorKey = aUnlocker ? kRestartUnlocker
+ : kRestartNoUnlocker;
+ if (PROFILE_STATUS_READ_ONLY == aStatus)
+ errorKey = kReadOnly;
+ else if (PROFILE_STATUS_ACCESS_DENIED == aStatus)
+ errorKey = kAccessDenied;
+- sb->FormatStringFromName(errorKey, params, 2, getter_Copies(killMessage));
++ GetFormattedString(overrideSB, sb, errorKey, params, 2,
++ getter_Copies(killMessage));
+
+- const char16_t *titleKey = ((PROFILE_STATUS_READ_ONLY == aStatus) ||
++ const char16_t* titleKey = ((PROFILE_STATUS_READ_ONLY == aStatus) ||
+ (PROFILE_STATUS_ACCESS_DENIED == aStatus))
+ ? MOZ_UTF16("profileProblemTitle")
+ : MOZ_UTF16("restartTitle");
+
+ nsXPIDLString killTitle;
+- sb->FormatStringFromName(titleKey, params, 1, getter_Copies(killTitle));
++ GetFormattedString(overrideSB, sb, titleKey, params, 1,
++ getter_Copies(killTitle));
+
+ if (!killMessage || !killTitle)
+ return NS_ERROR_FAILURE;
+@@ -2088,7 +2191,7 @@ ProfileMissingDialog(nsINativeAppSupport* aNative)
+ sbs->CreateBundle(kProfileProperties, getter_AddRefs(sb));
+ NS_ENSURE_TRUE_LOG(sbs, NS_ERROR_FAILURE);
+
+- NS_ConvertUTF8toUTF16 appName(gAppData->name);
++ NS_ConvertUTF8toUTF16 appName(MOZ_APP_DISPLAYNAME);
+ const char16_t* params[] = {appName.get(), appName.get()};
+
+ nsXPIDLString missingMessage;
1
0
commit 229c0e968c9b91b8f7125df6df4074862a39a879
Author: Sukhbir Singh <sukhbir(a)torproject.org>
Date: Wed Jul 13 15:42:37 2016 -0400
Rebase jar.mn patches
---
projects/instantbird/aboutDialog-jar.patch | 19 +++++++++++--------
projects/instantbird/branding/jar.patch | 14 +++++++-------
2 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/projects/instantbird/aboutDialog-jar.patch b/projects/instantbird/aboutDialog-jar.patch
index 91f13bf..2a1ed6d 100644
--- a/projects/instantbird/aboutDialog-jar.patch
+++ b/projects/instantbird/aboutDialog-jar.patch
@@ -1,12 +1,15 @@
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 @@
+@@ -9,8 +9,9 @@
+ % overlay chrome://mozapps/content/update/updates.xul chrome://instantbird/content/softwareUpdateOverlay.xul
#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
+ content/instantbird/aboutDialog.css
+-* content/instantbird/aboutDialog.xul
+- content/instantbird/aboutPanel.xml
++ content/instantbird/aboutDialog.xul
++ content/instantbird/aboutDialog.js
++ content/instantbird/aboutDialog-appUpdater.js
+ content/instantbird/account.js
+ content/instantbird/accounts.css
+ content/instantbird/accounts.js
diff --git a/projects/instantbird/branding/jar.patch b/projects/instantbird/branding/jar.patch
index 7254d77..a9648c7 100644
--- a/projects/instantbird/branding/jar.patch
+++ b/projects/instantbird/branding/jar.patch
@@ -2,10 +2,10 @@ 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(a)2x.png (content/about-logo(a)2x.png)
-+ content/branding/about-wordmark.png (content/about-wordmark.png)
+ 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(a)2x.png (content/about-logo(a)2x.png)
++ content/branding/about-wordmark.png (content/about-wordmark.png)
1
0

[tor-messenger-build/updater] ADd patch for #13252 (outside app directory)
by sukhbir@torproject.org 29 Jul '16
by sukhbir@torproject.org 29 Jul '16
29 Jul '16
commit d629613da79e6aaf77a4e1c625f6f83f916e7e80
Author: Sukhbir Singh <sukhbir(a)torproject.org>
Date: Mon Jul 18 12:40:35 2016 -0400
ADd patch for #13252 (outside app directory)
---
.../Mac-outside-app-data-bug-13252.mozpatch | 1124 ++++++++++++++++++++
1 file changed, 1124 insertions(+)
diff --git a/projects/instantbird/Mac-outside-app-data-bug-13252.mozpatch b/projects/instantbird/Mac-outside-app-data-bug-13252.mozpatch
new file mode 100644
index 0000000..a68f446
--- /dev/null
+++ b/projects/instantbird/Mac-outside-app-data-bug-13252.mozpatch
@@ -0,0 +1,1124 @@
+From 4f8084edd80a3726e9a995ff3407331807401558 Mon Sep 17 00:00:00 2001
+From: Kathy Brade <brade(a)pearlcrescent.com>
+Date: Fri, 18 Mar 2016 14:20:02 -0400
+Subject: Bug 13252 - Do not store data in the app bundle
+
+Add an --enable-tor-browser-data-outside-app-dir configure option.
+When this is enabled, all user data is stored in a directory named
+TorBrowser-Data which is located next to the application directory.
+
+The first time an updated browser is opened, migrate the existing
+browser profile, Tor data directory contents, and UpdateInfo to the
+TorBrowser-Data directory. If migration of the browser profile
+fails, an error alert is displayed and the browser is started
+using a new profile.
+
+Display an informative error messages if the TorBrowser-Data
+directory cannot be created due to an "access denied" or a
+"read only volume" error.
+
+Add support for installing "override" preferences within the user's
+browser profile. All .js files in distribution/preferences (on
+Mac OS, Contents/Resources/distribution/preferences) will be copied
+to the preferences directory within the user's browser profile when
+the profile is created and each time Tor Browser is updated. This
+mechanism will be used to install the extension-overrides.js file
+into the profile.
+
+On Mac OS, add support for the --invisible command line option which
+is used by the meek-http-helper to avoid showing an icon for the
+helper browser on the dock.
+
+diff --git a/configure.in b/configure.in
+index e9fb038..885ee84 100644
+--- a/configure.in
++++ b/configure.in
+@@ -6538,9 +6538,20 @@ if test -n "$TOR_BROWSER_UPDATE"; then
+ AC_DEFINE(TOR_BROWSER_UPDATE)
+ fi
+
++MOZ_ARG_ENABLE_BOOL(tor-browser-data-outside-app-dir,
++[ --enable-tor-browser-data-outside-app-dir
++ Enable Tor Browser data outside of app directory],
++ TOR_BROWSER_DATA_OUTSIDE_APP_DIR=1,
++ TOR_BROWSER_DATA_OUTSIDE_APP_DIR= )
++
++if test -n "$TOR_BROWSER_DATA_OUTSIDE_APP_DIR"; then
++ AC_DEFINE(TOR_BROWSER_DATA_OUTSIDE_APP_DIR)
++fi
++
+ AC_DEFINE_UNQUOTED(TOR_BROWSER_VERSION,"$TOR_BROWSER_VERSION")
+ AC_SUBST(TOR_BROWSER_VERSION)
+ AC_SUBST(TOR_BROWSER_UPDATE)
++AC_SUBST(TOR_BROWSER_DATA_OUTSIDE_APP_DIR)
+
+ dnl ========================================================
+ dnl build the tests by default
+diff --git a/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties b/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties
+index 3cf48ff..f5cb77a 100644
+--- a/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties
++++ b/toolkit/locales/en-US/chrome/mozapps/profile/profileSelection.properties
+@@ -17,6 +17,7 @@ profileProblemTitle=%S Profile Problem
+ profileReadOnly=You cannot run %S from a read-only file system. Please copy %S to another location before trying to use it.
+ profileReadOnlyMac=You cannot run %S from a read-only file system. Please copy %S to your Desktop or Applications folder before trying to use it.
+ profileAccessDenied=%S does not have permission to access the profile. Please adjust your file system permissions and try again.
++profileMigrationFailed=Migration of your existing %S profile failed.\nNew settings will be used.
+ # Profile manager
+ # LOCALIZATION NOTE (profileTooltip): First %S is the profile name, second %S is the path to the profile folder.
+ profileTooltip=Profile: '%S' - Path: '%S'
+diff --git a/toolkit/mozapps/extensions/AddonManager.jsm b/toolkit/mozapps/extensions/AddonManager.jsm
+index a453062..e2d4e44 100644
+--- a/toolkit/mozapps/extensions/AddonManager.jsm
++++ b/toolkit/mozapps/extensions/AddonManager.jsm
+@@ -45,6 +45,11 @@ const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
+ const PREF_SELECTED_LOCALE = "general.useragent.locale";
+ const UNKNOWN_XPCOM_ABI = "unknownABI";
+
++#ifdef TOR_BROWSER_VERSION
++#expand const TOR_BROWSER_VERSION = __TOR_BROWSER_VERSION__;
++const PREF_EM_LAST_TORBROWSER_VERSION = "extensions.lastTorBrowserVersion";
++#endif
++
+ const PREF_MIN_WEBEXT_PLATFORM_VERSION = "extensions.webExtensionsMinPlatformVersion";
+
+ const UPDATE_REQUEST_VERSION = 2;
+@@ -910,6 +915,30 @@ var AddonManagerInternal = {
+ this.validateBlocklist();
+ }
+
++#ifdef TOR_BROWSER_VERSION
++ // To ensure that extension override prefs are reinstalled into the
++ // user's profile after each update, set appChanged = true if the
++ // Mozilla app version has not changed but the Tor Browser version
++ // has changed.
++ let tbChanged = undefined;
++ try {
++ tbChanged = TOR_BROWSER_VERSION !=
++ Services.prefs.getCharPref(PREF_EM_LAST_TORBROWSER_VERSION);
++ }
++ catch (e) { }
++ if (tbChanged !== false) {
++ // Because PREF_EM_LAST_TORBROWSER_VERSION was not present in older
++ // versions of Tor Browser, an app change is indicated when tbChanged
++ // is undefined or true.
++ if (appChanged === false) {
++ appChanged = true;
++ }
++
++ Services.prefs.setCharPref(PREF_EM_LAST_TORBROWSER_VERSION,
++ TOR_BROWSER_VERSION);
++ }
++#endif
++
+ if (!MOZ_COMPATIBILITY_NIGHTLY) {
+ PREF_EM_CHECK_COMPATIBILITY = PREF_EM_CHECK_COMPATIBILITY_BASE + "." +
+ Services.appinfo.version.replace(BRANCH_REGEXP, "$1");
+diff --git a/toolkit/mozapps/extensions/internal/XPIProvider.jsm b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+index 7a58a7d..51c51b8 100644
+--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
++++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+@@ -130,6 +130,7 @@ const URI_EXTENSION_STRINGS = "chrome://mozapps/locale/extensions/exte
+ const STRING_TYPE_NAME = "type.%ID%.name";
+
+ const DIR_EXTENSIONS = "extensions";
++const DIR_PREFERENCES = "preferences";
+ const DIR_SYSTEM_ADDONS = "features";
+ const DIR_STAGE = "staged";
+ const DIR_TRASH = "trash";
+@@ -3510,6 +3511,58 @@ this.XPIProvider = {
+ return changed;
+ },
+
++ /**
++ * Installs any preference files located in the preferences directory of the
++ * application's distribution specific directory into the profile.
++ *
++ * @return true if any preference files were installed
++ */
++ installDistributionPreferences: function XPI_installDistributionPreferences() {
++ let distroDir;
++ try {
++ distroDir = FileUtils.getDir(KEY_APP_DISTRIBUTION, [DIR_PREFERENCES]);
++ }
++ catch (e) {
++ return false;
++ }
++
++ if (!distroDir.exists() || !distroDir.isDirectory())
++ return false;
++
++ let changed = false;
++ let prefOverrideDir = Services.dirsvc.get("PrefDOverride", Ci.nsIFile);
++
++ let entries = distroDir.directoryEntries
++ .QueryInterface(Ci.nsIDirectoryEnumerator);
++ let entry;
++ while ((entry = entries.nextFile)) {
++ let fileName = entry.leafName;
++ if (!entry.isFile() ||
++ fileName.substring(fileName.length - 3).toLowerCase() != ".js") {
++ logger.debug("Ignoring distribution preference that isn't a JS file: "
++ + entry.path);
++ continue;
++ }
++
++ try {
++ if (!prefOverrideDir.exists()) {
++ prefOverrideDir.create(Ci.nsIFile.DIRECTORY_TYPE,
++ FileUtils.PERMS_DIRECTORY);
++ }
++
++ entry.copyTo(prefOverrideDir, null);
++ changed = true;
++ } catch (e) {
++ logger.debug("Unable to copy " + entry.path + " to " +
++ prefOverrideDir.path);
++ }
++ }
++
++ entries.close();
++
++ return changed;
++ },
++
+ /**
+ * Imports the xpinstall permissions from preferences into the permissions
+ * manager for the user to change later.
+@@ -3583,6 +3636,12 @@ this.XPIProvider = {
+ if (updated) {
+ updateReasons.push("installDistributionAddons");
+ }
++
++ // Also copy distribution preferences to the user's profile.
++ updated = this.installDistributionPreferences();
++ if (updated) {
++ updateReasons.push("installDistributionPreferences");
++ }
+ }
+
+ // Telemetry probe added around getInstallState() to check perf
+diff --git a/toolkit/mozapps/extensions/moz.build b/toolkit/mozapps/extensions/moz.build
+index 8fbd96d..06091a5 100644
+--- a/toolkit/mozapps/extensions/moz.build
++++ b/toolkit/mozapps/extensions/moz.build
+@@ -30,12 +30,15 @@ EXTRA_PP_COMPONENTS += [
+ ]
+
+ EXTRA_JS_MODULES += [
+- 'AddonManager.jsm',
+ 'ChromeManifestParser.jsm',
+ 'DeferredSave.jsm',
+ 'LightweightThemeManager.jsm',
+ ]
+
++EXTRA_PP_JS_MODULES += [
++ 'AddonManager.jsm',
++]
++
+ JAR_MANIFESTS += ['jar.mn']
+
+ EXPORTS.mozilla += [
+diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp
+index a3a2857..20be296 100644
+--- a/toolkit/xre/nsAppRunner.cpp
++++ b/toolkit/xre/nsAppRunner.cpp
+@@ -1949,11 +1949,30 @@ GetOverrideStringBundle(nsIStringBundleService* aSBS, nsIStringBundle* *aResult)
+
+ *aResult = nullptr;
+
+- // Build Torbutton file URI string by starting from the profiles directory.
+ nsXREDirProvider* dirProvider = nsXREDirProvider::GetSingleton();
+ if (!dirProvider)
+ return;
+
++#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
++ // Build Torbutton file URI by starting from the distribution directory.
++ bool persistent = false; // ignored
++ nsCOMPtr<nsIFile> distribDir;
++ nsresult rv = dirProvider->GetFile(XRE_APP_DISTRIBUTION_DIR, &persistent,
++ getter_AddRefs(distribDir));
++ if (NS_FAILED(rv))
++ return;
++
++ // Create file URI, extract as string, and append Torbutton xpi relative path.
++ nsCOMPtr<nsIURI> uri;
++ nsAutoCString uriString;
++ if (NS_FAILED(NS_NewFileURI(getter_AddRefs(uri), distribDir)) ||
++ NS_FAILED(uri->GetSpec(uriString))) {
++ return;
++ }
++
++ uriString.Append("extensions/torbutton(a)torproject.org.xpi");
++#else
++ // Build Torbutton file URI string by starting from the profiles directory.
+ bool persistent = false; // ignored
+ nsCOMPtr<nsIFile> profilesDir;
+ nsresult rv = dirProvider->GetFile(NS_APP_USER_PROFILES_ROOT_DIR, &persistent,
+@@ -1970,6 +1989,7 @@ GetOverrideStringBundle(nsIStringBundleService* aSBS, nsIStringBundle* *aResult)
+ }
+
+ uriString.Append("profile.default/extensions/torbutton(a)torproject.org.xpi");
++#endif
+
+ nsCString userAgentLocale;
+ if (!NS_SUCCEEDED(Preferences::GetCString("general.useragent.locale",
+@@ -2019,6 +2039,9 @@ enum ProfileStatus {
+ PROFILE_STATUS_READ_ONLY,
+ PROFILE_STATUS_IS_LOCKED,
+ PROFILE_STATUS_OTHER_ERROR
++#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
++ , PROFILE_STATUS_MIGRATION_FAILED
++#endif
+ };
+
+ static const char kProfileProperties[] =
+@@ -2058,6 +2081,8 @@ private:
+
+ } // namespace
+
++// If aUnlocker is NULL, it is also OK for the following arguments to be NULL:
++// aProfileDir, aProfileLocalDir, aResult.
+ static ReturnAbortOnError
+ ProfileErrorDialog(nsIFile* aProfileDir, nsIFile* aProfileLocalDir,
+ ProfileStatus aStatus, nsIProfileUnlocker* aUnlocker,
+@@ -2069,7 +2094,8 @@ ProfileErrorDialog(nsIFile* aProfileDir, nsIFile* aProfileLocalDir,
+ rv = xpcom.Initialize();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+- mozilla::Telemetry::WriteFailedProfileLock(aProfileDir);
++ if (aProfileDir)
++ mozilla::Telemetry::WriteFailedProfileLock(aProfileDir);
+
+ rv = xpcom.SetWindowCreator(aNative);
+ NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
+@@ -2100,21 +2126,27 @@ ProfileErrorDialog(nsIFile* aProfileDir, nsIFile* aProfileLocalDir,
+ static const char16_t kReadOnly[] = MOZ_UTF16("profileReadOnlyMac");
+ #endif
+ static const char16_t kAccessDenied[] = MOZ_UTF16("profileAccessDenied");
++#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
++ static const char16_t kMigrationFailed[] = MOZ_UTF16("profileMigrationFailed");
++#endif
+
+ const char16_t* errorKey = aUnlocker ? kRestartUnlocker
+ : kRestartNoUnlocker;
++ const char16_t* titleKey = MOZ_UTF16("profileProblemTitle");
+ if (PROFILE_STATUS_READ_ONLY == aStatus)
+ errorKey = kReadOnly;
++#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
++ else if (PROFILE_STATUS_MIGRATION_FAILED == aStatus)
++ errorKey = kMigrationFailed;
++#endif
+ else if (PROFILE_STATUS_ACCESS_DENIED == aStatus)
+ errorKey = kAccessDenied;
++ else
++ titleKey = MOZ_UTF16("restartTitle");
++
+ GetFormattedString(overrideSB, sb, errorKey, params, 2,
+ getter_Copies(killMessage));
+
+- const char16_t* titleKey = ((PROFILE_STATUS_READ_ONLY == aStatus) ||
+- (PROFILE_STATUS_ACCESS_DENIED == aStatus))
+- ? MOZ_UTF16("profileProblemTitle")
+- : MOZ_UTF16("restartTitle");
+-
+ nsXPIDLString killTitle;
+ GetFormattedString(overrideSB, sb, titleKey, params, 1,
+ getter_Copies(killTitle));
+@@ -2158,7 +2190,8 @@ ProfileErrorDialog(nsIFile* aProfileDir, nsIFile* aProfileLocalDir,
+ }
+ } else {
+ #ifdef MOZ_WIDGET_ANDROID
+- if (mozilla::widget::GeckoAppShell::UnlockProfile()) {
++ if (aProfileDir && aProfileLocalDir && aResult &&
++ mozilla::widget::GeckoAppShell::UnlockProfile()) {
+ return NS_LockProfilePath(aProfileDir, aProfileLocalDir,
+ nullptr, aResult);
+ }
+@@ -2449,6 +2482,223 @@ static ProfileStatus CheckProfileWriteAccess(nsIToolkitProfile* aProfile)
+ return CheckProfileWriteAccess(profileDir);
+ }
+
++#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
++// Obtain an nsIFile for the app root directory, e.g., TorBrowser.app on
++// Mac OS and the directory that contains Browser/ on Linux and Windows.
++static nsresult GetAppRootDir(nsIFile *aAppDir, nsIFile **aAppRootDir)
++{
++ NS_ENSURE_ARG_POINTER(aAppDir);
++
++#ifdef XP_MACOSX
++ nsCOMPtr<nsIFile> tmpDir;
++ nsresult rv = aAppDir->GetParent(getter_AddRefs(tmpDir));
++ NS_ENSURE_SUCCESS(rv, rv);
++ return tmpDir->GetParent(aAppRootDir);
++#else
++ return aAppDir->Clone(aAppRootDir);
++#endif
++}
++
++static ProfileStatus CheckTorBrowserDataWriteAccess(nsIFile *aAppDir)
++{
++ // Check whether we can write to the directory that will contain
++ // TorBrowser-Data.
++ nsCOMPtr<nsIFile> tbDataDir;
++ nsXREDirProvider* dirProvider = nsXREDirProvider::GetSingleton();
++ if (!dirProvider)
++ return PROFILE_STATUS_OTHER_ERROR;
++ nsresult rv =
++ dirProvider->GetTorBrowserUserDataDir(getter_AddRefs(tbDataDir));
++ NS_ENSURE_SUCCESS(rv, PROFILE_STATUS_OTHER_ERROR);
++ nsCOMPtr<nsIFile> tbDataDirParent;
++ rv = tbDataDir->GetParent(getter_AddRefs(tbDataDirParent));
++ NS_ENSURE_SUCCESS(rv, PROFILE_STATUS_OTHER_ERROR);
++ return CheckProfileWriteAccess(tbDataDirParent);
++}
++
++// Move the directory defined by combining aSrcParentDir and aSrcRelativePath
++// to the location defined by combining aDestParentDir and aDestRelativePath.
++// If the source directory does not exist, no changes are made and NS_OK is
++// returned.
++// If the destination directory exists, its contents are removed after the
++// source directory has been moved (if the move fails for some reason, the
++// original contents of the destination directory are restored).
++static nsresult
++migrateOneTorBrowserDataDir(nsIFile *aSrcParentDir,
++ const nsACString &aSrcRelativePath,
++ nsIFile *aDestParentDir,
++ const nsACString &aDestRelativePath)
++{
++ NS_ENSURE_ARG_POINTER(aSrcParentDir);
++ NS_ENSURE_ARG_POINTER(aDestParentDir);
++
++ nsCOMPtr<nsIFile> srcDir;
++ nsresult rv = aSrcParentDir->Clone(getter_AddRefs(srcDir));
++ NS_ENSURE_SUCCESS(rv, rv);
++ if (!aSrcRelativePath.IsEmpty()) {
++ rv = srcDir->AppendRelativeNativePath(aSrcRelativePath);
++ NS_ENSURE_SUCCESS(rv, rv);
++ }
++
++ bool srcDirExists = false;
++ srcDir->Exists(&srcDirExists);
++ if (!srcDirExists)
++ return NS_OK; // Old data does not exist; skip migration.
++
++ nsCOMPtr<nsIFile> destDir;
++ rv = aDestParentDir->Clone(getter_AddRefs(destDir));
++ NS_ENSURE_SUCCESS(rv, rv);
++ if (!aDestRelativePath.IsEmpty()) {
++ rv = destDir->AppendRelativeNativePath(aDestRelativePath);
++ NS_ENSURE_SUCCESS(rv, rv);
++ }
++
++ nsCOMPtr<nsIFile> destParentDir;
++ rv = destDir->GetParent(getter_AddRefs(destParentDir));
++ NS_ENSURE_SUCCESS(rv, rv);
++
++ nsAutoString destLeafName;
++ rv = destDir->GetLeafName(destLeafName);
++ NS_ENSURE_SUCCESS(rv, rv);
++
++ bool destDirExists = false;
++ destDir->Exists(&destDirExists);
++ nsCOMPtr<nsIFile> tmpDir;
++ if (destDirExists) {
++ // The destination directory exists. When we are migrating an old
++ // Tor Browser profile, we expect this to be the case because we first
++ // allow the standard Mozilla startup code to create a new profile as
++ // usual, and then later (here) we set aside that profile directory and
++ // replace it with the old Tor Browser profile that we need to migrate.
++ // For now, move the Mozilla profile directory aside and set tmpDir to
++ // point to its new, temporary location in case migration fails and we
++ // need to restore the profile that was created by the Mozilla code.
++ nsAutoString tmpName(NS_LITERAL_STRING("tmp"));
++ rv = destDir->RenameTo(nullptr, tmpName);
++ NS_ENSURE_SUCCESS(rv, rv);
++ nsCOMPtr<nsIFile> dir;
++ rv = destParentDir->Clone(getter_AddRefs(dir));
++ NS_ENSURE_SUCCESS(rv, rv);
++ rv = dir->Append(tmpName);
++ NS_ENSURE_SUCCESS(rv, rv);
++ tmpDir = dir;
++ }
++
++ // Move the old directory to the new location using MoveTo() so that
++ // timestamps are preserved (MoveTo() is atomic as long as the source and
++ // destination are on the same volume).
++ rv = srcDir->MoveTo(destParentDir, destLeafName);
++ if (NS_FAILED(rv)) {
++ // The move failed. Restore the directory that we were trying to replace.
++ if (tmpDir)
++ tmpDir->RenameTo(nullptr, destLeafName);
++ return rv;
++ }
++
++ // Success. If we set aside a directory earlier by renaming it, remove it.
++ if (tmpDir)
++ tmpDir->Remove(true);
++
++ return NS_OK;
++}
++
++static nsresult
++deleteFile(nsIFile *aParentDir, const nsACString &aRelativePath)
++{
++ NS_ENSURE_ARG_POINTER(aParentDir);
++
++ nsCOMPtr<nsIFile> file;
++ nsresult rv = aParentDir->Clone(getter_AddRefs(file));
++ NS_ENSURE_SUCCESS(rv, rv);
++ if (!aRelativePath.IsEmpty()) {
++ rv = file->AppendRelativeNativePath(aRelativePath);
++ NS_ENSURE_SUCCESS(rv, rv);
++ }
++
++ return file->Remove(false);
++}
++
++// When this function is called, aProfile is a brand new profile and
++// aAppDir is the directory that contains the firefox executable.
++// Our strategy is to check if an old "in application" profile exists at
++// <AppRootDir>/TorBrowser/Data/Browser/profile.default. If so, we set
++// aside the new profile directory and replace it with the old one.
++// We use a similar approach for the Tor data and UpdateInfo directories.
++static nsresult
++migrateInAppTorBrowserProfile(nsIToolkitProfile *aProfile, nsIFile *aAppDir)
++{
++ NS_ENSURE_ARG_POINTER(aProfile);
++ NS_ENSURE_ARG_POINTER(aAppDir);
++
++ nsCOMPtr<nsIFile> appRootDir;
++ nsresult rv = GetAppRootDir(aAppDir, getter_AddRefs(appRootDir));
++ NS_ENSURE_SUCCESS(rv, rv);
++
++ // Create an nsIFile for the old <AppRootDir>/TorBrowser directory.
++ nsCOMPtr<nsIFile> oldTorBrowserDir;
++ rv = appRootDir->Clone(getter_AddRefs(oldTorBrowserDir));
++ NS_ENSURE_SUCCESS(rv, rv);
++ rv = oldTorBrowserDir->AppendRelativeNativePath(
++ NS_LITERAL_CSTRING("TorBrowser"));
++ NS_ENSURE_SUCCESS(rv, rv);
++
++ // Get an nsIFile for the TorBrowser-Data directory.
++ nsCOMPtr<nsIFile> newTBDataDir;
++ nsXREDirProvider* dirProvider = nsXREDirProvider::GetSingleton();
++ if (!dirProvider)
++ return NS_ERROR_UNEXPECTED;
++ rv = dirProvider->GetTorBrowserUserDataDir(getter_AddRefs(newTBDataDir));
++ NS_ENSURE_SUCCESS(rv, rv);
++
++ // Try to migrate the browser profile. If this fails, we return an error
++ // code and we do not try to migrate any other data.
++ nsCOMPtr<nsIFile> newProfileDir;
++ rv = aProfile->GetRootDir(getter_AddRefs(newProfileDir));
++ NS_ENSURE_SUCCESS(rv, rv);
++ nsAutoCString path(NS_LITERAL_CSTRING("Data" XPCOM_FILE_PATH_SEPARATOR
++ "Browser" XPCOM_FILE_PATH_SEPARATOR "profile.default"));
++ rv = migrateOneTorBrowserDataDir(oldTorBrowserDir, path,
++ newProfileDir, NS_LITERAL_CSTRING(""));
++ NS_ENSURE_SUCCESS(rv, rv); // Return immediately upon failure.
++
++ // Try to migrate the Tor data directory but do not return upon failure.
++ nsAutoCString torDataDirPath(NS_LITERAL_CSTRING("Data"
++ XPCOM_FILE_PATH_SEPARATOR "Tor"));
++ rv = migrateOneTorBrowserDataDir(oldTorBrowserDir, torDataDirPath,
++ newTBDataDir, NS_LITERAL_CSTRING("Tor"));
++ if (NS_SUCCEEDED(rv)) {
++ // Make a "best effort" attempt to remove the Tor data files that should
++ // no longer be stored in the Tor user data directory (they have been
++ // relocated to a read-only Tor directory, e.g.,
++ // TorBrowser.app/Contents/Resources/TorBrowser/Tor.
++ deleteFile(newTBDataDir,
++ NS_LITERAL_CSTRING("Tor" XPCOM_FILE_PATH_SEPARATOR "geoip"));
++ deleteFile(newTBDataDir,
++ NS_LITERAL_CSTRING("Tor" XPCOM_FILE_PATH_SEPARATOR "geoip6"));
++ deleteFile(newTBDataDir,
++ NS_LITERAL_CSTRING("Tor" XPCOM_FILE_PATH_SEPARATOR "torrc-defaults"));
++ }
++
++ // Try to migrate the UpdateInfo directory.
++ nsCOMPtr<nsIFile> newUpdateInfoDir;
++ nsresult rv2 = dirProvider->GetUpdateRootDir(
++ getter_AddRefs(newUpdateInfoDir));
++ if (NS_SUCCEEDED(rv2)) {
++ nsAutoCString updateInfoPath(NS_LITERAL_CSTRING("UpdateInfo"));
++ rv2 = migrateOneTorBrowserDataDir(oldTorBrowserDir, updateInfoPath,
++ newUpdateInfoDir, NS_LITERAL_CSTRING(""));
++ }
++
++ // If all pieces of the migration succeeded, remove the old TorBrowser
++ // directory.
++ if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(rv2)) {
++ oldTorBrowserDir->Remove(true);
++ }
++
++ return NS_OK;
++}
++#endif
++
+ static bool gDoMigration = false;
+ static bool gDoProfileReset = false;
+
+@@ -2461,7 +2711,8 @@ static bool gDoProfileReset = false;
+ // 5) if there are *no* profiles, set up profile-migration
+ // 6) display the profile-manager UI
+ static nsresult
+-SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, nsINativeAppSupport* aNative,
++SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc,
++ nsIFile *aAppDir, nsINativeAppSupport* aNative,
+ bool* aStartOffline, nsACString* aProfileName)
+ {
+ StartupTimeline::Record(StartupTimeline::SELECT_PROFILE);
+@@ -2742,6 +2993,20 @@ SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, n
+ aProfileSvc->SetDefaultProfile(profile);
+ #endif
+ aProfileSvc->Flush();
++#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
++ // Handle migration from an older version of Tor Browser in which the
++ // user data was stored inside the application directory.
++ rv = migrateInAppTorBrowserProfile(profile, aAppDir);
++ if (!NS_SUCCEEDED(rv)) {
++ // Display an error alert and continue startup. Since XPCOM was
++ // initialized in a limited way inside ProfileErrorDialog() and
++ // because it cannot be reinitialized, use LaunchChild() to start
++ // the browser.
++ ProfileErrorDialog(profile, PROFILE_STATUS_MIGRATION_FAILED, nullptr,
++ aNative, aResult);
++ return LaunchChild(aNative);
++ }
++#endif
+ rv = profile->Lock(nullptr, aResult);
+ if (NS_SUCCEEDED(rv)) {
+ if (aProfileName)
+@@ -3313,6 +3578,14 @@ XREMain::XRE_mainInit(bool* aExitFlag)
+ NS_BREAK();
+ #endif
+
++#if defined(XP_MACOSX) && defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR)
++ bool hideDockIcon = (CheckArg("invisible") == ARG_FOUND);
++ if (hideDockIcon) {
++ ProcessSerialNumber psn = { 0, kCurrentProcess };
++ TransformProcessType(&psn, kProcessTransformToBackgroundApplication);
++ }
++#endif
++
+ #ifdef USE_GLX_TEST
+ // bug 639842 - it's very important to fire this process BEFORE we set up
+ // error handling. indeed, this process is expected to be crashy, and we
+@@ -4073,6 +4346,22 @@ XREMain::XRE_mainStartup(bool* aExitFlag)
+ #endif
+
+ rv = NS_NewToolkitProfileService(getter_AddRefs(mProfileSvc));
++#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
++ if (NS_FAILED(rv)) {
++ // NS_NewToolkitProfileService() returns a generic NS_ERROR_FAILURE error
++ // if creation of the TorBrowser-Data directory fails due to access denied
++ // or because of a read-only disk volume. Do an extra check here to detect
++ // these errors so we can display an informative error message.
++ ProfileStatus status = CheckTorBrowserDataWriteAccess(exeDir);
++ if ((PROFILE_STATUS_ACCESS_DENIED == status) ||
++ (PROFILE_STATUS_READ_ONLY == status)) {
++ ProfileErrorDialog(nullptr, nullptr, status, nullptr, mNativeApp,
++ nullptr);
++ return 1;
++ }
++ }
++#endif
++
+ if (rv == NS_ERROR_FILE_ACCESS_DENIED) {
+ PR_fprintf(PR_STDERR, "Error: Access was denied while trying to open files in " \
+ "your profile directory.\n");
+@@ -4083,8 +4372,8 @@ XREMain::XRE_mainStartup(bool* aExitFlag)
+ return 1;
+ }
+
+- rv = SelectProfile(getter_AddRefs(mProfileLock), mProfileSvc, mNativeApp, &mStartOffline,
+- &mProfileName);
++ rv = SelectProfile(getter_AddRefs(mProfileLock), mProfileSvc, exeDir,
++ mNativeApp, &mStartOffline, &mProfileName);
+ if (rv == NS_ERROR_LAUNCHED_CHILD_PROCESS ||
+ rv == NS_ERROR_ABORT) {
+ *aExitFlag = true;
+diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp
+index 403e820..e3c1449 100644
+--- a/toolkit/xre/nsXREDirProvider.cpp
++++ b/toolkit/xre/nsXREDirProvider.cpp
+@@ -38,6 +38,8 @@
+ #include "mozilla/Preferences.h"
+ #include "mozilla/Telemetry.h"
+
++#include "TorFileUtils.h"
++
+ #include <stdlib.h>
+
+ #ifdef XP_WIN
+@@ -1057,40 +1059,48 @@ nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult)
+ getter_AddRefs(updRoot));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+-#else
++#elif defined(TOR_BROWSER_UPDATE)
++ // For Tor Browser, we store update history, etc. within the UpdateInfo
++ // directory under the user data directory.
++ nsresult rv = GetTorBrowserUserDataDir(getter_AddRefs(updRoot));
++ NS_ENSURE_SUCCESS(rv, rv);
++ rv = updRoot->AppendNative(NS_LITERAL_CSTRING("UpdateInfo"));
++ NS_ENSURE_SUCCESS(rv, rv);
++#if defined(XP_MACOSX) && defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR)
++ // Since the TorBrowser-Data directory may be shared among different
++ // installations of the application, embed the app path in the update dir
++ // so that the update history is partitioned. This is much less likely to
++ // be an issue on Linux or Windows because the Tor Browser packages for
++ // those platforms include a "container" folder that provides partitioning
++ // by default, and we do not support use of a shared, OS-recommended area
++ // for user data on those platforms.
+ nsCOMPtr<nsIFile> appFile;
+ bool per = false;
+- nsresult rv = GetFile(XRE_EXECUTABLE_FILE, &per, getter_AddRefs(appFile));
+- NS_ENSURE_SUCCESS(rv, rv);
+- rv = appFile->GetParent(getter_AddRefs(updRoot));
++ rv = GetFile(XRE_EXECUTABLE_FILE, &per, getter_AddRefs(appFile));
+ NS_ENSURE_SUCCESS(rv, rv);
++ nsCOMPtr<nsIFile> appRootDirFile;
++ nsAutoString appDirPath;
++ if (NS_FAILED(appFile->GetParent(getter_AddRefs(appRootDirFile))) ||
++ NS_FAILED(appRootDirFile->GetPath(appDirPath))) {
++ return NS_ERROR_FAILURE;
++ }
+
+-#ifdef XP_MACOSX
+-#ifdef TOR_BROWSER_UPDATE
+-#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
+- // For Tor Browser, we cannot store update history, etc. under the user's
+- // home directory. Instead, we place it under
+- // Tor Browser.app/../TorBrowser-Data/UpdateInfo/
+- nsCOMPtr<nsIFile> appRootDir;
+- rv = GetAppRootDir(getter_AddRefs(appRootDir));
+- NS_ENSURE_SUCCESS(rv, rv);
+- nsCOMPtr<nsIFile> localDir;
+- rv = appRootDir->GetParent(getter_AddRefs(localDir));
+- NS_ENSURE_SUCCESS(rv, rv);
+- rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("TorBrowser-Data"
+- XPCOM_FILE_PATH_SEPARATOR "UpdateInfo"));
+-#else
+- // For Tor Browser, we cannot store update history, etc. under the user's home directory.
+- // Instead, we place it under Tor Browser.app/TorBrowser/UpdateInfo/
+- nsCOMPtr<nsIFile> localDir;
+- rv = GetAppRootDir(getter_AddRefs(localDir));
+- NS_ENSURE_SUCCESS(rv, rv);
+- rv = localDir->AppendNative(NS_LITERAL_CSTRING("TorBrowser"));
++ int32_t dotIndex = appDirPath.RFind(".app");
++ if (dotIndex == kNotFound) {
++ dotIndex = appDirPath.Length();
++ }
++ appDirPath = Substring(appDirPath, 1, dotIndex - 1);
++ rv = updRoot->AppendRelativePath(appDirPath);
+ NS_ENSURE_SUCCESS(rv, rv);
+- rv = localDir->AppendNative(NS_LITERAL_CSTRING("UpdateInfo"));
+ #endif
++#else // ! TOR_BROWSER_UPDATE
++ nsCOMPtr<nsIFile> appFile;
++ bool per = false;
++ nsresult rv = GetFile(XRE_EXECUTABLE_FILE, &per, getter_AddRefs(appFile));
+ NS_ENSURE_SUCCESS(rv, rv);
+-#else
++ rv = appFile->GetParent(getter_AddRefs(updRoot));
++ NS_ENSURE_SUCCESS(rv, rv);
++#ifdef XP_MACOSX
+ nsCOMPtr<nsIFile> appRootDirFile;
+ nsCOMPtr<nsIFile> localDir;
+ nsAutoString appDirPath;
+@@ -1121,7 +1131,6 @@ nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult)
+ NS_FAILED(localDir->AppendRelativePath(appDirPath))) {
+ return NS_ERROR_FAILURE;
+ }
+-#endif
+
+ localDir.forget(aResult);
+ return NS_OK;
+@@ -1215,7 +1224,7 @@ nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult)
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ #endif // XP_WIN
+-#endif
++#endif // ! TOR_BROWSER_UPDATE
+ updRoot.forget(aResult);
+ return NS_OK;
+ }
+@@ -1268,12 +1277,15 @@ nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile, bool aLocal)
+ // Copied from nsAppFileLocationProvider (more or less)
+ NS_ENSURE_ARG_POINTER(aFile);
+ nsCOMPtr<nsIFile> localDir;
+-
+- nsresult rv = GetAppRootDir(getter_AddRefs(localDir));
++ nsresult rv = GetTorBrowserUserDataDir(getter_AddRefs(localDir));
+ NS_ENSURE_SUCCESS(rv, rv);
+- rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("TorBrowser"
+- XPCOM_FILE_PATH_SEPARATOR "Data"
++
++#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
++ rv = localDir->AppendNative(NS_LITERAL_CSTRING("Browser"));
++#else
++ rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("Data"
+ XPCOM_FILE_PATH_SEPARATOR "Browser"));
++#endif
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (aLocal) {
+@@ -1377,43 +1389,16 @@ nsXREDirProvider::GetUserDataDirectory(nsIFile** aFile, bool aLocal,
+ }
+
+ nsresult
+-nsXREDirProvider::GetAppRootDir(nsIFile* *aFile)
++nsXREDirProvider::GetTorBrowserUserDataDir(nsIFile* *aFile)
+ {
+ NS_ENSURE_ARG_POINTER(aFile);
+- nsCOMPtr<nsIFile> appRootDir;
+-
+- nsresult rv = GetAppDir()->Clone(getter_AddRefs(appRootDir));
++ nsCOMPtr<nsIFile> exeFile;
++ bool per = false;
++ nsresult rv = GetFile(XRE_EXECUTABLE_FILE, &per, getter_AddRefs(exeFile));
+ NS_ENSURE_SUCCESS(rv, rv);
+-
+- int levelsToRemove = 0; // In FF21+, appDir points to browser subdirectory.
+-#if defined(XP_MACOSX)
+- levelsToRemove += 1;
+-#endif
+- while (appRootDir && (levelsToRemove > 0)) {
+- // When crawling up the hierarchy, components named "." do not count.
+- nsAutoCString removedName;
+- rv = appRootDir->GetNativeLeafName(removedName);
+- NS_ENSURE_SUCCESS(rv, rv);
+- bool didRemove = !removedName.Equals(".");
+-
+- // Remove a directory component.
+- nsCOMPtr<nsIFile> parentDir;
+- rv = appRootDir->GetParent(getter_AddRefs(parentDir));
+- NS_ENSURE_SUCCESS(rv, rv);
+- appRootDir = parentDir;
+-
+- if (didRemove)
+- --levelsToRemove;
+- }
+-
+- if (!appRootDir)
+- return NS_ERROR_FAILURE;
+-
+- appRootDir.forget(aFile);
+- return NS_OK;
++ return TorBrowser_GetUserDataDir(exeFile, aFile);
+ }
+
+-
+ nsresult
+ nsXREDirProvider::EnsureDirectoryExists(nsIFile* aDirectory)
+ {
+diff --git a/toolkit/xre/nsXREDirProvider.h b/toolkit/xre/nsXREDirProvider.h
+index b86cc68..e8190e3 100644
+--- a/toolkit/xre/nsXREDirProvider.h
++++ b/toolkit/xre/nsXREDirProvider.h
+@@ -100,6 +100,12 @@ public:
+ */
+ nsresult GetProfileDir(nsIFile* *aResult);
+
++ /**
++ * Get the TorBrowser user data directory by calling the
++ * TorBrowser_GetUserDataDir() utility function.
++ */
++ nsresult GetTorBrowserUserDataDir(nsIFile* *aFile);
++
+ protected:
+ nsresult GetFilesInternal(const char* aProperty, nsISimpleEnumerator** aResult);
+ nsresult GetUserDataDirectoryHome(nsIFile* *aFile, bool aLocal);
+@@ -107,7 +113,6 @@ protected:
+ #if defined(XP_UNIX) || defined(XP_MACOSX)
+ static nsresult GetSystemExtensionsDirectory(nsIFile** aFile);
+ #endif
+- nsresult GetAppRootDir(nsIFile* *aFile);
+ static nsresult EnsureDirectoryExists(nsIFile* aDirectory);
+ void EnsureProfileFileExists(nsIFile* aFile);
+
+diff --git a/xpcom/io/TorFileUtils.cpp b/xpcom/io/TorFileUtils.cpp
+new file mode 100644
+index 0000000..2b0b100
+--- /dev/null
++++ b/xpcom/io/TorFileUtils.cpp
+@@ -0,0 +1,130 @@
++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
++/* vim: set ts=8 sts=2 et sw=2 tw=80: */
++/* 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/. */
++
++#include "TorFileUtils.h"
++
++static nsresult GetAppRootDir(nsIFile *aExeFile, nsIFile** aFile);
++
++//-----------------------------------------------------------------------------
++NS_METHOD
++TorBrowser_GetUserDataDir(nsIFile *aExeFile, nsIFile** aFile)
++{
++ NS_ENSURE_ARG_POINTER(aFile);
++ nsCOMPtr<nsIFile> tbDataDir;
++
++#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
++ nsAutoCString tbDataLeafName(NS_LITERAL_CSTRING("TorBrowser-Data"));
++ nsCOMPtr<nsIFile> appRootDir;
++ nsresult rv = GetAppRootDir(aExeFile, getter_AddRefs(appRootDir));
++ NS_ENSURE_SUCCESS(rv, rv);
++#ifndef XP_MACOSX
++ // On all platforms except Mac OS, we always operate in a "portable" mode
++ // where the TorBrowser-Data directory is located next to the application.
++ rv = appRootDir->GetParent(getter_AddRefs(tbDataDir));
++ NS_ENSURE_SUCCESS(rv, rv);
++ rv = tbDataDir->AppendNative(tbDataLeafName);
++ NS_ENSURE_SUCCESS(rv, rv);
++#else
++ // For Mac OS, determine whether we should store user data in the OS's
++ // standard location (i.e., under ~/Library/Application Support). We use
++ // the OS location if (1) the application is installed in a directory whose
++ // path contains "/Applications" or (2) the TorBrowser-Data directory does
++ // not exist and cannot be created (which probably means we lack write
++ // permission to the directory that contains the application).
++ nsAutoString appRootPath;
++ rv = appRootDir->GetPath(appRootPath);
++ NS_ENSURE_SUCCESS(rv, rv);
++ bool useOSLocation = (appRootPath.Find("/Applications",
++ true /* ignore case */) >= 0);
++ if (!useOSLocation) {
++ // We hope to use the portable (aka side-by-side) approach, but before we
++ // commit to that, let's ensure that we can create the TorBrowser-Data
++ // directory. If it already exists, we will try to use it; if not and we
++ // fail to create it, we will switch to ~/Library/Application Support.
++ rv = appRootDir->GetParent(getter_AddRefs(tbDataDir));
++ NS_ENSURE_SUCCESS(rv, rv);
++ rv = tbDataDir->AppendNative(tbDataLeafName);
++ NS_ENSURE_SUCCESS(rv, rv);
++ bool exists = false;
++ rv = tbDataDir->Exists(&exists);
++ if (NS_SUCCEEDED(rv) && !exists)
++ rv = tbDataDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
++ useOSLocation = NS_FAILED(rv);
++ }
++
++ if (useOSLocation) {
++ // We are using ~/Library/Application Support/TorBrowser-Data. We do not
++ // need to create that directory here because the code in nsXREDirProvider
++ // will do so (and the user should always have write permission for
++ // ~/Library/Application Support; if they do not we have no more options).
++ FSRef fsRef;
++ OSErr err = ::FSFindFolder(kUserDomain, kApplicationSupportFolderType,
++ kCreateFolder, &fsRef);
++ NS_ENSURE_FALSE(err, NS_ERROR_FAILURE);
++ // To convert the FSRef returned by FSFindFolder() into an nsIFile that
++ // points to ~/Library/Application Support, we first create an empty
++ // nsIFile object (no path) and then use InitWithFSRef() to set the
++ // path.
++ rv = NS_NewNativeLocalFile(EmptyCString(), true,
++ getter_AddRefs(tbDataDir));
++ NS_ENSURE_SUCCESS(rv, rv);
++ nsCOMPtr<nsILocalFileMac> dirFileMac = do_QueryInterface(tbDataDir);
++ if (!dirFileMac)
++ return NS_ERROR_UNEXPECTED;
++ rv = dirFileMac->InitWithFSRef(&fsRef);
++ NS_ENSURE_SUCCESS(rv, rv);
++ rv = tbDataDir->AppendNative(tbDataLeafName);
++ NS_ENSURE_SUCCESS(rv, rv);
++ }
++#endif
++
++#else
++ // User data is embedded within the application directory (i.e.,
++ // TOR_BROWSER_DATA_OUTSIDE_APP_DIR is not defined).
++ nsresult rv = GetAppRootDir(aExeFile, getter_AddRefs(tbDataDir));
++ NS_ENSURE_SUCCESS(rv, rv);
++ rv = tbDataDir->AppendNative(NS_LITERAL_CSTRING("TorBrowser"));
++ NS_ENSURE_SUCCESS(rv, rv);
++#endif
++
++ tbDataDir.forget(aFile);
++ return NS_OK;
++}
++
++static nsresult
++GetAppRootDir(nsIFile *aExeFile, nsIFile** aFile)
++{
++ NS_ENSURE_ARG_POINTER(aExeFile);
++ NS_ENSURE_ARG_POINTER(aFile);
++ nsCOMPtr<nsIFile> appRootDir = aExeFile;
++
++ int levelsToRemove = 0; // Remove firefox (the executable file).
++#if defined(XP_MACOSX)
++ levelsToRemove += 1; // On Mac OS, we must also remove Contents/MacOS.
++#endif
++ while (appRootDir && (levelsToRemove > 0)) {
++ // When crawling up the hierarchy, components named "." do not count.
++ nsAutoCString removedName;
++ nsresult rv = appRootDir->GetNativeLeafName(removedName);
++ NS_ENSURE_SUCCESS(rv, rv);
++ bool didRemove = !removedName.Equals(".");
++
++ // Remove a directory component.
++ nsCOMPtr<nsIFile> parentDir;
++ rv = appRootDir->GetParent(getter_AddRefs(parentDir));
++ NS_ENSURE_SUCCESS(rv, rv);
++ appRootDir = parentDir;
++
++ if (didRemove)
++ --levelsToRemove;
++ }
++
++ if (!appRootDir)
++ return NS_ERROR_FAILURE;
++
++ appRootDir.forget(aFile);
++ return NS_OK;
++}
+diff --git a/xpcom/io/TorFileUtils.h b/xpcom/io/TorFileUtils.h
+new file mode 100644
+index 0000000..293ed04
+--- /dev/null
++++ b/xpcom/io/TorFileUtils.h
+@@ -0,0 +1,35 @@
++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
++/* vim: set ts=8 sts=2 et sw=2 tw=80: */
++/* 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/. */
++
++#ifndef TorFileUtils_h__
++#define TorFileUtils_h__
++
++#include "nsIFile.h"
++
++class nsIFile;
++
++/**
++ * TorBrowser_GetUserDataDir
++ *
++ * Retrieve the Tor Browser user data directory.
++ * When built with --enable-tor-browser-data-outside-app-dir, the directory
++ * is next to the application directory, except on Mac OS where it may be
++ * there or it may be at ~/Library/Application Support/TorBrowser-Data (the
++ * latter location is used if the .app bundle is in a directory whose path
++ * contains /Applications or if we lack write access to the directory that
++ * contains the .app).
++ * When built without --enable-tor-browser-data-outside-app-dir, this
++ * directory is TorBrowser.app/TorBrowser.
++ *
++ * @param aExeFile The firefox executable.
++ * @param aFile Out parameter that is set to the Tor Browser user data
++ * directory.
++ * @return NS_OK on success. Error otherwise.
++ */
++extern NS_METHOD
++TorBrowser_GetUserDataDir(nsIFile *aExeFile, nsIFile** aFile);
++
++#endif // !TorFileUtils_h__
+diff --git a/xpcom/io/moz.build b/xpcom/io/moz.build
+index bc62f71..c90f33c 100644
+--- a/xpcom/io/moz.build
++++ b/xpcom/io/moz.build
+@@ -80,6 +80,7 @@ EXPORTS += [
+ 'nsUnicharInputStream.h',
+ 'nsWildCard.h',
+ 'SpecialSystemDirectory.h',
++ 'TorFileUtils.h',
+ ]
+
+ EXPORTS.mozilla += [
+@@ -116,6 +117,7 @@ UNIFIED_SOURCES += [
+ 'SnappyFrameUtils.cpp',
+ 'SnappyUncompressInputStream.cpp',
+ 'SpecialSystemDirectory.cpp',
++ 'TorFileUtils.cpp',
+ ]
+
+ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
+diff --git a/xpcom/io/nsAppFileLocationProvider.cpp b/xpcom/io/nsAppFileLocationProvider.cpp
+index 039a89e..da66b90 100644
+--- a/xpcom/io/nsAppFileLocationProvider.cpp
++++ b/xpcom/io/nsAppFileLocationProvider.cpp
+@@ -29,6 +29,7 @@
+ #include <sys/param.h>
+ #endif
+
++#include "TorFileUtils.h"
+
+ // WARNING: These hard coded names need to go away. They need to
+ // come from localizable resources
+@@ -282,8 +283,14 @@ nsAppFileLocationProvider::CloneMozBinDirectory(nsIFile** aLocalFile)
+ //----------------------------------------------------------------------------------------
+ // GetProductDirectory - Gets the directory which contains the application data folder
+ //
++#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
++// UNIX and WIN : <App Folder>/../TorBrowser-Data/Browser
++// Mac : <App Folder>/../../../TorBrowser-Data/Browser OR
++// ~/Library/Application Support/TorBrowser-Data/Browser
++#else
+ // UNIX and WIN : <App Folder>/TorBrowser/Data/Browser
+ // Mac : <App Folder>/../../TorBrowser/Data/Browser
++#endif
+ //----------------------------------------------------------------------------------------
+ NS_METHOD
+ nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,
+@@ -293,42 +300,25 @@ nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,
+ return NS_ERROR_INVALID_ARG;
+ }
+
+- nsresult rv;
++ nsresult rv = NS_ERROR_UNEXPECTED;
+ bool exists;
+- nsCOMPtr<nsIFile> localDir;
++ nsCOMPtr<nsIFile> localDir, exeFile;
+
+- rv = CloneMozBinDirectory(getter_AddRefs(localDir));
++ nsCOMPtr<nsIProperties> directoryService(
++ do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
++ NS_ENSURE_SUCCESS(rv, rv);
++ rv = directoryService->Get(XRE_EXECUTABLE_FILE, NS_GET_IID(nsIFile),
++ getter_AddRefs(exeFile));
++ NS_ENSURE_SUCCESS(rv, rv);
++ rv = TorBrowser_GetUserDataDir(exeFile, getter_AddRefs(localDir));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+- int levelsToRemove = 0; // In FF21+, bin dir points to browser subdirectory.
+-#if defined(XP_MACOSX)
+- levelsToRemove += 1;
+-#endif
+- while (localDir && (levelsToRemove > 0)) {
+- // When crawling up the hierarchy, components named "." do not count.
+- nsAutoCString removedName;
+- rv = localDir->GetNativeLeafName(removedName);
+- NS_ENSURE_SUCCESS(rv, rv);
+- bool didRemove = !removedName.Equals(".");
+-
+- // Remove a directory component.
+- nsCOMPtr<nsIFile> parentDir;
+- rv = localDir->GetParent(getter_AddRefs(parentDir));
+- NS_ENSURE_SUCCESS(rv, rv);
+- localDir = parentDir;
+-
+- if (didRemove) {
+- --levelsToRemove;
+- }
+- }
+-
+- if (!localDir) {
+- return NS_ERROR_FAILURE;
+- }
+-
+- rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("TorBrowser"
+- XPCOM_FILE_PATH_SEPARATOR "Data"
++#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
++ rv = localDir->AppendNative(NS_LITERAL_CSTRING("Browser"));
++#else
++ rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("Data"
+ XPCOM_FILE_PATH_SEPARATOR "Browser"));
++#endif
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (aLocal) {
+--
+cgit v0.10.2
+
1
0

[tor-messenger-build/updater] Update tor-messenger/build script
by sukhbir@torproject.org 29 Jul '16
by sukhbir@torproject.org 29 Jul '16
29 Jul '16
commit 8a4f5db17a82e8b098a74c3e9a96b8b9c2e27423
Author: Sukhbir Singh <sukhbir(a)torproject.org>
Date: Sat Jul 9 13:05:46 2016 -0400
Update tor-messenger/build script
- Change path of extensions to TorBrowser directory
- Replace Messenger with Browser directory
---
projects/tor-messenger/build | 61 +++++++++++++++++++++++++-------------------
1 file changed, 35 insertions(+), 26 deletions(-)
diff --git a/projects/tor-messenger/build b/projects/tor-messenger/build
index 8006deb..f50c490 100755
--- a/projects/tor-messenger/build
+++ b/projects/tor-messenger/build
@@ -11,25 +11,25 @@ rootdir=$(pwd)
mkdir bundle
[% IF c("var/windows") -%]
7z x -y -obundle [% c('input_files_by_name/instantbird') %]
-mv bundle/instantbird bundle/Messenger
+mv bundle/instantbird bundle/Browser
[% ELSE -%]
-mkdir bundle/Messenger
-tar xf [% c('input_files_by_name/instantbird') %] -C bundle/Messenger --strip 1
+mkdir bundle/Browser
+tar xf [% c('input_files_by_name/instantbird') %] -C bundle/Browser --strip 1
[% END -%]
-find bundle/Messenger -exec touch -m -t $(date -d @[% c('timestamp') %] +%Y%m%d%H%M) {} \;
+find bundle/Browser -exec touch -m -t $(date -d @[% c('timestamp') %] +%Y%m%d%H%M) {} \;
[% IF c("var/linux") -%]
# remove non reproducible files (FIPS-140)
# Tor Browser removes them too
-rm -f bundle/Messenger/*.chk
+rm -f bundle/Browser/*.chk
[% END -%]
-mkdir bundle/Messenger/TorMessenger
+mkdir bundle/Browser/TorBrowser
tar xf [% c('input_files_by_name/bundle-data') %]
[% IF c("var/linux") -%]
-mv Bundle-Data/linux/* bundle/Messenger/TorMessenger/
+mv Bundle-Data/linux/* bundle/Browser/TorBrowser/
[% ELSE -%]
-mv Bundle-Data/windows/* bundle/Messenger/TorMessenger/
+mv Bundle-Data/windows/* bundle/Browser/TorBrowser/
[% END -%]
[% IF c("var/linux") %]
@@ -37,30 +37,35 @@ tar xf [% c('input_files_by_name/gcc') %]
chmod 755 start-tor-messenger start-tor-messenger.desktop execdesktop
cp start-tor-messenger.desktop bundle/
-mv start-tor-messenger.desktop bundle/Messenger/
-mv start-tor-messenger bundle/Messenger/
-mv execdesktop bundle/Messenger/
+mv start-tor-messenger.desktop bundle/Browser/
+mv start-tor-messenger bundle/Browser/
+mv execdesktop bundle/Browser/
-mkdir -p bundle/Messenger/lib
-cp -L gcc/lib[% c('arch') == 'x86_64' ? '64' : '32' %]/libstdc++.so.6 bundle/Messenger/lib/
+mkdir -p bundle/Browser/lib
+cp -L gcc/lib[% c('arch') == 'x86_64' ? '64' : '32' %]/libstdc++.so.6 bundle/Browser/lib/
[% END %]
-cp cert_override.txt bundle/Messenger/TorMessenger/Data/Browser/profile.default/
+cp cert_override.txt bundle/Browser/TorBrowser/Data/Browser/profile.default/
-cd bundle/Messenger/extensions
-tar xf ../../../[% c('input_files_by_name/ctypes-otr') %]
+cd bundle/Browser/TorBrowser/Data/Browser/profile.default/
+mkdir extensions
+cd extensions/
+tar xf ../../../../../../../[% c('input_files_by_name/ctypes-otr') %]
mv ctypes-otr* 'ctypes-otr@tormessenger'
+
mkdir tor-launcher(a)torproject.org
-7z x -y -otor-launcher(a)torproject.org ../../../[% c('input_files_by_name/tor-launcher') %]
+7z x -y -otor-launcher(a)torproject.org ../../../../../../../[% c('input_files_by_name/tor-launcher') %]
cat $rootdir/Bundle-Data/PTConfigs/bridge_prefs.js >> \
tor-launcher(a)torproject.org/defaults/preferences/prefs.js
-mkdir -p tor-launcher(a)torproject.org/TorBrowser/Data
+
[% IF c("var/windows") -%]
-7z x ../../../[% c('input_files_by_name/tor-browser') %]
+7z x ../../../../../../../[% c('input_files_by_name/tor-browser') %]
mv \$_OUTDIR tor-browser_en-US
cp -pf tor-browser_en-US/Browser/libssp-0.dll tor-browser_en-US/Browser/TorBrowser/Tor/
+
[% ELSE -%]
-tar xf ../../../[% c('input_files_by_name/tor-browser') %]
+tar xf ../../../../../../../[% c('input_files_by_name/tor-browser') %]
+
[% END -%]
sed -i 's/^SocksPort .*/SocksPort [% c("var/tor_socks_port") %]/' tor-browser_en-US/Browser/TorBrowser/Data/Tor/torrc-defaults
sed -i 's/^ControlPort .*/ControlPort [% c("var/tor_control_port") %]/' tor-browser_en-US/Browser/TorBrowser/Data/Tor/torrc-defaults
@@ -68,21 +73,25 @@ sed -i 's/^ControlPort .*/ControlPort [% c("var/tor_control_port") %]/' tor-brow
[% IF c("var/windows") -%]
# use meek in standalone mode: https://lists.torproject.org/pipermail/tor-dev/2015-November/009887.html
sed -i 's/\(ClientTransportPlugin meek exec\) [^ ]\+ [^ ]\+ -- /\1 /' tor-browser_en-US/Browser/TorBrowser/Data/Tor/torrc-defaults
-sed -i 's|TorBrowser\\Tor\\PluggableTransports|extensions\\tor-launcher(a)torproject.org\\TorBrowser\\Tor\\PluggableTransports|g' \
+sed -i 's|TorBrowser\\Tor\\PluggableTransports|TorBrowser\\Tor\\PluggableTransports|g' \
tor-browser_en-US/Browser/TorBrowser/Data/Tor/torrc-defaults
rm -f tor-browser_en-US/Browser/TorBrowser/Tor/PluggableTransports/meek-client-torbrowser.exe
[% ELSE -%]
# use meek in standalone mode: https://lists.torproject.org/pipermail/tor-dev/2015-November/009887.html
sed -i 's/\(ClientTransportPlugin meek exec\) [^ ]\+ -- /\1 /' tor-browser_en-US/Browser/TorBrowser/Data/Tor/torrc-defaults
-sed -i 's|TorBrowser/Tor/PluggableTransports|extensions/tor-launcher(a)torproject.org/TorBrowser/Tor/PluggableTransports|g' \
+sed -i 's|TorBrowser/Tor/PluggableTransports|TorBrowser/Tor/PluggableTransports|g' \
tor-browser_en-US/Browser/TorBrowser/Data/Tor/torrc-defaults
rm -f tor-browser_en-US/Browser/TorBrowser/Tor/PluggableTransports/meek-client-torbrowser
[% END -%]
-mv tor-browser_en-US/Browser/TorBrowser/Tor tor-launcher(a)torproject.org/TorBrowser/Tor
-mv tor-browser_en-US/Browser/TorBrowser/Data/Tor tor-launcher(a)torproject.org/TorBrowser/Data/Tor
-rm -Rf tor-browser_en-US
-cd ../../../
+cd ../../../../../../
+
+mv Browser/TorBrowser/Data/Browser/profile.default/extensions/tor-browser_en-US/Browser/TorBrowser/Tor Browser/TorBrowser/
+cp Browser/TorBrowser/Data/Browser/profile.default/extensions/tor-browser_en-US/Browser/TorBrowser/Data/Tor/* Browser/TorBrowser/Data/Tor/
+
+rm -Rf Browser/TorBrowser/Data/Browser/profile.default/extensions/tor-browser_en-US
+cd ..
+
mv bundle tor-messenger
[% IF c('var/windows') -%]
makensis tor-messenger.nsi
1
0

[tor-messenger-build/updater] Add patch or #16940 (also #14392)
by sukhbir@torproject.org 29 Jul '16
by sukhbir@torproject.org 29 Jul '16
29 Jul '16
commit 9cfd3634a5ab22c39b0ec715e3410c4ebebc5ed1
Author: Sukhbir Singh <sukhbir(a)torproject.org>
Date: Mon Jul 18 12:41:06 2016 -0400
Add patch or #16940 (also #14392)
---
...ate-load-local-changes-bug-14392-first.mozpatch | 18 +
...te-load-local-changes-bug-16940-second.mozpatch | 368 +++++++++++++++++++++
projects/instantbird/aboutTBUpdateLogo.png | Bin 0 -> 2724 bytes
3 files changed, 386 insertions(+)
diff --git a/projects/instantbird/Update-load-local-changes-bug-14392-first.mozpatch b/projects/instantbird/Update-load-local-changes-bug-14392-first.mozpatch
new file mode 100644
index 0000000..e1bc5bf
--- /dev/null
+++ b/projects/instantbird/Update-load-local-changes-bug-14392-first.mozpatch
@@ -0,0 +1,18 @@
+commit bb781597694015aed8ea4d121eac503542fd52f2
+Author: Mike Perry <mikeperry-git(a)torproject.org>
+Date: Wed Feb 11 16:45:24 2015 -0800
+
+ Bug 14392: Make about:tor behave like other initial pages.
+
+diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
+index 4f2642a..934a223 100644
+--- a/browser/base/content/browser.js
++++ b/browser/base/content/browser.js
+@@ -258,6 +258,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "LoginManagerParent",
+ "resource://gre/modules/LoginManagerParent.jsm");
+
+ var gInitialPages = [
++ "about:tor",
+ "about:blank",
+ "about:newtab",
+ "about:home",
diff --git a/projects/instantbird/Update-load-local-changes-bug-16940-second.mozpatch b/projects/instantbird/Update-load-local-changes-bug-16940-second.mozpatch
new file mode 100644
index 0000000..25aac2a
--- /dev/null
+++ b/projects/instantbird/Update-load-local-changes-bug-16940-second.mozpatch
@@ -0,0 +1,368 @@
+From 3815bb323160cf9163a07e36859c2ea83c905ace Mon Sep 17 00:00:00 2001
+From: Kathy Brade <brade(a)pearlcrescent.com>
+Date: Wed, 25 Nov 2015 11:36:20 -0500
+Subject: Bug 16940: After update, load local change notes.
+
+Add an about:tbupdate page that displays the first section from
+TorBrowser/Docs/ChangeLog.txt and includes a link to the remote
+post-update page (typically our blog entry for the release).
+
+diff --git a/browser/base/content/abouttbupdate/aboutTBUpdate.css b/browser/base/content/abouttbupdate/aboutTBUpdate.css
+new file mode 100644
+index 0000000..489c9d2
+--- /dev/null
++++ b/browser/base/content/abouttbupdate/aboutTBUpdate.css
+@@ -0,0 +1,34 @@
++body {
++ font-family: sans-serif;
++ font-size: 110%;
++ background-image: -moz-linear-gradient(top, #ffffff, #ffffff 10%, #d5ffd5 50%, #d5ffd5);
++ background-attachment: fixed;
++ background-size: 100% 100%;
++}
++
++#logo {
++ background-image: url("chrome://browser/content/abouttbupdate/aboutTBUpdateLogo.png");
++ height: 128px;
++ width: 128px;
++ margin: 20px;
++ float: left;
++}
++
++#msg {
++ margin-top: 50px;
++ float: left;
++}
++
++#msg-updated {
++ font-size: 120%;
++ margin-bottom: 20px;
++}
++
++#changelog-container {
++ margin: 0px 20px 20px 20px;
++}
++
++#changelog {
++ margin-left: 20px;
++ white-space: pre;
++}
+diff --git a/browser/base/content/abouttbupdate/aboutTBUpdate.js b/browser/base/content/abouttbupdate/aboutTBUpdate.js
+new file mode 100644
+index 0000000..8243647
+--- /dev/null
++++ b/browser/base/content/abouttbupdate/aboutTBUpdate.js
+@@ -0,0 +1,10 @@
++// Copyright (c) 2015, The Tor Project, Inc.
++// See LICENSE for licensing information.
++//
++// vim: set sw=2 sts=2 ts=8 et syntax=javascript:
++
++function init()
++{
++ let event = new CustomEvent("AboutTBUpdateLoad", { bubbles: true });
++ document.dispatchEvent(event);
++}
+diff --git a/browser/base/content/abouttbupdate/aboutTBUpdate.xhtml b/browser/base/content/abouttbupdate/aboutTBUpdate.xhtml
+new file mode 100644
+index 0000000..3a29e0c
+--- /dev/null
++++ b/browser/base/content/abouttbupdate/aboutTBUpdate.xhtml
+@@ -0,0 +1,34 @@
++<?xml version="1.0" encoding="UTF-8"?>
++
++<!DOCTYPE html [
++ <!ENTITY % htmlDTD
++ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
++ "DTD/xhtml1-strict.dtd">
++ %htmlDTD;
++ <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
++ %globalDTD;
++ <!ENTITY % tbUpdateDTD SYSTEM "chrome://browser/locale/aboutTBUpdate.dtd">
++ %tbUpdateDTD;
++]>
++
++<html xmlns="http://www.w3.org/1999/xhtml">
++<head>
++ <title>&aboutTBUpdate.title;</title>
++ <link rel="stylesheet" type="text/css"
++ href="chrome://browser/content/abouttbupdate/aboutTBUpdate.css"/>
++ <script src="chrome://browser/content/abouttbupdate/aboutTBUpdate.js"
++ type="text/javascript;version=1.7"/>
++</head>
++<body dir="&locale.dir;" onload="init()">
++<div id="logo"/>
++<div id="msg">
++<div id="msg-updated">&aboutTBUpdate.updated;</div>
++<div>&aboutTBUpdate.linkPrefix;<a id="infolink">&aboutTBUpdate.linkLabel;</a>&aboutTBUpdate.linkSuffix;
++</div>
++</div>
++<br clear="all"/>
++<div id="changelog-container">&aboutTBUpdate.changeLogHeading;
++<div id="changelog"></div>
++</div>
++</body>
++</html>
+diff --git a/browser/base/content/abouttbupdate/aboutTBUpdateLogo.png b/browser/base/content/abouttbupdate/aboutTBUpdateLogo.png
+new file mode 100644
+index 0000000..be5cae9
+Binary files /dev/null and b/browser/base/content/abouttbupdate/aboutTBUpdateLogo.png differ
+diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
+index 6e78084..0adbe61 100644
+--- a/browser/base/content/browser.js
++++ b/browser/base/content/browser.js
+@@ -259,6 +259,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "LoginManagerParent",
+
+ var gInitialPages = [
+ "about:tor",
++#ifdef TOR_BROWSER_UPDATE
++ "about:tbupdate",
++#endif
+ "about:blank",
+ "about:newtab",
+ "about:home",
+@@ -2425,8 +2428,14 @@ function URLBarSetURI(aURI) {
+
+ // Replace initial page URIs with an empty string
+ // only if there's no opener (bug 370555).
++#ifdef TOR_BROWSER_UPDATE
++ if (gInitialPages.indexOf(uri.spec.split('?')[0]) != -1 &&
++ checkEmptyPageOrigin(gBrowser.selectedBrowser, uri))
++#else
+ if (gInitialPages.indexOf(uri.spec) != -1 &&
+- checkEmptyPageOrigin(gBrowser.selectedBrowser, uri)) {
++ checkEmptyPageOrigin(gBrowser.selectedBrowser, uri))
++#endif
++ {
+ value = "";
+ } else {
+ value = losslessDecodeURI(uri);
+@@ -7043,7 +7052,11 @@ var gIdentityHandler = {
+ this._uriHasHost = false;
+ }
+
+- let whitelist = /^(?:accounts|addons|cache|config|crashes|customizing|downloads|healthreport|home|license|newaddon|permissions|preferences|privatebrowsing|rights|sessionrestore|support|welcomeback)(?:[?#]|$)/i;
++#ifdef TOR_BROWSER_UPDATE
++ let whitelist = /^(?:accounts|addons|cache|config|crashes|customizing|downloads|healthreport|home|license|newaddon|permissions|preferences|privatebrowsing|rights|sessionrestore|support|welcomeback|tor|tbupdate)(?:[?#]|$)/i;
++#else
++ let whitelist = /^(?:accounts|addons|cache|config|crashes|customizing|downloads|healthreport|home|license|newaddon|permissions|preferences|privatebrowsing|rights|sessionrestore|support|welcomeback|tor)(?:[?#]|$)/i;
++#endif
+ this._isSecureInternalUI = uri.schemeIs("about") && whitelist.test(uri.path);
+
+ this._sslStatus = gBrowser.securityUI
+diff --git a/browser/base/content/tab-content.js b/browser/base/content/tab-content.js
+index c8f39ee..44489a2 100644
+--- a/browser/base/content/tab-content.js
++++ b/browser/base/content/tab-content.js
+@@ -10,6 +10,9 @@ var {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+ Cu.import("resource://gre/modules/Services.jsm");
+ Cu.import("resource://gre/modules/ExtensionContent.jsm");
++#ifdef TOR_BROWSER_UPDATE
++Cu.import("resource://gre/modules/NetUtil.jsm");
++#endif
+
+ XPCOMUtils.defineLazyModuleGetter(this, "E10SUtils",
+ "resource:///modules/E10SUtils.jsm");
+@@ -368,6 +371,82 @@ var AboutReaderListener = {
+ };
+ AboutReaderListener.init();
+
++#ifdef TOR_BROWSER_UPDATE
++let AboutTBUpdateListener = {
++ init: function(chromeGlobal) {
++ chromeGlobal.addEventListener('AboutTBUpdateLoad', this, false, true);
++ },
++
++ get isAboutTBUpdate() {
++ return content.document.documentURI.split('?')[0].toLowerCase()
++ == "about:tbupdate";
++ },
++
++ handleEvent: function(aEvent) {
++ if (this.isAboutTBUpdate && (aEvent.type == "AboutTBUpdateLoad"))
++ this.onPageLoad();
++ },
++
++ onPageLoad: function() {
++ let doc = content.document;
++ doc.getElementById("infolink").setAttribute("href", this.getPostUpdateURL());
++ doc.getElementById("changelog").textContent = this.getChangeLogText();
++ },
++
++ // Extract the post update URL from this page's query string.
++ getPostUpdateURL: function() {
++ let idx = content.document.documentURI.indexOf('?');
++ if (idx > 0)
++ return decodeURIComponent(content.document.documentURI.substring(idx+1));
++
++ // No query string: use the default URL.
++ return Services.urlFormatter.formatURLPref("startup.homepage_override_url");
++ },
++
++ // Read and return the text from the beginning of the changelog file that is
++ // located at TorBrowser/Docs/ChangeLog.txt.
++ // On Mac OS, when building with --enable-tor-browser-data-outside-app-dir
++ // to support Gatekeeper signing, the file is located in
++ // TorBrowser.app/Contents/Resources/TorBrowser/Docs/.
++ //
++ // When electrolysis is enabled we will need to adopt an architecture that is
++ // more similar to the one that is used for about:home (see AboutHomeListener
++ // in this file and browser/modules/AboutHome.jsm).
++ getChangeLogText: function() {
++ try {
++#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
++ // "XREExeF".parent is the directory that contains firefox, i.e.,
++ // Browser/ or, on Mac OS, TorBrowser.app/Contents/MacOS/.
++ let f = Services.dirsvc.get("XREExeF", Ci.nsIFile).parent;
++#ifdef XP_MACOSX
++ f = f.parent;
++ f.append("Resources");
++#endif
++ f.append("TorBrowser");
++#else
++ // "DefProfRt" is .../TorBrowser/Data/Browser
++ let f = Cc["@mozilla.org/file/directory_service;1"]
++ .getService(Ci.nsIProperties).get("DefProfRt", Ci.nsIFile);
++ f = f.parent.parent; // Remove "Data/Browser"
++#endif
++ f.append("Docs");
++ f.append("ChangeLog.txt");
++
++ let fs = Cc["@mozilla.org/network/file-input-stream;1"]
++ .createInstance(Ci.nsIFileInputStream);
++ fs.init(f, -1, 0, 0);
++ let s = NetUtil.readInputStreamToString(fs, fs.available());
++ fs.close();
++
++ // Truncate at the first empty line.
++ return s.replace(/[\r\n][\r\n][\s\S]*$/m, "");
++ } catch (e) {}
++
++ return "";
++ },
++};
++AboutTBUpdateListener.init(this);
++#endif
+
+ var ContentSearchMediator = {
+
+diff --git a/browser/base/jar.mn b/browser/base/jar.mn
+index a39f8fa..45f6e09 100644
+--- a/browser/base/jar.mn
++++ b/browser/base/jar.mn
+@@ -73,8 +73,14 @@ browser.jar:
+ content/browser/aboutTabCrashed.xhtml (content/aboutTabCrashed.xhtml)
+ * content/browser/aboutTabGroupsMigration.xhtml (content/aboutTabGroupsMigration.xhtml)
+ content/browser/aboutTabGroupsMigration.js (content/aboutTabGroupsMigration.js)
++#ifdef TOR_BROWSER_UPDATE
++ content/browser/abouttbupdate/aboutTBUpdate.xhtml (content/abouttbupdate/aboutTBUpdate.xhtml)
++ content/browser/abouttbupdate/aboutTBUpdate.js (content/abouttbupdate/aboutTBUpdate.js)
++ content/browser/abouttbupdate/aboutTBUpdate.css (content/abouttbupdate/aboutTBUpdate.css)
++ content/browser/abouttbupdate/aboutTBUpdateLogo.png (content/abouttbupdate/aboutTBUpdateLogo.png)
++#endif
+ * content/browser/browser.css (content/browser.css)
+- content/browser/browser.js (content/browser.js)
++* content/browser/browser.js (content/browser.js)
+ * content/browser/browser.xul (content/browser.xul)
+ content/browser/browser-addons.js (content/browser-addons.js)
+ content/browser/browser-ctrlTab.js (content/browser-ctrlTab.js)
+@@ -104,7 +110,7 @@ browser.jar:
+ content/browser/browser-thumbnails.js (content/browser-thumbnails.js)
+ content/browser/browser-trackingprotection.js (content/browser-trackingprotection.js)
+ * content/browser/chatWindow.xul (content/chatWindow.xul)
+- content/browser/tab-content.js (content/tab-content.js)
++* content/browser/tab-content.js (content/tab-content.js)
+ content/browser/content.js (content/content.js)
+ content/browser/social-content.js (content/social-content.js)
+ content/browser/defaultthemes/1.footer.jpg (content/defaultthemes/1.footer.jpg)
+diff --git a/browser/components/about/AboutRedirector.cpp b/browser/components/about/AboutRedirector.cpp
+index 78f55c9..ab069e5 100644
+--- a/browser/components/about/AboutRedirector.cpp
++++ b/browser/components/about/AboutRedirector.cpp
+@@ -138,6 +138,13 @@ static RedirEntry kRedirMap[] = {
+ nsIAboutModule::ALLOW_SCRIPT |
+ nsIAboutModule::HIDE_FROM_ABOUTABOUT |
+ nsIAboutModule::MAKE_UNLINKABLE },
++#ifdef TOR_BROWSER_UPDATE
++ { "tbupdate", "chrome://browser/content/abouttbupdate/aboutTBUpdate.xhtml",
++ nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
++ nsIAboutModule::ALLOW_SCRIPT |
++ nsIAboutModule::MAKE_UNLINKABLE |
++ nsIAboutModule::HIDE_FROM_ABOUTABOUT },
++#endif
+ };
+ static const int kRedirTotal = ArrayLength(kRedirMap);
+
+diff --git a/browser/components/build/nsModule.cpp b/browser/components/build/nsModule.cpp
+index 7950d7c..a316cb3 100644
+--- a/browser/components/build/nsModule.cpp
++++ b/browser/components/build/nsModule.cpp
+@@ -115,6 +115,9 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
+ { NS_ABOUT_MODULE_CONTRACTID_PREFIX "reader", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
+ { NS_ABOUT_MODULE_CONTRACTID_PREFIX "pocket-saved", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
+ { NS_ABOUT_MODULE_CONTRACTID_PREFIX "pocket-signup", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
++#ifdef TOR_BROWSER_UPDATE
++ { NS_ABOUT_MODULE_CONTRACTID_PREFIX "tbupdate", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
++#endif
+ #if defined(XP_WIN)
+ { NS_IEHISTORYENUMERATOR_CONTRACTID, &kNS_WINIEHISTORYENUMERATOR_CID },
+ #elif defined(XP_MACOSX)
+diff --git a/browser/components/nsBrowserContentHandler.js b/browser/components/nsBrowserContentHandler.js
+index b892eaf..8cc5cc5 100644
+--- a/browser/components/nsBrowserContentHandler.js
++++ b/browser/components/nsBrowserContentHandler.js
+@@ -573,6 +573,13 @@ nsBrowserContentHandler.prototype = {
+ // into account because that requires waiting for the session file
+ // to be read. If a crash occurs after updating, before restarting,
+ // we may open the startPage in addition to restoring the session.
++ //
++ // Tor Browser: Instead of opening the post-update "override page"
++ // directly, an about:tbupdate page is opened that includes a link
++ // to the override page as well as text from the first part of the
++ // local ChangeLog.txt file. The override page URL comes from the
++ // openURL attribute within the updates.xml file or, if no showURL
++ // action is present, from the startup.homepage_override_url pref.
+ var ss = Components.classes["@mozilla.org/browser/sessionstartup;1"]
+ .getService(Components.interfaces.nsISessionStartup);
+ willRestoreSession = ss.isAutomaticRestoreEnabled();
+@@ -586,6 +593,11 @@ nsBrowserContentHandler.prototype = {
+ overridePage = overridePage.replace("%OLD_TOR_BROWSER_VERSION%",
+ old_tbversion);
+ #endif
++
++#ifdef TOR_BROWSER_UPDATE
++ if (overridePage)
++ overridePage = "about:tbupdate?" + encodeURIComponent(overridePage);
++#endif
+ break;
+ }
+ }
+diff --git a/browser/locales/en-US/chrome/browser/aboutTBUpdate.dtd b/browser/locales/en-US/chrome/browser/aboutTBUpdate.dtd
+new file mode 100644
+index 0000000..37567bd
+--- /dev/null
++++ b/browser/locales/en-US/chrome/browser/aboutTBUpdate.dtd
+@@ -0,0 +1,6 @@
++<!ENTITY aboutTBUpdate.title "Tor Messenger Update">
++<!ENTITY aboutTBUpdate.updated "Tor Messenger has been updated.">
++<!ENTITY aboutTBUpdate.linkPrefix "For the most up-to-date information about this release, ">
++<!ENTITY aboutTBUpdate.linkLabel "visit our website">
++<!ENTITY aboutTBUpdate.linkSuffix ".">
++<!ENTITY aboutTBUpdate.changeLogHeading "Changelog:">
+diff --git a/browser/locales/jar.mn b/browser/locales/jar.mn
+index 44c5e6a..0f18e06 100644
+--- a/browser/locales/jar.mn
++++ b/browser/locales/jar.mn
+@@ -21,6 +21,9 @@
+ locale/browser/aboutTabCrashed.dtd (%chrome/browser/aboutTabCrashed.dtd)
+ locale/browser/syncCustomize.dtd (%chrome/browser/syncCustomize.dtd)
+ locale/browser/aboutSyncTabs.dtd (%chrome/browser/aboutSyncTabs.dtd)
++#ifdef TOR_BROWSER_UPDATE
++ locale/browser/aboutTBUpdate.dtd (%chrome/browser/aboutTBUpdate.dtd)
++#endif
+ locale/browser/browser.dtd (%chrome/browser/browser.dtd)
+ locale/browser/baseMenuOverlay.dtd (%chrome/browser/baseMenuOverlay.dtd)
+ locale/browser/browser.properties (%chrome/browser/browser.properties)
+--
+cgit v0.10.2
diff --git a/projects/instantbird/aboutTBUpdateLogo.png b/projects/instantbird/aboutTBUpdateLogo.png
new file mode 100644
index 0000000..3de3c93
Binary files /dev/null and b/projects/instantbird/aboutTBUpdateLogo.png differ
1
0

[tor-messenger-build/updater] aboutDialog.xul should be preprocessed
by sukhbir@torproject.org 29 Jul '16
by sukhbir@torproject.org 29 Jul '16
29 Jul '16
commit 643c8ef077c5ff8f2381f40877e6751f6d0d7098
Author: Sukhbir Singh <sukhbir(a)torproject.org>
Date: Mon Jul 18 22:12:30 2016 -0400
aboutDialog.xul should be preprocessed
---
projects/instantbird/aboutDialog-jar.patch | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/projects/instantbird/aboutDialog-jar.patch b/projects/instantbird/aboutDialog-jar.patch
index 0257e61..96a1498 100644
--- a/projects/instantbird/aboutDialog-jar.patch
+++ b/projects/instantbird/aboutDialog-jar.patch
@@ -7,7 +7,7 @@ diff --git a/im/content/jar.mn b/im/content/jar.mn
content/instantbird/aboutDialog.css
-* content/instantbird/aboutDialog.xul
- content/instantbird/aboutPanel.xml
-+ content/instantbird/aboutDialog.xul
++* content/instantbird/aboutDialog.xul
+* content/instantbird/aboutDialog.js
+* content/instantbird/aboutDialog-appUpdater.js
content/instantbird/account.js
1
0

[tor-messenger-build/updater] Use Debian 7.11 image for Linux builds
by sukhbir@torproject.org 29 Jul '16
by sukhbir@torproject.org 29 Jul '16
29 Jul '16
commit 9979e309fa0a311602826a763e81af441ce05cbf
Author: Sukhbir Singh <sukhbir(a)torproject.org>
Date: Wed Jul 13 15:42:17 2016 -0400
Use Debian 7.11 image for Linux builds
---
projects/instantbird/config | 4 ++--
rbm.conf | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/projects/instantbird/config b/projects/instantbird/config
index 324afd7..b3623d6 100644
--- a/projects/instantbird/config
+++ b/projects/instantbird/config
@@ -36,7 +36,7 @@ targets:
linux-x86_64:
var:
arch_deps:
- - yasm-1
+ - yasm
linux-i686:
var:
arch_deps:
@@ -44,7 +44,7 @@ targets:
- ia32-libs
- lib32z1-dev
- lib32asound2-dev
- - yasm-1
+ - yasm
osx-x86_64:
var:
arch_deps:
diff --git a/rbm.conf b/rbm.conf
index 7d35cc2..c3b3a3b 100644
--- a/rbm.conf
+++ b/rbm.conf
@@ -27,14 +27,14 @@ targets:
noint:
debug: 0
linux-x86_64:
- distribution: Ubuntu-10.04
+ distribution: Debian-7.11
arch: x86_64
var:
linux: 1
osname: linux-x86_64
compiler: gcc
linux-i686:
- distribution: Ubuntu-10.04
+ distribution: Debian-7.11
arch: i686
var:
linux: 1
1
0

[tor-messenger-build/updater] Use the about dialog from Firefox
by sukhbir@torproject.org 29 Jul '16
by sukhbir@torproject.org 29 Jul '16
29 Jul '16
commit 3b8cae90376092d4926d59c23be2cf7e3b9559db
Author: Sukhbir Singh <sukhbir(a)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(a)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(a)2x.png b/projects/instantbird/about-logo(a)2x.png
new file mode 100644
index 0000000..99d626e
Binary files /dev/null and b/projects/instantbird/about-logo(a)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_defau…. -->
+<!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/">
+ &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">
+ &help.donateLink;
+ </label>
+ &help.or;
+ <label class="text-link"
+ href="https://www.torproject.org/getinvolved/volunteer.html.en">
+ &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_defau…">&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">
+ &bottomLinks.questions;
+ </label>
+ <label class="text-link bottom-link"
+ href="https://www.torproject.org/getinvolved/relays">
+ &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(a)2x.png (content/about-logo(a)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(a)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(a)2x.png
+ - filename: about-wordmark.png
+ - filename: branding-aboutDialog.css
- filename: branding/osx.patch
enable: '[% c("var/osx") %]'
- filename: bug-1218193.patch
1
0