66fa9fdc51
DOMInputPasswordAdded event is triggered on autocomplete submission which causes an error in LoginManager. The error gets logged in the console, though the autocomplete does work. This just removes the event from ActorManagerParent. Fixes: #3883
549 lines
25 KiB
Bash
Executable file
549 lines
25 KiB
Bash
Executable file
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# Copyright (c) 2011 Zotero
|
|
# Center for History and New Media
|
|
# George Mason University, Fairfax, Virginia, USA
|
|
# http://zotero.org
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
APP_ROOT_DIR="$(dirname "$SCRIPT_DIR")"
|
|
. "$APP_ROOT_DIR/config.sh"
|
|
cd "$APP_ROOT_DIR"
|
|
|
|
function usage {
|
|
cat >&2 <<DONE
|
|
Usage: $0 -p platforms [-s]
|
|
Options
|
|
-p PLATFORMS Platforms to build (m=Mac, w=Windows, l=Linux)
|
|
DONE
|
|
exit 1
|
|
}
|
|
|
|
BUILD_MAC=0
|
|
BUILD_WIN=0
|
|
BUILD_LINUX=0
|
|
while getopts "p:s" opt; do
|
|
case $opt in
|
|
p)
|
|
for i in `seq 0 1 $((${#OPTARG}-1))`
|
|
do
|
|
case ${OPTARG:i:1} in
|
|
m) BUILD_MAC=1;;
|
|
w) BUILD_WIN=1;;
|
|
l) BUILD_LINUX=1;;
|
|
*)
|
|
echo "$0: Invalid platform option ${OPTARG:i:1}"
|
|
usage
|
|
;;
|
|
esac
|
|
done
|
|
;;
|
|
esac
|
|
shift $((OPTIND-1)); OPTIND=1
|
|
done
|
|
|
|
# Require at least one platform
|
|
if [[ $BUILD_MAC == 0 ]] && [[ $BUILD_WIN == 0 ]] && [[ $BUILD_LINUX == 0 ]]; then
|
|
usage
|
|
fi
|
|
|
|
function replace_line {
|
|
pattern=$1
|
|
replacement=$2
|
|
file=$3
|
|
|
|
if egrep -q "$pattern" "$file"; then
|
|
perl -pi -e "s/$pattern/$replacement/" "$file"
|
|
else
|
|
echo "$pattern" not found in "$file" -- aborting 2>&1
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
function remove_line {
|
|
pattern=$1
|
|
file=$2
|
|
|
|
if egrep -q "$pattern" "$file"; then
|
|
egrep -v "$pattern" "$file" > "$file.tmp"
|
|
mv "$file.tmp" "$file"
|
|
else
|
|
echo "$pattern" not found in "$file" -- aborting 2>&1
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
function get_utf16_chars {
|
|
str=$(echo -n "$1" | xxd -p | fold -w 2 | sed -r 's/(.+)/\\\\x{\1}\\\\x{00}/')
|
|
# Add NUL padding
|
|
if [ -n "${2:-}" ]; then
|
|
# Multiply characters x 2 for UTF-16
|
|
for i in `seq 1 $(($2 * 2))`; do
|
|
str+=$(echo '\\x{00}')
|
|
done
|
|
fi
|
|
echo $str | xargs | sed 's/ //g'
|
|
}
|
|
|
|
#
|
|
# Make various modifications to the stock Firefox app
|
|
#
|
|
function modify_omni {
|
|
platform=$1
|
|
|
|
mkdir omni
|
|
mv omni.ja omni
|
|
cd omni
|
|
# omni.ja is an "optimized" ZIP file, so use a script from Mozilla to avoid a warning from unzip
|
|
# here and to make it work after rezipping below
|
|
python3 "$APP_ROOT_DIR/scripts/optimizejars.py" --deoptimize ./ ./ ./
|
|
rm -f omni.ja.log
|
|
unzip omni.ja
|
|
rm omni.ja
|
|
|
|
replace_line 'BROWSER_CHROME_URL:.+' 'BROWSER_CHROME_URL: "chrome:\/\/zotero\/content\/zoteroPane.xhtml",' modules/AppConstants.sys.mjs
|
|
|
|
# https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/internals/preferences.html
|
|
#
|
|
# It's not clear that most of these do anything anymore when not compiled in, but just in case
|
|
replace_line 'MOZ_REQUIRE_SIGNING:' 'MOZ_REQUIRE_SIGNING: false \&\&' modules/AppConstants.sys.mjs
|
|
replace_line 'MOZ_DATA_REPORTING:' 'MOZ_DATA_REPORTING: false \&\&' modules/AppConstants.sys.mjs
|
|
replace_line 'MOZ_SERVICES_HEALTHREPORT:' 'MOZ_SERVICES_HEALTHREPORT: false \&\&' modules/AppConstants.sys.mjs
|
|
replace_line 'MOZ_TELEMETRY_REPORTING:' 'MOZ_TELEMETRY_REPORTING: false \&\&' modules/AppConstants.sys.mjs
|
|
replace_line 'MOZ_TELEMETRY_ON_BY_DEFAULT:' 'MOZ_TELEMETRY_ON_BY_DEFAULT: false \&\&' modules/AppConstants.sys.mjs
|
|
replace_line 'MOZ_CRASHREPORTER:' 'MOZ_CRASHREPORTER: false \&\&' modules/AppConstants.sys.mjs
|
|
replace_line 'MOZ_UPDATE_CHANNEL:.+' 'MOZ_UPDATE_CHANNEL: "none",' modules/AppConstants.sys.mjs
|
|
replace_line '"https:\/\/[^\/]+mozilla.com.+"' '""' modules/AppConstants.sys.mjs
|
|
|
|
# Don't use Mozilla Maintenance Service on Windows
|
|
replace_line 'MOZ_MAINTENANCE_SERVICE:' 'MOZ_MAINTENANCE_SERVICE: false \&\&' modules/AppConstants.sys.mjs
|
|
# Continue using app.update.auto in prefs.js on Windows
|
|
replace_line 'PER_INSTALLATION_PREFS_PLATFORMS = \["win"\]' 'PER_INSTALLATION_PREFS_PLATFORMS = []' modules/UpdateUtils.sys.mjs
|
|
|
|
# Prompt if major update is available instead of installing automatically on restart
|
|
replace_line 'if \(!updateAuto\) \{' 'if (update.type == "major") {
|
|
LOG("UpdateService:_selectAndInstallUpdate - prompting because it is a major update");
|
|
AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_SHOWPROMPT_PREF);
|
|
Services.obs.notifyObservers(update, "update-available", "show-prompt");
|
|
return;
|
|
}
|
|
if (!updateAuto) {' modules/UpdateService.sys.mjs
|
|
|
|
# Avoid console warning about resource://gre/modules/FxAccountsCommon.js
|
|
replace_line 'const logins = this._data.logins;' 'const logins = this._data.logins; if (this._data.logins.length != -1) return;' modules/LoginStore.sys.mjs
|
|
|
|
# Prevent error during network requests
|
|
replace_line 'async lazyInit\(\) \{' 'async lazyInit() { if (this.features) return false;' modules/UrlClassifierExceptionListService.sys.mjs
|
|
|
|
replace_line 'pref\("network.captive-portal-service.enabled".+' 'pref("network.captive-portal-service.enabled", false);' greprefs.js
|
|
replace_line 'pref\("network.connectivity-service.enabled".+' 'pref("network.connectivity-service.enabled", false);' greprefs.js
|
|
replace_line 'pref\("toolkit.telemetry.server".+' 'pref("toolkit.telemetry.server", "");' greprefs.js
|
|
replace_line 'pref\("toolkit.telemetry.unified".+' 'pref("toolkit.telemetry.unified", false);' greprefs.js
|
|
replace_line 'pref\("media.gmp-manager.url".+' 'pref("media.gmp-manager.url", "");' greprefs.js
|
|
|
|
#
|
|
# # Disable transaction timeout
|
|
# perl -pi -e 's/let timeoutPromise/\/*let timeoutPromise/' modules/Sqlite.jsm
|
|
# perl -pi -e 's/return Promise.race\(\[transactionPromise, timeoutPromise\]\);/*\/return transactionPromise;/' modules/Sqlite.jsm
|
|
# rm -f jsloader/resource/gre/modules/Sqlite.jsm
|
|
#
|
|
# Disable unwanted components
|
|
remove_line '(RemoteSettings|services-|telemetry|Telemetry|URLDecorationAnnotationsService)' components/components.manifest
|
|
|
|
# Do not trigger LoginManager event that logs an error on autocomplete submission
|
|
remove_line 'DOMInputPasswordAdded: \{\},' modules/ActorManagerParent.sys.mjs
|
|
|
|
# On Mac/Linux, ignore relative paths in PATH in Subprocess.pathSearch(), used when a bare command is passed to Utilities.Internal.subprocess()
|
|
if [[ $platform != win* ]]; then
|
|
replace_line 'let path = PathUtils.join\(dir, bin\);' 'if (!dir.startsWith("\/")) continue; let path = PathUtils.join(dir, bin);' modules/subprocess/subprocess_unix.sys.mjs
|
|
fi
|
|
|
|
# Remove unwanted files
|
|
rm modules/FxAccounts*
|
|
# Causes a startup error -- try an empty file or a shim instead?
|
|
#rm modules/Telemetry*
|
|
rm modules/URLDecorationAnnotationsService.sys.mjs
|
|
rm -rf modules/services-*
|
|
|
|
# Clear most WebExtension manifest properties
|
|
replace_line 'manifest = normalized.value;' 'manifest = normalized.value;
|
|
if (this.type == "extension") {
|
|
if (!manifest.applications?.zotero?.id) {
|
|
this.manifestError("applications.zotero.id not provided");
|
|
}
|
|
if (!manifest.applications?.zotero?.update_url) {
|
|
this.manifestError("applications.zotero.update_url not provided");
|
|
}
|
|
if (!manifest.applications?.zotero?.strict_max_version) {
|
|
this.manifestError("applications.zotero.strict_max_version not provided");
|
|
}
|
|
manifest.browser_specific_settings = undefined;
|
|
manifest.content_scripts = [];
|
|
manifest.permissions = [];
|
|
manifest.host_permissions = [];
|
|
manifest.web_accessible_resources = undefined;
|
|
manifest.experiment_apis = {};
|
|
}' modules/Extension.sys.mjs
|
|
|
|
# Use applications.zotero instead of applications.gecko
|
|
replace_line 'let bss = manifest.applications\?.gecko' 'let bss = manifest.applications?.zotero' modules/addons/XPIInstall.jsm
|
|
replace_line 'manifest.applications\?.gecko' 'manifest.applications?.zotero' modules/Extension.sys.mjs
|
|
|
|
# When installing addon, use app version instead of toolkit version for targetApplication
|
|
replace_line "id: TOOLKIT_ID," "id: '$APP_ID'," modules/addons/XPIInstall.jsm
|
|
|
|
# Accept zotero@chnm.gmu.edu for target application to allow Zotero 6 plugins to remain
|
|
# installed in Zotero 7
|
|
replace_line "if \(targetApp.id == Services.appinfo.ID\) \{" "if (targetApp.id == 'zotero\@chnm.gmu.edu') targetApp.id = '$APP_ID'; if (targetApp.id == Services.appinfo.ID) {" modules/addons/XPIDatabase.jsm
|
|
# Fix addon.id is undefined with built-in theme addons, anyway we don't support theme addons
|
|
replace_line 'addon.type === "theme"' 'false' modules/addons/XPIDatabase.jsm
|
|
|
|
# For updates, look for applications.zotero instead of applications.gecko in manifest.json and
|
|
# use the app id and version for strict_min_version/strict_max_version comparisons
|
|
replace_line 'gecko: \{\},' 'zotero: {},' modules/addons/AddonUpdateChecker.sys.mjs
|
|
replace_line 'if \(!\("gecko" in applications\)\) \{' 'if (!("zotero" in applications)) {' modules/addons/AddonUpdateChecker.sys.mjs
|
|
replace_line '"gecko not in application entry' '"zotero not in application entry' modules/addons/AddonUpdateChecker.sys.mjs
|
|
replace_line 'let app = getProperty\(applications, "gecko", "object"\);' 'let app = getProperty(applications, "zotero", "object");' modules/addons/AddonUpdateChecker.sys.mjs
|
|
replace_line "id: TOOLKIT_ID," "id: '$APP_ID'," modules/addons/AddonUpdateChecker.sys.mjs
|
|
replace_line 'lazy.AddonManagerPrivate.webExtensionsMinPlatformVersion' '"7.0"' modules/addons/AddonUpdateChecker.sys.mjs
|
|
replace_line 'result.targetApplications.push' 'false && result.targetApplications.push' modules/addons/AddonUpdateChecker.sys.mjs
|
|
|
|
# Allow addon installation by bypassing confirmation dialogs. If we want a confirmation dialog,
|
|
# we need to either add gXPInstallObserver from browser-addons.js [1][2] or provide our own with
|
|
# Ci.amIWebInstallPrompt [3].
|
|
#
|
|
# [1] https://searchfox.org/mozilla-esr102/rev/5a6d529652045050c5cdedc0558238949b113741/browser/base/content/browser.js#1902-1923
|
|
# [2] https://searchfox.org/mozilla-esr102/rev/5a6d529652045050c5cdedc0558238949b113741/browser/base/content/browser-addons.js#201
|
|
# [3] https://searchfox.org/mozilla-esr102/rev/5a6d529652045050c5cdedc0558238949b113741/toolkit/mozapps/extensions/AddonManager.sys.mjs#3114-3124
|
|
replace_line 'if \(info.addon.userPermissions\) \{' 'if (false) {' modules/AddonManager.sys.mjs
|
|
replace_line '\} else if \(info.addon.sitePermissions\) \{' '} else if (false) {' modules/AddonManager.sys.mjs
|
|
replace_line '\} else if \(requireConfirm\) \{' '} else if (false) {' modules/AddonManager.sys.mjs
|
|
|
|
# Make addon listener methods wait for promises, to allow calling asynchronous plugin `shutdown`
|
|
# and `uninstall` methods in our `onInstalling` handler
|
|
replace_line 'callAddonListeners\(aMethod' 'async callAddonListeners(aMethod' modules/AddonManager.sys.mjs
|
|
# Don't need this one to be async, but we can't easily avoid modifying its `listener[aMethod].apply()` call
|
|
replace_line 'callManagerListeners\(aMethod' 'async callManagerListeners(aMethod' modules/AddonManager.sys.mjs
|
|
replace_line 'AddonManagerInternal.callAddonListeners.apply\(AddonManagerInternal, aArgs\);' \
|
|
'return AddonManagerInternal.callAddonListeners.apply(AddonManagerInternal, aArgs);' modules/AddonManager.sys.mjs
|
|
replace_line 'listener\[aMethod\].apply\(listener, aArgs\);' \
|
|
'let maybePromise = listener[aMethod].apply(listener, aArgs);
|
|
if (maybePromise && maybePromise.then) await maybePromise;' modules/AddonManager.sys.mjs
|
|
replace_line 'AddonManagerPrivate.callAddonListeners' 'await AddonManagerPrivate.callAddonListeners' modules/addons/XPIInstall.jsm
|
|
replace_line 'let uninstall = \(\) => \{' 'let uninstall = async () => {' modules/addons/XPIInstall.jsm
|
|
replace_line 'cancelUninstallAddon\(aAddon\)' 'async cancelUninstallAddon(aAddon)' modules/addons/XPIInstall.jsm
|
|
|
|
# No idea why this is necessary, but without it initialization fails with "TypeError: "constructor" is read-only"
|
|
replace_line 'LoginStore.prototype.constructor = LoginStore;' '\/\/LoginStore.prototype.constructor = LoginStore;' modules/LoginStore.sys.mjs
|
|
#
|
|
# # Allow proxy password saving
|
|
# perl -pi -e 's/get _inPrivateBrowsing\(\) \{/get _inPrivateBrowsing() {if (true) { return false; }/' components/nsLoginManagerPrompter.js
|
|
#
|
|
# # Change text in update dialog
|
|
# perl -pi -e 's/A security and stability update for/A new version of/' chrome/en-US/locale/en-US/mozapps/update/updates.properties
|
|
# perl -pi -e 's/updateType_major=New Version/updateType_major=New Major Version/' chrome/en-US/locale/en-US/mozapps/update/updates.properties
|
|
# perl -pi -e 's/updateType_minor=Security Update/updateType_minor=New Version/' chrome/en-US/locale/en-US/mozapps/update/updates.properties
|
|
# perl -pi -e 's/update for &brandShortName; as soon as possible/update as soon as possible/' chrome/en-US/locale/en-US/mozapps/update/updates.dtd
|
|
#
|
|
# Set available locales
|
|
cp "$APP_ROOT_DIR/assets/multilocale.txt" res/multilocale.txt
|
|
|
|
# Use Zotero URL opening in Mozilla dialogs (e.g., app update dialog)
|
|
replace_line 'function openURL\(aURL\) \{' 'function openURL(aURL) {let {Zotero} = ChromeUtils.importESModule("chrome:\/\/zotero\/content\/zotero.mjs"); Zotero.launchURL(aURL); if (true) { return; }' chrome/toolkit/content/global/contentAreaUtils.js
|
|
|
|
#
|
|
# Modify Add-ons window
|
|
#
|
|
|
|
# Prevent display: block from overriding display: none on <hr>s
|
|
replace_line 'display: block !important;' 'display: block;' chrome/toolkit/content/global/elements/panel-list.css
|
|
|
|
file="chrome/toolkit/content/mozapps/extensions/aboutaddons.css"
|
|
echo >> $file
|
|
# Hide search bar, Themes and Plugins tabs, and sidebar footer
|
|
echo '.main-search, button[name="theme"], button[name="plugin"], sidebar-footer { display: none; }' >> $file
|
|
echo '.main-heading { margin-top: 2em; }' >> $file
|
|
# Hide Details/Permissions tabs in addon details so we only show details
|
|
echo 'addon-details > button-group { display: none !important; }' >> $file
|
|
# Hide "Debug Addons" and "Manage Extension Shortcuts"
|
|
echo 'panel-item[action="debug-addons"], panel-item[action="reset-update-states"] + hr, panel-item[action="manage-shortcuts"] { display: none }' >> $file
|
|
# Show cursor feedback on plugin homepage links
|
|
echo '.addon-detail-row-homepage .text-link { cursor: pointer; color: -moz-nativehyperlinktext; }' >> $file
|
|
echo '.addon-detail-row-homepage .text-link:hover { text-decoration: underline; }' >> $file
|
|
|
|
file="chrome/toolkit/content/mozapps/extensions/aboutaddons.js"
|
|
# Hide unsigned-addon warning
|
|
replace_line 'if \(!isCorrectlySigned\(addon\)\) \{' 'if (!isCorrectlySigned(addon)) {return {};' $file
|
|
# Hide Private Browsing setting in addon details
|
|
replace_line 'pbRow\.' '\/\/pbRow.' $file
|
|
replace_line 'let isAllowed = await isAllowedInPrivateBrowsing' '\/\/let isAllowed = await isAllowedInPrivateBrowsing' $file
|
|
# Use our own strings for the removal prompt
|
|
replace_line 'let \{ BrowserAddonUI \} = windowRoot.ownerGlobal;' '' $file
|
|
replace_line 'await BrowserAddonUI.promptRemoveExtension' 'promptRemoveExtension' $file
|
|
|
|
# Customize empty-list message
|
|
replace_line 'createEmptyListMessage\(\) {' 'createEmptyListMessage() {
|
|
var p = document.createElement("p");
|
|
p.id = "empty-list-message";
|
|
return p;' $file
|
|
# Swap in include.js, which we need for Zotero.getString(), for abuse-reports.js, which we don't need
|
|
|
|
# Open plugin links in external browser
|
|
replace_line 'let homepageURL = homepageRow.querySelector\(\"a\"\);' 'let homepageURL = homepageRow.querySelector(\"\.text-link\");' $file
|
|
replace_line 'homepageURL.href = addon.homepageURL;' 'homepageURL.setAttribute("href", addon.homepageURL);' $file
|
|
replace_line '<a target="_blank" dir="ltr"><\/a>' \
|
|
'<label target="_blank" class="text-link" dir="ltr"><\/label>' \
|
|
chrome/toolkit/content/mozapps/extensions/aboutaddons.html
|
|
|
|
# Hide Recommendations tab in sidebar and recommendations in main pane
|
|
replace_line 'function isDiscoverEnabled\(\) \{' 'function isDiscoverEnabled() {return false;' chrome/toolkit/content/mozapps/extensions/aboutaddonsCommon.js
|
|
replace_line 'pref\("extensions.htmlaboutaddons.recommendations.enabled".+' 'pref("extensions.htmlaboutaddons.recommendations.enabled", false);' greprefs.js
|
|
|
|
# Hide Report option
|
|
replace_line 'pref\("extensions.abuseReport.enabled".+' 'pref("extensions.abuseReport.enabled", false);' greprefs.js
|
|
|
|
# The first displayed Services.prompt dialog's size jumps around because sizeToContent() is called twice
|
|
# Fix by preventing the first sizeToContent() call if the icon hasn't been loaded yet
|
|
replace_line 'window.sizeToContent\(\);' 'if (ui.infoIcon.complete) window.sizeToContent();' chrome/toolkit/content/global/commonDialog.js
|
|
replace_line 'ui.infoIcon.addEventListener' 'if (!ui.infoIcon.complete) ui.infoIcon.addEventListener' chrome/toolkit/content/global/commonDialog.js
|
|
|
|
# Import style into built-in dialogs
|
|
replace_line 'id=\"commonDialogWindow\"' \
|
|
'id=\"commonDialogWindow\" class=\"zotero-dialog\"' \
|
|
chrome/toolkit/content/global/commonDialog.xhtml
|
|
replace_line '<\?xml-stylesheet href=\"chrome:\/\/global\/skin\/commonDialog.css\" type=\"text\/css\"\?>' \
|
|
'<\?xml-stylesheet href=\"chrome:\/\/global\/skin\/commonDialog.css\" type=\"text\/css\"\?>
|
|
<\?xml-stylesheet href=\"chrome:\/\/zotero-platform\/content\/zotero.css\" type=\"text\/css\"\?>' \
|
|
chrome/toolkit/content/global/commonDialog.xhtml
|
|
# commonDialog.xhtml can be opened via Services.prompt in the Profile Manager, so check for a profile first
|
|
replace_line '<script>' \
|
|
'<script>
|
|
try {
|
|
Services.dirsvc.get(\"ProfD\", Ci.nsIFile);
|
|
Services.scriptloader.loadSubScript(\"chrome:\/\/zotero\/content\/include.js\", this);
|
|
Services.scriptloader.loadSubScript(\"chrome:\/\/zotero\/content\/customElements.js\", this);
|
|
} catch (e) {}' \
|
|
chrome/toolkit/content/global/commonDialog.xhtml
|
|
|
|
# Use native checkbox instead of Firefox-themed version in prompt dialogs
|
|
replace_line '<xul:checkbox' '<xul:checkbox native=\"true\"' chrome/toolkit/content/global/commonDialog.xhtml
|
|
|
|
# The <browser> CE appends its autoscroll <popup> to document.documentElement, which doesn't work in zoteroPane.xhtml
|
|
# (in Firefox browser.xhtml, document.documentElement is <html>, which can contain <popup>s; in zoteroPane.xhtml, it's
|
|
# <window>, which can't)
|
|
# Fix by appending it to a <popupset> instead
|
|
replace_line 'document.documentElement.appendChild\(this._autoScrollPopup\);' 'let popupset = document.querySelector("popupset");
|
|
if (!popupset) {
|
|
popupset = document.createXULElement("popupset");
|
|
document.documentElement.appendChild(popupset);
|
|
}
|
|
popupset.appendChild(this._autoScrollPopup);' chrome/toolkit/content/global/elements/browser-custom-element.js
|
|
|
|
zip -qr9XD omni.ja *
|
|
mv omni.ja ..
|
|
cd ..
|
|
python3 "$APP_ROOT_DIR/scripts/optimizejars.py" --optimize ./ ./ ./
|
|
rm -rf omni
|
|
|
|
# Unzip browser/omni.ja and leave unzipped
|
|
cd browser
|
|
mkdir omni
|
|
mv omni.ja omni
|
|
cd omni
|
|
ls -la
|
|
set +e
|
|
unzip omni.ja
|
|
set -e
|
|
rm omni.ja
|
|
|
|
# Remove Firefox update URLs
|
|
remove_line 'pref\("app.update.url.(manual|details)' defaults/preferences/firefox-branding.js
|
|
|
|
# Remove Firefox overrides (e.g., to use Firefox-specific strings for connection errors)
|
|
remove_line '(override)' chrome/chrome.manifest
|
|
|
|
# Remove WebExtension APIs
|
|
remove_line ext-browser.json components/components.manifest
|
|
|
|
# Don't open a second window if app is already open when launching .exe (Windows) or running via
|
|
# command line (macOS)
|
|
replace_line 'function dch_handle\(cmdLine\) \{' 'function dch_handle(cmdLine) {
|
|
if (cmdLine.state == Ci.nsICommandLine.STATE_REMOTE_AUTO) { return; }
|
|
' modules/BrowserContentHandler.sys.mjs
|
|
}
|
|
|
|
mkdir -p xulrunner
|
|
cd xulrunner
|
|
|
|
if [ $BUILD_MAC == 1 ]; then
|
|
GECKO_VERSION="$GECKO_VERSION_MAC"
|
|
DOWNLOAD_URL="https://ftp.mozilla.org/pub/firefox/releases/$GECKO_VERSION"
|
|
rm -rf Firefox.app
|
|
|
|
if [ -e "Firefox $GECKO_VERSION.app.zip" ]; then
|
|
echo "Using Firefox $GECKO_VERSION.app.zip"
|
|
unzip "Firefox $GECKO_VERSION.app.zip"
|
|
else
|
|
curl -o Firefox.dmg "$DOWNLOAD_URL/mac/en-US/Firefox%20$GECKO_VERSION.dmg"
|
|
set +e
|
|
hdiutil detach -quiet /Volumes/Firefox 2>/dev/null
|
|
set -e
|
|
hdiutil attach -quiet Firefox.dmg
|
|
cp -a /Volumes/Firefox/Firefox.app .
|
|
hdiutil detach -quiet /Volumes/Firefox
|
|
fi
|
|
|
|
# Download custom components
|
|
#echo
|
|
#rm -rf MacOS
|
|
#if [ -e "Firefox $GECKO_VERSION MacOS.zip" ]; then
|
|
# echo "Using Firefox $GECKO_VERSION MacOS.zip"
|
|
# unzip "Firefox $GECKO_VERSION MacOS.zip"
|
|
#else
|
|
# echo "Downloading Firefox $GECKO_VERSION MacOS.zip"
|
|
# curl -o MacOS.zip "${custom_components_url}Firefox%20$GECKO_VERSION%20MacOS.zip"
|
|
# unzip MacOS.zip
|
|
#fi
|
|
#echo
|
|
|
|
pushd Firefox.app/Contents/Resources
|
|
modify_omni mac
|
|
popd
|
|
|
|
# Replace "FirefoxCP" with "ZoteroCP" for subprocesses ("Isolated Web Content", "Socket Process", "Web Content", etc.)
|
|
info_plist=Firefox.app/Contents/MacOS/plugin-container.app/Contents/Resources/English.lproj/InfoPlist.strings
|
|
from=$(get_utf16_chars "FirefoxCP")
|
|
to=$(get_utf16_chars "ZoteroCP")
|
|
perl -pi -e "s/$from/$to/" $info_plist
|
|
# Check for UTF-16 "ZoteroCP"
|
|
if ! grep -a -q "Z.o.t.e.r.o.C.P." $info_plist; then
|
|
echo '"ZoteroCP" not found in InfoPlist.strings after replacement'
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -e "Firefox $GECKO_VERSION.app.zip" ]; then
|
|
rm "Firefox.dmg"
|
|
fi
|
|
|
|
#if [ ! -e "Firefox $GECKO_VERSION MacOS.zip" ]; then
|
|
# rm "MacOS.zip"
|
|
#fi
|
|
echo $("$SCRIPT_DIR/xulrunner_hash" -p m) > hash-mac
|
|
fi
|
|
|
|
if [ $BUILD_WIN == 1 ]; then
|
|
GECKO_VERSION="$GECKO_VERSION_WIN"
|
|
DOWNLOAD_URL="https://ftp.mozilla.org/pub/firefox/releases/$GECKO_VERSION"
|
|
|
|
for arch in win32 win-x64 win-aarch64; do
|
|
xdir=firefox-$arch
|
|
|
|
rm -rf $xdir
|
|
mkdir $xdir
|
|
|
|
if [ -e "Firefox Setup $GECKO_VERSION-$arch.exe" ]; then
|
|
echo "Using Firefox Setup $GECKO_VERSION-$arch.exe"
|
|
cp "Firefox Setup $GECKO_VERSION-$arch.exe" "Firefox%20Setup%20$GECKO_VERSION.exe"
|
|
else
|
|
if [ $arch = "win-x64" ]; then
|
|
curl -O "$DOWNLOAD_URL/win64/en-US/Firefox%20Setup%20$GECKO_VERSION.exe"
|
|
elif [ $arch = "win-aarch64" ]; then
|
|
curl -O "$DOWNLOAD_URL/win64-aarch64/en-US/Firefox%20Setup%20$GECKO_VERSION.exe"
|
|
else
|
|
curl -O "$DOWNLOAD_URL/$arch/en-US/Firefox%20Setup%20$GECKO_VERSION.exe"
|
|
fi
|
|
fi
|
|
|
|
7z x Firefox%20Setup%20$GECKO_VERSION.exe -o$xdir 'core/*'
|
|
mv $xdir/core $xdir-core
|
|
rm -rf $xdir
|
|
mv $xdir-core $xdir
|
|
|
|
pushd $xdir
|
|
|
|
# Replace "Mozilla-1de4eec8-1241-4177-a864-e594e8d1fb38" with "Zotero" for C:\ProgramData directory
|
|
#
|
|
# Mozilla uses a UUID in the path because they previously used just "Mozilla" and needed to
|
|
# recreate the folder with correct permissions for security reasons, but we never had a folder in
|
|
# ProgramData, so we can just create it as "Zotero". Instead of using a custom xul.dll, just
|
|
# replace the hard-coded string with "Zotero" and add a bunch of NULs.
|
|
from=$(get_utf16_chars "Mozilla-1de4eec8-1241-4177-a864-e594e8d1fb38")
|
|
to=$(get_utf16_chars "Zotero" 38)
|
|
perl -pe "s/$from/$to/" < xul.dll > xul.dll.new
|
|
mv xul.dll.new xul.dll
|
|
|
|
# Check for UTF-16 "Zotero" in DLL
|
|
#
|
|
# (The macOS strings command doesn't have an encoding option, so skip on macOS. We could
|
|
# require binutils, which has GNU strings, but you need to build on Windows to make an
|
|
# installer, so a Windows build from macOS likely isn't being deployed, and there's no
|
|
# reason the Perl command above should fail anyway.)
|
|
if [[ "`uname`" != "Darwin" ]] && [[ -z "$(strings -e l xul.dll | grep -m 1 Zotero)" ]]; then
|
|
echo '"Zotero" not found in xul.dll after replacement'
|
|
exit 1
|
|
fi
|
|
|
|
modify_omni $arch
|
|
# Disable skeleton UI window
|
|
# https://forums.zotero.org/discussion/comment/437636/#Comment_437636
|
|
replace_line 'pref\("browser\.startup\.preXulSkeletonUI", true\);' 'pref("browser.startup.preXulSkeletonUI", false);' defaults/preferences/firefox.js
|
|
popd
|
|
|
|
# Uncomment to create local copies for reuse
|
|
#cp "Firefox%20Setup%20$GECKO_VERSION.exe" "Firefox Setup $GECKO_VERSION-$arch.exe"
|
|
rm "Firefox%20Setup%20$GECKO_VERSION.exe"
|
|
echo
|
|
echo
|
|
done
|
|
echo $("$SCRIPT_DIR/xulrunner_hash" -p w) > hash-win
|
|
fi
|
|
|
|
if [ $BUILD_LINUX == 1 ]; then
|
|
GECKO_VERSION="$GECKO_VERSION_LINUX"
|
|
DOWNLOAD_URL="https://ftp.mozilla.org/pub/firefox/releases/$GECKO_VERSION"
|
|
|
|
|
|
# Include 32-bit build if not in CI
|
|
if [[ "${CI:-}" = "1" ]] || [[ "${SKIP_32:-}" = "1" ]]; then
|
|
arches="x86_64"
|
|
else
|
|
arches="i686 x86_64"
|
|
fi
|
|
for arch in $arches; do
|
|
xdir="firefox-$arch"
|
|
rm -rf $xdir
|
|
|
|
archived_file="firefox-$GECKO_VERSION-$arch.tar.bz2"
|
|
if [ -e "$archived_file" ]; then
|
|
echo "Using $archived_file"
|
|
cp "$archived_file" "firefox-$GECKO_VERSION.tar.bz2"
|
|
else
|
|
curl -O "$DOWNLOAD_URL/linux-$arch/en-US/firefox-$GECKO_VERSION.tar.bz2"
|
|
fi
|
|
|
|
tar xvf firefox-$GECKO_VERSION.tar.bz2
|
|
mv firefox firefox-$arch
|
|
|
|
pushd firefox-$arch
|
|
modify_omni $arch
|
|
popd
|
|
echo $($SCRIPT_DIR/xulrunner_hash -p l) > hash-linux
|
|
rm "firefox-$GECKO_VERSION.tar.bz2"
|
|
done
|
|
fi
|
|
|
|
echo Done
|