aboutsummaryrefslogtreecommitdiff
path: root/modules/firefox.home
diff options
context:
space:
mode:
Diffstat (limited to 'modules/firefox.home')
-rw-r--r--modules/firefox.home/autoconfig.js15
-rw-r--r--modules/firefox.home/chrome/customNewTab.uc.js13
-rw-r--r--modules/firefox.home/chrome/extensionsManager.uc.js73
-rw-r--r--modules/firefox.home/chrome/globalKeybindings.uc.js4
-rw-r--r--modules/firefox.home/chrome/loadingIndicator.uc.js109
-rw-r--r--modules/firefox.home/chrome/styles/variables.css10
-rw-r--r--modules/firefox.home/chrome/userChrome.css72
-rw-r--r--modules/firefox.home/chrome/utils/BootstrapLoader.js133
-rw-r--r--modules/firefox.home/chrome/utils/ChromeManifest.sys.mjs415
-rw-r--r--modules/firefox.home/chrome/utils/userChrome.js272
-rw-r--r--modules/firefox.home/chrome/utils/userChrome.jsm231
-rw-r--r--modules/firefox.home/chrome/utils/xPref.jsm85
-rw-r--r--modules/firefox.home/chrome/utils/xPref.sys.mjs92
-rw-r--r--modules/firefox.home/default.nix22
-rw-r--r--modules/firefox.home/policies.nix3
-rw-r--r--modules/firefox.home/preferences.nix2
-rw-r--r--modules/firefox.home/tridactyl/themes/phenax.css173
-rw-r--r--modules/firefox.home/tridactyl/tridactylrc36
18 files changed, 958 insertions, 802 deletions
diff --git a/modules/firefox.home/autoconfig.js b/modules/firefox.home/autoconfig.js
index a5744d2..bd9d747 100644
--- a/modules/firefox.home/autoconfig.js
+++ b/modules/firefox.home/autoconfig.js
@@ -1,11 +1,13 @@
// Autoconfig
+try {
pref('general.config.sandbox_enabled', false);
pref('general.config.obscure_value', 0);
pref('svg.context-properties.content.enabled', true);
lockPref('xpinstall.signatures.required', false);
lockPref('extensions.install_origins.enabled', false);
lockPref('extensions.experiments.enabled', true);
+} catch (ex) { console.error(ex); };
// Setup user chrome support
try {
@@ -13,20 +15,23 @@ try {
cmanifest.append('utils');
cmanifest.append('chrome.manifest');
Components.manager.QueryInterface(Ci.nsIComponentRegistrar).autoRegister(cmanifest);
-} catch (ex) { };
+} catch (ex) { console.error(ex); };
try {
Services.scriptloader.loadSubScript('chrome://userchromejs/content/BootstrapLoader.js');
-} catch (ex) { };
+} catch (ex) { console.error(ex); };
try {
- ChromeUtils.import('chrome://userchromejs/content/userChrome.jsm');
-} catch (ex) { };
+ Services.scriptloader.loadSubScript('chrome://userchromejs/content/userChrome.js');
+} catch (ex) {};
// Prefs
+try {
pref('devtools.theme', 'dark');
pref('devtools.toolbox.alwaysOnTop', true);
pref('devtools.toolbox.host', 'window');
+pref('devtools.chrome.enabled', true);
+pref('devtools.debugger.remote-enabled', true);
pref('privacy.donottrackheader.enabled', true);
pref('identity.fxaccounts.toolbar.enabled', false);
-
+} catch (ex) { console.error(ex); };
diff --git a/modules/firefox.home/chrome/customNewTab.uc.js b/modules/firefox.home/chrome/customNewTab.uc.js
index 4c8faca..7ea8ee2 100644
--- a/modules/firefox.home/chrome/customNewTab.uc.js
+++ b/modules/firefox.home/chrome/customNewTab.uc.js
@@ -2,20 +2,19 @@
// @name Custom New Tab
// @version 1.0
// @description Load a custom link or local file, instead of the default new tab page
+// @include main
// @startup UC.customNewTab.updateNewTabURL()
// @shutdown UC.customNewTab.destroy();
+// @onlyonce
// ==/UserScript==
+console.log('------------------------- newtab')
(() => {
// Managed in about:config
const NEWTAB_URL_PREF = 'browser.newtab.url'
- console.log('-------------------------------------------');
- console.log('-------------------------------------------');
- console.log('-------------------------------------------');
-
if (!AboutNewTab) {
- globalThis.AboutNewTab = ChromeUtils.import('resource:///modules/AboutNewTab.jsm').AboutNewTab;
+ globalThis.AboutNewTab = ChromeUtils.importESModule('resource:///modules/AboutNewTab.sys.mjs').AboutNewTab;
}
const module = {
@@ -28,10 +27,6 @@
},
init() {
- console.log('-------------------------------------------');
- console.log('init new tab');
- console.log('-------------------------------------------');
-
module.updateNewTabURL();
Services.obs.addObserver(module.updateNewTabURL, 'newtab-url-changed');
},
diff --git a/modules/firefox.home/chrome/extensionsManager.uc.js b/modules/firefox.home/chrome/extensionsManager.uc.js
deleted file mode 100644
index f5f3ed2..0000000
--- a/modules/firefox.home/chrome/extensionsManager.uc.js
+++ /dev/null
@@ -1,73 +0,0 @@
-// ==UserScript==
-// @name Custom New Tab
-// @version 1.0
-// @description Load a custom link or local file, instead of the default new tab page
-// @startup UC.extensionsManager.init(win)
-// @shutdown UC.extensionsManager.destroy();
-// ==/UserScript==
-
-(() => {
- const ENABLE = false;
-
- // Managed in about:config
- const EXTENSION_SETTINGS_PREF = 'extensions.uc.userExtensionSettings'
-
- const getSettings = () => {
- try {
- return JSON.parse(xPref.get(EXTENSION_SETTINGS_PREF) || 'null') ?? {};
- } catch (e) {
- return {};
- }
- }
-
- const saveSettings = (settings) =>
- xPref.set(EXTENSION_SETTINGS_PREF, JSON.stringify(settings));
-
- const updateExtensionSetting = (id, update) => {
- const settings = getSettings();
- settings.extensions[id] ??= {};
- settings.extensions[id] = update(settings.extensions[id] ?? {}) ?? {};
- saveSettings(settings);
- }
-
- const getCurrentTabHost = () => gBrowser.selectedTab.linkedBrowser.currentURI.host.trim() || null;
-
- const module = {
- disableForHost(id, host = getCurrentTabHost()) {
- updateExtensionSetting(id, s => {
- const urls = new Set(s.disabledHosts || []);
- urls.add(host);
- s.disabledHosts = [...urls];
- return s;
- });
- },
-
- async onTabChange() {
- const currentHost = getCurrentTabHost();
- if (!currentHost) return;
-
- const settings = getSettings();
- const addons = await AddonManager.getAllAddons();
- addons.forEach(addon => {
- const disabledHosts = settings?.extensions[addon.id].disabledHosts ?? [];
- const shouldDisable = disabledHosts.includes(currentHost)
-
- if (addon.isActive && shouldDisable)
- return addon.disable();
- if (!addon.isActive && !shouldDisable)
- return addon.enable();
- })
- },
-
- init(_win) {
- if (!ENABLE) return;
-
- Services.obs.addObserver(module.onTabChange, 'TabSelect');
- },
- destroy() {
- Services.obs.removeObserver(module.onTabChange, 'TabSelect');
- },
- };
-
- UC.extensionsManager = module;
-})();
diff --git a/modules/firefox.home/chrome/globalKeybindings.uc.js b/modules/firefox.home/chrome/globalKeybindings.uc.js
index d8c0f51..fe1d1f7 100644
--- a/modules/firefox.home/chrome/globalKeybindings.uc.js
+++ b/modules/firefox.home/chrome/globalKeybindings.uc.js
@@ -2,10 +2,14 @@
// @name Global Keybindings
// @version 1.0
// @description Setup global keybindings on all windows
+// @include main
// @startup UC.globalKeybindings.init(win);
// @shutdown UC.globalKeybindings.destroy();
+// @onlyonce
// ==/UserScript==
+console.log('------------------------- keybinds')
+
(() => {
// Configure global keybindings
const KEYBINDINGS = () => ({
diff --git a/modules/firefox.home/chrome/loadingIndicator.uc.js b/modules/firefox.home/chrome/loadingIndicator.uc.js
deleted file mode 100644
index 286376a..0000000
--- a/modules/firefox.home/chrome/loadingIndicator.uc.js
+++ /dev/null
@@ -1,109 +0,0 @@
-// ==UserScript==
-// @name Loading indicator
-// @version 1.0
-// @description Loading indicator for the url bar
-// @startup UC.loadingIndicator.init(win)
-// @shutdown UC.loadingIndicator.destroy()
-// ==/UserScript==
-
-(() => {
- const ENABLED = true;
-
- class TabProgressListener {
- static instances = [];
-
- static createListener(tab, onStateChange) {
- const oldListener = TabProgressListener.instances.find(l => l.tab === tab)
- if (oldListener) return oldListener;
- const listener = new TabProgressListener(tab, onStateChange);
- TabProgressListener.instances.push(listener);
- listener.attach();
- return listener;
- }
-
- static cleanup() {
- TabProgressListener.instances.forEach(l => l.cleanup())
- }
-
- loadedPercentage = 0;
- constructor(tab, onStateChange) {
- this.tab = tab;
- this._stateChange = onStateChange;
- }
-
- attach() {
- const browser = this.tab.linkedBrowser;
- browser.webProgress.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_ALL)
- }
-
- cleanup() {
- try {
- const index = TabProgressListener.instances.indexOf(this);
- if (index !== -1)
- TabProgressListener.instances.splice(index, 1);
- } finally {
- this.tab.linkedBrowser.webProgress.removeProgressListener(this);
- }
- }
-
- // Start query listener methods
-
- QueryInterface = ChromeUtils.generateQI(['nsIWebProgressListener', 'nsISupportsWeakReference'])
-
- onStateChange(_webProgress, _request, stateFlags, _status) {
- if (stateFlags & Ci.nsIWebProgressListener.STATE_START) {
- this._stateChange?.('loading');
- } else if (stateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
- this._stateChange?.('loaded');
- }
- }
- }
-
- const module = {
- onProgressStateUpdate: (win, state) => {
- /** @type {HTMLElement} */
- const urlBar = win.gURLBar.textbox;
- // console.log(state, urlBar);
- if (!urlBar) return;
-
- // urlBar.style.setProperty('--ff-urlbar-progress', perc);
- urlBar.dataset.pageProgress = state;
- },
-
- setupTab: (tab, win) => {
- const listener = TabProgressListener.createListener(tab, (state) => module.onProgressStateUpdate(win, state));
-
- tab.addEventListener('TabClose', () => listener.cleanup());
- },
-
- setupWindow: win => {
- win.gBrowser.tabs.forEach(tab => module.setupTab(tab, win));
- win.gBrowser.tabContainer.addEventListener('TabOpen', event => {
- module.setupTab(event.target, win);
- });
- win.gBrowser.tabContainer.addEventListener('TabSelect', _event => {
- const isLoading = gBrowser.selectedTab.linkedBrowser.webProgress.isLoadingDocument
- module.onProgressStateUpdate(win, isLoading ? 'loading' : 'loaded');
- });
- },
-
- init(win) {
- if (!ENABLED) return;
-
- const handle = () => {
- Services.obs.removeObserver(handle, 'browser-window-before-show');
- module.setupWindow(win);
- }
-
- if (win.__SSi) handle();
- else Services.obs.addObserver(handle, 'browser-window-before-show');
- },
-
- destroy() {
- TabProgressListener.cleanup();
- },
- };
-
- UC.loadingIndicator = module;
-})()
-
diff --git a/modules/firefox.home/chrome/styles/variables.css b/modules/firefox.home/chrome/styles/variables.css
index 82e1723..fa6a944 100644
--- a/modules/firefox.home/chrome/styles/variables.css
+++ b/modules/firefox.home/chrome/styles/variables.css
@@ -1,9 +1,9 @@
:root {
- --ff-accent-color: #4e3aA3;
- --ff-accent-color-1: #8161ff;
- --ff-bg-color: #0f0c19;
- --ff-bg-color-1: #16121f;
- --ff-bg-color-2: #26222f;
+ --ff-accent-color: #007070;
+ --ff-accent-color-1: #009090;
+ --ff-bg-color: #000000;
+ --ff-bg-color-1: #101414;
+ --ff-bg-color-2: #202222;
--ff-bg-private: hsl(247, 36%, 15%);
--ff-urlbar-height: 24px;
}
diff --git a/modules/firefox.home/chrome/userChrome.css b/modules/firefox.home/chrome/userChrome.css
index e845194..2746e21 100644
--- a/modules/firefox.home/chrome/userChrome.css
+++ b/modules/firefox.home/chrome/userChrome.css
@@ -26,16 +26,15 @@ toolbarbutton {
min-height: 0;
}
-/* Rounded browser content window */
+/* browser content window */
#browser {
background-color: var(--ff-bg-color);
}
#appcontent {
- margin: 4px;
+ margin: 0 !important;
margin-top: 0;
- border-radius: 6px;
- border: 1px solid rgba(255,255,255,0.06);
- overflow: hidden;
+ border-radius: 0 !important;
+ border: none !important;
}
@@ -103,7 +102,7 @@ toolbarbutton#alltabs-button {
#nav-bar {
border-top: none !important;
background-color: var(--toolbar-bgcolor) !important;
- padding: 3px 2px 0 !important;
+ padding: 0 2px 0 !important;
}
#TabsToolbar {
visibility: collapse !important;
@@ -137,20 +136,34 @@ toolbarbutton#alltabs-button {
color: var(--ff-accent-color-1) !important;
}
.urlbarView {
- background-color: var(--ff-bg-color-2) !important;
+ background-color: var(--ff-bg-color-1) !important;
+ margin-inline: 0 !important;
+ width: 100% !important;
+}
+.urlbarView-row {
+ border-radius: 0 !important;
}
.urlbar-input-container {
- background-color: var(--ff-bg-color-2) !important;
+ background-color: var(--ff-bg-color) !important;
+ border-radius: 0 !important;
border-color: transparent !important;
min-height: 0 !important;
padding-inline: 0 !important;
padding-block: 0 !important;
height: var(--ff-urlbar-height) !important;
}
-
+#urlbar {
+ top: 0 !important;
+}
+#urlbar[breakout-extend] {
+ top: 0 !important;
+}
+#urlbar:not([breakout-extend]), .urlbar-input-container {
+ height: 26px !important;
+}
#urlbar[breakout-extend] .urlbar-input-container {
- background-color: var(--ff-bg-color-2) !important;
+ background-color: var(--ff-bg-color-1) !important;
padding-inline: 0 !important;
}
#urlbar[breakout-extend] .urlbar-input-container #identity-box {
@@ -164,55 +177,32 @@ toolbarbutton#alltabs-button {
/* Sidebar + tab */
+#browser { background-color: red !important; }
#sidebar-main {
background: var(--ff-bg-color) !important;
}
#sidebar-box {
- background: var(--ff-bg-color) !important;
+ background: var(--ff-bg-color-1) !important;
margin: 3px 0 !important;
}
#sidebar {
- background: var(--ff-bg-color-2) !important;
+ background: var(--ff-bg-color) !important;
+ border-radius: 0 !important;
+ border: none !important;
+ outline: none !important;
}
#tabbrowser-tabbox {
- border-radius: 6px !important;
- overflow: hidden !important;
- margin: 4px !important;
+ border-radius: 0 !important;
+ margin: 0 !important;
}
-/* URL bar progress indicator */
-/* #urlbar[data-page-progress="loaded"]::before {
- display: none !important;
-} */
-
@keyframes ucLoadingSnimation {
0% { background-position: 130% 50%; }
100% { background-position: -70% 50%; }
}
-/* #urlbar[data-page-progress]::before {
- display: block;
- content: " ";
- pointer-events: none;
- width: 100%;
- height: 100%;
- position: absolute;
- bottom: 0;
- left: 0;
- z-index: 1;
- background: linear-gradient(
- 140deg,
- rgba(255, 255, 255, 0) 35%,
- rgba(255, 255, 255, .25) 50%,
- rgba(255, 255, 255, 0) 65%
- ) rgba(255, 255, 255, 0.05);
- background-size: 200% 200%;
- animation: ucLoadingSnimation 2.2s ease-in-out infinite;
- border-bottom: 2px solid var(--ff-accent-color);
-} */
-
/* Key mode indicator */
#navigator-toolbox[data-key-mode=""]::after {
diff --git a/modules/firefox.home/chrome/utils/BootstrapLoader.js b/modules/firefox.home/chrome/utils/BootstrapLoader.js
index eddc1de..69631ab 100644
--- a/modules/firefox.home/chrome/utils/BootstrapLoader.js
+++ b/modules/firefox.home/chrome/utils/BootstrapLoader.js
@@ -4,10 +4,13 @@
'use strict';
-ChromeUtils.defineESModuleGetters(this, {
+const Services = globalThis.Services;
+
+ChromeUtils.defineESModuleGetters(globalThis, {
Blocklist: 'resource://gre/modules/Blocklist.sys.mjs',
ConsoleAPI: 'resource://gre/modules/Console.sys.mjs',
InstallRDF: 'chrome://userchromejs/content/RDFManifestConverter.sys.mjs',
+ ChromeManifest: 'chrome://userchromejs/content/ChromeManifest.sys.mjs',
});
Services.obs.addObserver(doc => {
@@ -18,7 +21,7 @@ Services.obs.addObserver(doc => {
win.customElements.get('addon-card').prototype.handleEvent = function (e) {
if (e.type === 'click' &&
e.target.getAttribute('action') === 'preferences' &&
- this.addon.__AddonInternal__.optionsType == 1/*AddonManager.OPTIONS_TYPE_DIALOG*/) {
+ this.addon.__AddonInternal__.optionsType == 1/*AddonManager.OPTIONS_TYPE_DIALOG*/ && !!this.addon.optionsURL) {
var windows = Services.wm.getEnumerator(null);
while (windows.hasMoreElements()) {
var win2 = windows.getNext();
@@ -39,31 +42,40 @@ Services.obs.addObserver(doc => {
let update_orig = win.customElements.get('addon-options').prototype.update;
win.customElements.get('addon-options').prototype.update = function (card, addon) {
update_orig.apply(this, arguments);
- if (addon.__AddonInternal__.optionsType == 1/*AddonManager.OPTIONS_TYPE_DIALOG*/)
+ if (addon.__AddonInternal__?.optionsType == 1/*AddonManager.OPTIONS_TYPE_DIALOG*/ && !!addon.optionsURL)
this.querySelector('panel-item[data-l10n-id="preferences-addon-button"]').hidden = false;
}
}
}, 'chrome-document-loaded');
-const { AddonManager } = ChromeUtils.importESModule('resource://gre/modules/AddonManager.sys.mjs');
-const { XPIDatabase, AddonInternal } = ChromeUtils.importESModule('resource://gre/modules/addons/XPIDatabase.sys.mjs');
-const { XPIExports } = ChromeUtils.importESModule('resource://gre/modules/addons/XPIExports.sys.mjs');
+const {AddonManager} = ChromeUtils.importESModule('resource://gre/modules/AddonManager.sys.mjs');
+const {XPIDatabase, AddonInternal} = ChromeUtils.importESModule('resource://gre/modules/addons/XPIDatabase.sys.mjs');
+const {XPIExports} = ChromeUtils.importESModule('resource://gre/modules/addons/XPIExports.sys.mjs')
+
+XPIDatabase.isDisabledLegacy = () => false;
var orig_verifyBundleSignedState = XPIExports.verifyBundleSignedState;
XPIExports.verifyBundleSignedState = async (aBundle, aAddon) => {
- if(!aAddon.isWebExtension && aAddon.type === "extension") return { signedState: undefined, signedTypes: [] };
+ if(!aAddon.isWebExtension && aAddon.type === 'extension' || aAddon.id.includes('_N_SIGN_'))
+ return { signedState: undefined, signedTypes: [] };
return orig_verifyBundleSignedState(aBundle, aAddon);
}
-XPIDatabase.isDisabledLegacy = () => false;
-
ChromeUtils.defineLazyGetter(this, 'BOOTSTRAP_REASONS', () => {
- const { XPIProvider } = ChromeUtils.importESModule('resource://gre/modules/addons/XPIProvider.sys.mjs');
+ const {XPIProvider} = ChromeUtils.importESModule('resource://gre/modules/addons/XPIProvider.sys.mjs');
return XPIProvider.BOOTSTRAP_REASONS;
});
-const { Log } = ChromeUtils.importESModule('resource://gre/modules/Log.sys.mjs');
-var logger = Log.repository.getLogger('addons.bootstrap');
+ChromeUtils.defineLazyGetter(this, "logger", () => {
+ let { ConsoleAPI } = ChromeUtils.importESModule(
+ "resource://gre/modules/Console.sys.mjs"
+ );
+ let consoleOptions = {
+ maxLogLevel: "all",
+ prefix: "BootstrapLoader",
+ };
+ return new ConsoleAPI(consoleOptions);
+});
/**
* Valid IDs fit this pattern.
@@ -369,6 +381,81 @@ var BootstrapLoader = {
let startup = findMethod('startup');
let shutdown = findMethod('shutdown');
+ /**
+ * Reads content from a jar: URI
+ *
+ * @param {nsIURI} jarURI - The jar: URI to read from
+ * @returns {Promise<string>} The content of the file inside the JAR
+ */
+ async function readFromJarURI(jarURI) {
+ return new Promise((resolve, reject) => {
+ try {
+ const channel = Services.io.newChannelFromURI(
+ jarURI,
+ null,
+ Services.scriptSecurityManager.getSystemPrincipal(),
+ null,
+ Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL,
+ Ci.nsIContentPolicy.TYPE_OTHER
+ );
+
+ const inputStream = channel.open();
+ const scriptableStream = Cc[
+ '@mozilla.org/scriptableinputstream;1'
+ ].createInstance(Ci.nsIScriptableInputStream);
+ scriptableStream.init(inputStream);
+
+ let data = '';
+ let available = 0;
+ while ((available = scriptableStream.available()) > 0) {
+ data += scriptableStream.read(available);
+ }
+
+ scriptableStream.close();
+ inputStream.close();
+ resolve(data);
+ } catch (e) {
+ reject(e);
+ }
+ });
+ }
+
+ // Register a chrome manifest temporarily and return a function which un-does
+ // the registrarion when no longer needed.
+ function createManifestTemporarily(manifestText) {
+ let tempDir = Services.dirsvc.get('ProfD', Ci.nsIFile)
+ tempDir.append('browser-extension-data');
+ tempDir.append(addon.id);
+ tempDir.append('manifests');
+ if (tempDir.exists()) {
+ // Clean any leftover temp.manifest
+ tempDir.remove(true);
+ }
+ tempDir.append('temp.manifest.' + Date.now());
+
+ let foStream = Cc[
+ '@mozilla.org/network/file-output-stream;1'
+ ].createInstance(Ci.nsIFileOutputStream);
+ foStream.init(tempDir, 0x02 | 0x08 | 0x20, 0o664, 0); // write, create, truncate
+ foStream.write(manifestText, manifestText.length);
+ foStream.close();
+
+ Components.manager
+ .QueryInterface(Ci.nsIComponentRegistrar)
+ .autoRegister(tempDir);
+
+ Cc['@mozilla.org/uriloader/external-helper-app-service;1']
+ .getService(Ci.nsPIExternalAppLauncher)
+ .deleteTemporaryFileOnExit(tempDir);
+
+ return function () {
+ tempDir.fileSize = 0; // truncate the manifest
+ Cc['@mozilla.org/chrome/chrome-registry;1']
+ .getService(Ci.nsIXULChromeRegistry)
+ .checkForNewChrome();
+ };
+ }
+
return {
install(...args) {
install(...args);
@@ -382,10 +469,23 @@ var BootstrapLoader = {
Services.obs.notifyObservers(null, 'startupcache-invalidate');
},
- startup(...args) {
+ async startup(...args) {
if (addon.type == 'extension') {
logger.debug(`Registering manifest for ${file.path}\n`);
- Components.manager.addBootstrappedManifestLocation(file);
+ const manifestURI = getURIForResourceInFile(file, 'chrome.manifest');
+ let manifestData = await readFromJarURI(manifestURI);
+ let chromeManifest = new ChromeManifest(() => {
+ return manifestData;
+ }, {
+ application: Services.appinfo.ID,
+ appversion: Services.appinfo.version,
+ platformversion: Services.appinfo.platformVersion,
+ os: Services.appinfo.OS,
+ osversion: Services.sysinfo.getProperty('version'),
+ abi: Services.appinfo.XPCOMABI
+ });
+ await chromeManifest.parse()
+ this._clearManifest = createManifestTemporarily(chromeManifest.toString(getURIForResourceInFile(file, '').spec));
}
return startup(...args);
},
@@ -398,7 +498,8 @@ var BootstrapLoader = {
} finally {
if (reason != BOOTSTRAP_REASONS.APP_SHUTDOWN) {
logger.debug(`Removing manifest for ${file.path}\n`);
- Components.manager.removeBootstrappedManifestLocation(file);
+ this._clearManifest();
+ this._clearManifest = null;
}
}
},
@@ -416,4 +517,4 @@ if (AddonManager.isReady) {
};
});
});
-} \ No newline at end of file
+}
diff --git a/modules/firefox.home/chrome/utils/ChromeManifest.sys.mjs b/modules/firefox.home/chrome/utils/ChromeManifest.sys.mjs
new file mode 100644
index 0000000..f2ebc18
--- /dev/null
+++ b/modules/firefox.home/chrome/utils/ChromeManifest.sys.mjs
@@ -0,0 +1,415 @@
+/* exported ChromeManifest */
+"use strict";
+
+/**
+ * A default map, which assumes a default value on get() if the key doesn't exist
+ */
+class DefaultMap extends Map {
+ /**
+ * Constructs the default map
+ *
+ * @param {Function} _default A function that returns the default value for this map
+ * @param {*} iterable An iterable to initialize the map with
+ */
+ constructor(_default, iterable) {
+ super(iterable);
+ this._default = _default;
+ }
+
+ /**
+ * Get the given key, creating if necessary
+ *
+ * @param {String} key The key of the map to get
+ * @param {Boolean} create True, if the key should be created in case it doesn't exist.
+ */
+ get(key, create = true) {
+ if (this.has(key)) {
+ return super.get(key);
+ } else if (create) {
+ this.set(key, this._default());
+ return super.get(key);
+ }
+
+ return this._default();
+ }
+}
+
+/**
+ * A parser for chrome.manifest files. Implements a subset of
+ * https://developer.mozilla.org/en-US/docs/Mozilla/Chrome_Registration
+ */
+export class ChromeManifest {
+ /**
+ * Constucts the chrome.manifest parser
+ *
+ * @param {Function} loader An asynchronous function that will load further files, e.g.
+ * those included via the |manifest| instruction. The
+ * function will take the file as an argument and should
+ * resolve with the string contents of that file
+ * @param {Object} options Object describing the current system. The keys are manifest
+ * instructions
+ */
+ constructor(loader, options) {
+ this.loader = loader;
+ this.options = options;
+
+ this.overlay = new DefaultMap(() => []);
+ this.locales = new DefaultMap(() => new Map());
+ this.style = new DefaultMap(() => new Set());
+ this.category = new DefaultMap(() => new Map());
+
+ this.component = new Map();
+ this.contract = new Map();
+
+ this.content = new Map();
+ this.skin = new DefaultMap(() => new Map());
+ this.resource = new Map();
+ this.override = new Map();
+ }
+
+ /**
+ * Parse the given file.
+ *
+ * @param {String} filename The filename to load
+ * @param {String} base The relative directory this file is expected to be in.
+ * @return {Promise} Resolved when loading completes
+ */
+ async parse(filename = "chrome.manifest", base = "") {
+ await this.parseString(await this.loader(filename), base);
+ }
+
+ /**
+ * Parse the given string.
+ *
+ * @param {String} data The file data to load
+ * @param {String} base The relative directory this file is expected to be in.
+ * @return {Promise} Resolved when loading completes
+ */
+ async parseString(data, base = "") {
+ const lines = data.split("\n");
+ const extraManifests = [];
+ for (const line of lines) {
+ const parts = line.split(/\s+/);
+ const directive = parts.shift();
+ switch (directive) {
+ case "manifest":
+ extraManifests.push(this._parseManifest(base, ...parts));
+ break;
+ case "component": this._parseComponent(...parts);
+ break;
+ case "contract": this._parseContract(...parts);
+ break;
+ case "category": this._parseCategory(...parts);
+ break;
+ case "content": this._parseContent(...parts);
+ break;
+ case "locale": this._parseLocale(...parts);
+ break;
+ case "skin": this._parseSkin(...parts);
+ break;
+ case "resource": this._parseResource(...parts);
+ break;
+ case "overlay": this._parseOverlay(...parts);
+ break;
+ case "style": this._parseStyle(...parts);
+ break;
+ case "override": this._parseOverride(...parts);
+ break;
+ }
+ }
+
+ await Promise.all(extraManifests);
+ }
+
+ /**
+ * Ensure the flags provided for the instruction match our options
+ *
+ * @param {String[]} flags An array of raw flag values in the form key=value.
+ * @return {Boolean} True, if the flags match the options provided in the constructor
+ */
+ _parseFlags(flags) {
+ const matchString = (a, sign, b) => {
+ if (sign != "=") {
+ console.warn(`Invalid sign ${sign} in ${a}${sign}${b}, dropping manifest instruction`);
+ return false;
+ }
+ return a == b;
+ };
+
+ const matchVersion = (a, sign, b) => {
+ switch (sign) {
+ case "=": return Services.vc.compare(a, b) == 0;
+ case ">": return Services.vc.compare(a, b) > 0;
+ case "<": return Services.vc.compare(a, b) < 0;
+ case ">=": return Services.vc.compare(a, b) >= 0;
+ case "<=": return Services.vc.compare(a, b) <= 0;
+ default:
+ console.warn(`Invalid sign ${sign} in ${a}${sign}${b}, dropping manifest instruction`);
+ return false;
+ }
+ };
+
+ const flagdata = new DefaultMap(() => []);
+
+ const flagMatches = (key, typeMatch) => {
+ return !flagdata.has(key) || flagdata.get(key).some(val => typeMatch(this.options[key], ...val));
+ };
+
+ for (const flag of flags) {
+ const match = flag.match(/(\w+)(>=|<=|<|>|=)(.*)/);
+ if (match) {
+ flagdata.get(match[1]).push([match[2], match[3]]);
+ } else {
+ console.warn(`Invalid flag ${flag}, dropping manifest instruction`);
+ }
+ }
+
+ return flagMatches("application", matchString) &&
+ flagMatches("appversion", matchVersion) &&
+ flagMatches("platformversion", matchVersion) &&
+ flagMatches("os", matchString) &&
+ flagMatches("osversion", matchVersion) &&
+ flagMatches("abi", matchString);
+ }
+
+ /**
+ * Parse the manifest instruction, to load other files
+ *
+ * @param {String} base The base directory the manifest file is in
+ * @param {String} filename The file and path to load
+ * @param {...String} flags The flags for this instruction
+ * @return {Promise} Promise resolved when the manifest is loaded
+ */
+ async _parseManifest(base, filename, ...flags) {
+ if (this._parseFlags(flags)) {
+ const dirparts = filename.split("/");
+ dirparts.pop();
+
+ try {
+ await this.parse(filename, base + "/" + dirparts.join("/"));
+ } catch (e) {
+ console.log(`Could not read manifest '${base}/${filename}'.`);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Parse the component instruction, to load xpcom components
+ *
+ * @param {String} classid The xpcom class id to load
+ * @param {String} loction The file location of this component
+ * @param {...String} flags The flags for this instruction
+ */
+ _parseComponent(classid, location, ...flags) {
+ if (this._parseFlags(flags)) {
+ this.component.set(classid, location);
+ }
+ }
+
+ /**
+ * Parse the contract instruction, to load xpcom contract ids
+ *
+ * @param {String} contractid The xpcom contract id to load
+ * @param {String} location The file location of this component
+ * @param {...String} flags The flags for this instruction
+ */
+ _parseContract(contractid, location, ...flags) {
+ if (this._parseFlags(flags)) {
+ this.contract.set(contractid, location);
+ }
+ }
+
+ /**
+ * Parse the category instruction, to set up xpcom categories
+ *
+ * @param {String} category The name of the category
+ * @param {String} entryName The category entry name
+ * @param {String} value The category entry value
+ * @param {...String} flags The flags for this instruction
+ */
+ _parseCategory(category, entryName, value, ...flags) {
+ if (this._parseFlags(flags)) {
+ this.category.get(category).set(entryName, value);
+ }
+ }
+
+ /**
+ * Parse the content instruction, to set chrome content locations
+ *
+ * @param {String} shortname The content short name, e.g. chrome://shortname/content/
+ * @param {String} location The location for this content registration
+ * @param {...String} flags The flags for this instruction
+ */
+ _parseContent(shortname, location, ...flags) {
+ if (this._parseFlags(flags)) {
+ this.content.set(shortname, location);
+ }
+ }
+
+ /**
+ * Parse the locale instruction, to set chrome locale locations
+ *
+ * @param {String} shortname The locale short name, e.g. chrome://shortname/locale/
+ * @param {String} location The location for this locale registration
+ * @param {...String} flags The flags for this instruction
+ */
+ _parseLocale(shortname, locale, location, ...flags) {
+ if (this._parseFlags(flags)) {
+ this.locales.get(shortname).set(locale, location);
+ }
+ }
+
+ /**
+ * Parse the skin instruction, to set chrome skin locations
+ *
+ * @param {String} shortname The skin short name, e.g. chrome://shortname/skin/
+ * @param {String} location The location for this skin registration
+ * @param {...String} flags The flags for this instruction
+ */
+ _parseSkin(packagename, skinname, location, ...flags) {
+ if (this._parseFlags(flags)) {
+ this.skin.get(packagename).set(skinname, location);
+ }
+ }
+
+ /**
+ * Parse the resource instruction, to set up resource uri subtitutions
+ *
+ * @param {String} packagename The resource package name, e.g. resource://packagename/
+ * @param {String} url The location for this content registration
+ * @param {...String} flags The flags for this instruction
+ */
+ _parseResource(packagename, location, ...flags) {
+ if (this._parseFlags(flags)) {
+ this.resource.set(packagename, location);
+ }
+ }
+
+ /**
+ * Parse the overlay instruction, to set up xul overlays
+ *
+ * @param {String} targetUrl The chrome target url
+ * @param {String} overlayUrl The url of the xul overlay
+ * @param {...String} flags The flags for this instruction
+ */
+ _parseOverlay(targetUrl, overlayUrl, ...flags) {
+ if (this._parseFlags(flags)) {
+ this.overlay.get(targetUrl).push(overlayUrl);
+ }
+ }
+
+ /**
+ * Parse the style instruction, to add stylesheets into chrome windows
+ *
+ * @param {String} uri The uri of the chrome window
+ * @param {String} sheet The uri of the css sheet
+ * @param {...String} flags The flags for this instruction
+ */
+ _parseStyle(uri, sheet, ...flags) {
+ if (this._parseFlags(flags)) {
+ this.style.get(uri).add(sheet);
+ }
+ }
+
+ /**
+ * Parse the override instruction, to set chrome uri overrides
+ *
+ * @param {String} uri The uri being overridden
+ * @param {String} newuri The replacement uri for the original location
+ * @param {...String} flags The flags for this instruction
+ */
+ _parseOverride(uri, newuri, ...flags) {
+ if (this._parseFlags(flags)) {
+ this.override.set(uri, newuri);
+ }
+ }
+
+ /**
+ * Output the manifest data as a string in chrome.manifest format
+ * If root is provided, convert all relative locations to absolute paths.
+ *
+ * @param {String} [root] The absolute path root to resolve relative locations
+ * @return {String} The manifest contents as a string
+ */
+ toString(root = "") {
+ const lines = [];
+ const isRelative = loc => {
+ // Not absolute if doesn't start with /, \, or protocol (chrome://, resource://, etc)
+ return (
+ typeof loc === "string" &&
+ !loc.match(/^(?:[a-zA-Z]+:|\\|\/)/)
+ );
+ };
+ const absolutize = loc => {
+ if (!root) return loc;
+ if (loc === "/") return root;
+ if (isRelative(loc)) {
+ return root.replace(/[\\/]$/, "") + "/" + loc.replace(/^([\\\/])/, "");
+ }
+ return loc;
+ };
+
+ // Output components
+ for (const [classid, location] of this.component) {
+ lines.push(`component ${classid} ${absolutize(location)}`);
+ }
+
+ // Output contracts
+ for (const [contractid, location] of this.contract) {
+ lines.push(`contract ${contractid} ${absolutize(location)}`);
+ }
+
+ // Output categories
+ for (const [category, entries] of this.category) {
+ for (const [entryName, value] of entries) {
+ lines.push(`category ${category} ${entryName} ${value}`);
+ }
+ }
+
+ // Output content
+ for (const [shortname, location] of this.content) {
+ lines.push(`content ${shortname} ${absolutize(location)}`);
+ }
+
+ // Output locales
+ for (const [shortname, locales] of this.locales) {
+ for (const [locale, location] of locales) {
+ lines.push(`locale ${shortname} ${locale} ${absolutize(location)}`);
+ }
+ }
+
+ // Output skins
+ for (const [packagename, skins] of this.skin) {
+ for (const [skinname, location] of skins) {
+ lines.push(`skin ${packagename} ${skinname} ${absolutize(location)}`);
+ }
+ }
+
+ // Output resources
+ for (const [packagename, location] of this.resource) {
+ lines.push(`resource ${packagename} ${absolutize(location)}`);
+ }
+
+ // Output overlays
+ for (const [targetUrl, overlays] of this.overlay) {
+ for (const overlayUrl of overlays) {
+ lines.push(`overlay ${targetUrl} ${absolutize(overlayUrl)}`);
+ }
+ }
+
+ // Output styles
+ for (const [uri, sheets] of this.style) {
+ for (const sheet of sheets) {
+ lines.push(`style ${uri} ${absolutize(sheet)}`);
+ }
+ }
+
+ // Output overrides
+ for (const [uri, newuri] of this.override) {
+ lines.push(`override ${uri} ${newuri}`);
+ }
+
+ return lines.join("\n");
+ }
+}
diff --git a/modules/firefox.home/chrome/utils/userChrome.js b/modules/firefox.home/chrome/utils/userChrome.js
new file mode 100644
index 0000000..1870bee
--- /dev/null
+++ b/modules/firefox.home/chrome/utils/userChrome.js
@@ -0,0 +1,272 @@
+'use strict';
+
+(() => {
+ ChromeUtils.defineESModuleGetters(globalThis, {
+ xPref: 'chrome://userchromejs/content/xPref.sys.mjs',
+ Management: 'resource://gre/modules/Extension.sys.mjs',
+ AppConstants: 'resource://gre/modules/AppConstants.sys.mjs',
+ });
+
+ let UC = {
+ webExts: new Map(),
+ sidebar: new Map(),
+ sandboxes: new WeakMap()
+ };
+
+ let _uc = {
+ ALWAYSEXECUTE: 'rebuild_userChrome.uc.js',
+ BROWSERCHROME: AppConstants.MOZ_APP_NAME == 'thunderbird' ? 'chrome://messenger/content/messenger.xhtml' : 'chrome://browser/content/browser.xhtml',
+ BROWSERTYPE: AppConstants.MOZ_APP_NAME == 'thunderbird' ? 'mail:3pane' : 'navigator:browser',
+ BROWSERNAME: AppConstants.MOZ_APP_NAME.charAt(0).toUpperCase() + AppConstants.MOZ_APP_NAME.slice(1),
+ PREF_ENABLED: 'userChromeJS.enabled',
+ PREF_SCRIPTSDISABLED: 'userChromeJS.scriptsDisabled',
+
+ chromedir: Services.dirsvc.get('UChrm', Ci.nsIFile),
+ scriptsDir: '',
+
+ sss: Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService),
+
+ getScripts: function () {
+ this.scripts = {};
+ let files = this.chromedir.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
+ while (files.hasMoreElements()) {
+ let file = files.getNext().QueryInterface(Ci.nsIFile);
+ if (/\.uc\.js$/i.test(file.leafName)) {
+ _uc.getScriptData(file);
+ }
+ }
+ },
+
+ getScriptData: function (aFile) {
+ let aContent = this.readFile(aFile);
+ let header = (aContent.match(/^\/\/ ==UserScript==\s*\n(?:.*\n)*?\/\/ ==\/UserScript==\s*\n/m) || [''])[0];
+ let match, rex = {
+ include: [],
+ exclude: []
+ };
+ let findNextRe = /^\/\/ @(include|exclude)\s+(.+)\s*$/gm;
+ while ((match = findNextRe.exec(header))) {
+ rex[match[1]].push(match[2].replace(/^main$/i, _uc.BROWSERCHROME).replace(/\*/g, '.*?'));
+ }
+ if (!rex.include.length) {
+ rex.include.push(_uc.BROWSERCHROME);
+ }
+ let exclude = rex.exclude.length ? '(?!' + rex.exclude.join('$|') + '$)' : '';
+
+ let def = ['', ''];
+ let author = (header.match(/\/\/ @author\s+(.+)\s*$/im) || def)[1];
+ let filename = aFile.leafName || '';
+
+ return this.scripts[filename] = {
+ filename: filename,
+ file: aFile,
+ url: Services.io.getProtocolHandler('file').QueryInterface(Ci.nsIFileProtocolHandler).getURLSpecFromDir(this.chromedir) + filename,
+ name: (header.match(/\/\/ @name\s+(.+)\s*$/im) || def)[1],
+ description: (header.match(/\/\/ @description\s+(.+)\s*$/im) || def)[1],
+ version: (header.match(/\/\/ @version\s+(.+)\s*$/im) || def)[1],
+ author: (header.match(/\/\/ @author\s+(.+)\s*$/im) || def)[1],
+ regex: new RegExp('^' + exclude + '(' + (rex.include.join('|') || '.*') + ')$', 'i'),
+ id: (header.match(/\/\/ @id\s+(.+)\s*$/im) || ['', filename.split('.uc.js')[0] + '@' + (author || 'userChromeJS')])[1],
+ homepageURL: (header.match(/\/\/ @homepageURL\s+(.+)\s*$/im) || def)[1],
+ downloadURL: (header.match(/\/\/ @downloadURL\s+(.+)\s*$/im) || def)[1],
+ updateURL: (header.match(/\/\/ @updateURL\s+(.+)\s*$/im) || def)[1],
+ optionsURL: (header.match(/\/\/ @optionsURL\s+(.+)\s*$/im) || def)[1],
+ startup: (header.match(/\/\/ @startup\s+(.+)\s*$/im) || def)[1],
+ shutdown: (header.match(/\/\/ @shutdown\s+(.+)\s*$/im) || def)[1],
+ onlyonce: /\/\/ @onlyonce\b/.test(header),
+ isRunning: false,
+ get isEnabled() {
+ return (xPref.get(_uc.PREF_SCRIPTSDISABLED) || '').split(',').indexOf(this.filename) == -1;
+ }
+ }
+ },
+
+ readFile: function (aFile, metaOnly = false) {
+ let stream = Cc['@mozilla.org/network/file-input-stream;1'].createInstance(Ci.nsIFileInputStream);
+ stream.init(aFile, 0x01, 0, 0);
+ let cvstream = Cc['@mozilla.org/intl/converter-input-stream;1'].createInstance(Ci.nsIConverterInputStream);
+ cvstream.init(stream, 'UTF-8', 1024, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+ let content = '',
+ data = {};
+ while (cvstream.readString(4096, data)) {
+ content += data.value;
+ if (metaOnly && content.indexOf('// ==/UserScript==') > 0) {
+ break;
+ }
+ }
+ cvstream.close();
+ return content.replace(/\r\n?/g, '\n');
+ },
+
+ everLoaded: [],
+
+ loadScript: function (script, win) {
+ if (!script.regex.test(win.location.href) || (script.filename != this.ALWAYSEXECUTE && !script.isEnabled)) {
+ return;
+ }
+
+ if (script.onlyonce && script.isRunning) {
+ if (script.startup) {
+ Cu.evalInSandbox(`(function(script, win){${script.startup}})`, this.getSandbox(win))(script, win);
+ }
+ return;
+ }
+
+ try {
+ Services.scriptloader.loadSubScript(script.url + '?' + script.file.lastModifiedTime,
+ script.onlyonce ? { window: win } : win);
+ script.isRunning = true;
+ if (script.startup) {
+ Cu.evalInSandbox(`(function(script, win){${script.startup}})`, this.getSandbox(win))(script, win);
+ }
+ if (!script.shutdown) {
+ this.everLoaded.push(script.id);
+ }
+ } catch (ex) {
+ Cu.reportError(ex);
+ }
+ },
+
+ getSandbox: function (doc) {
+ if (!UC.sandboxes) UC.sandboxes = new WeakMap();
+ let global = Cu.getGlobalForObject(doc);
+ if (UC.sandboxes.has(global))
+ return UC.sandboxes.get(global);
+ let sb = Cu.Sandbox(Services.scriptSecurityManager.getSystemPrincipal(), {
+ sandboxPrototype: global,
+ sameZoneAs: global,
+ wantXrays: false,
+ sandboxName: 'UCJS:Sandbox'
+ });
+ UC.sandboxes.set(global, sb);
+ global.addEventListener('unload', () => {
+ UC.sandboxes.delete(global);
+ Cu.nukeSandbox(sb);
+ });
+ return sb;
+ },
+
+ windows: function (fun, onlyBrowsers = true) {
+ let windows = Services.wm.getEnumerator(onlyBrowsers ? this.BROWSERTYPE : null);
+ while (windows.hasMoreElements()) {
+ let win = windows.getNext();
+ if (!win._uc)
+ continue;
+ if (!onlyBrowsers) {
+ let frames = win.docShell.getAllDocShellsInSubtree(Ci.nsIDocShellTreeItem.typeAll, Ci.nsIDocShell.ENUMERATE_FORWARDS);
+ let res = frames.some(frame => {
+ let fWin = frame.domWindow;
+ let {document, location} = fWin;
+ if (fun(document, fWin, location))
+ return true;
+ });
+ if (res)
+ break;
+ } else {
+ let {document, location} = win;
+ if (fun(document, win, location))
+ break;
+ }
+ }
+ },
+
+ createElement: function (doc, tag, atts, XUL = true) {
+ let el = XUL ? doc.createXULElement(tag) : doc.createElement(tag);
+ for (let att in atts) {
+ if (att.startsWith('on'))
+ el.addEventListener(att.slice(2), typeof atts[att] == "string" ?
+ Cu.evalInSandbox(`(function(event){${atts[att]}})`, this.getSandbox(doc)) : atts[att]);
+ else
+ el.setAttribute(att, atts[att]);
+ }
+ return el
+ }
+ };
+
+ if (xPref.get(_uc.PREF_ENABLED) === undefined) {
+ xPref.set(_uc.PREF_ENABLED, true, true);
+ }
+
+ if (xPref.get(_uc.PREF_SCRIPTSDISABLED) === undefined) {
+ xPref.set(_uc.PREF_SCRIPTSDISABLED, '', true);
+ }
+
+ let UserChrome_js = {
+ observe: function (aSubject) {
+ if (
+ AppConstants.MOZ_APP_NAME == "thunderbird" &&
+ aSubject?.location?.href.startsWith("chrome://messenger/content")
+ ) {
+ aSubject.addEventListener("DOMContentLoaded", () => {
+ this.load(aSubject);
+ }, {once: true})
+ } else {
+ aSubject.addEventListener('DOMContentLoaded', this, {once: true});
+ }
+ },
+
+ handleEvent: function (aEvent) {
+ let document = aEvent.originalTarget;
+ let window = document.defaultView;
+ if (window.document.isInitialDocument) {
+ this.load(window.parent);
+ } else {
+ this.load(window);
+ }
+ },
+
+ load: function (window) {
+ let location = window.location;
+
+ if (!this.sharedWindowOpened && location.href == 'chrome://extensions/content/dummy.xhtml') {
+ this.sharedWindowOpened = true;
+
+ Management.on('extension-browser-inserted', function (topic, browser) {
+ browser.messageManager.addMessageListener('Extension:BackgroundViewLoaded', this.messageListener.bind(this));
+ }.bind(this));
+ } else if (/^(chrome:(?!\/\/global\/content\/commonDialog\.x?html)|about:(?!blank))/i.test(location.href)) {
+ window.UC = UC;
+ window._uc = _uc;
+ window.xPref = xPref;
+ if (window._gBrowser) // bug 1443849
+ window.gBrowser = window._gBrowser;
+
+ if (xPref.get(_uc.PREF_ENABLED)) {
+ Object.values(_uc.scripts).forEach(script => {
+ _uc.loadScript(script, window);
+ });
+ } else if (!UC.rebuild) {
+ _uc.loadScript(_uc.scripts[_uc.ALWAYSEXECUTE], window);
+ }
+ }
+ },
+
+ messageListener: function (msg) {
+ const browser = msg.target;
+ const { addonId } = browser._contentPrincipal;
+
+ browser.messageManager.removeMessageListener('Extension:BackgroundViewLoaded', this.messageListener);
+
+ if (browser.ownerGlobal.location.href == 'chrome://extensions/content/dummy.xhtml') {
+ UC.webExts.set(addonId, browser);
+ Services.obs.notifyObservers(null, 'UCJS:WebExtLoaded', addonId);
+ } else {
+ let win = browser.ownerGlobal.windowRoot.ownerGlobal;
+ UC.sidebar.get(addonId)?.set(win, browser) || UC.sidebar.set(addonId, new Map([[win, browser]]));
+ Services.obs.notifyObservers(win, 'UCJS:SidebarLoaded', addonId);
+ }
+ }
+ };
+
+ if (!Services.appinfo.inSafeMode) {
+ _uc.chromedir.append(_uc.scriptsDir);
+ _uc.getScripts();
+ let windows = Services.wm.getEnumerator(null);
+ while (windows.hasMoreElements()) {
+ let win = windows.getNext();
+ if (!('UC' in win))
+ UserChrome_js.load(win)
+ }
+ Services.obs.addObserver(UserChrome_js, 'chrome-document-global-created', false);
+ }
+})();
diff --git a/modules/firefox.home/chrome/utils/userChrome.jsm b/modules/firefox.home/chrome/utils/userChrome.jsm
deleted file mode 100644
index 17a9224..0000000
--- a/modules/firefox.home/chrome/utils/userChrome.jsm
+++ /dev/null
@@ -1,231 +0,0 @@
-let EXPORTED_SYMBOLS = [];
-
-const { xPref } = ChromeUtils.import('chrome://userchromejs/content/xPref.jsm');
-const { Management } = ChromeUtils.import('resource://gre/modules/Extension.jsm');
-const { AppConstants } = ChromeUtils.import('resource://gre/modules/AppConstants.jsm');
-
-let UC = {
- webExts: new Map(),
- sidebar: new Map()
-};
-
-let _uc = {
- ALWAYSEXECUTE: 'rebuild_userChrome.uc.js',
- BROWSERCHROME: AppConstants.MOZ_APP_NAME == 'thunderbird' ? 'chrome://messenger/content/messenger.xhtml' : 'chrome://browser/content/browser.xhtml',
- BROWSERTYPE: AppConstants.MOZ_APP_NAME == 'thunderbird' ? 'mail:3pane' : 'navigator:browser',
- BROWSERNAME: AppConstants.MOZ_APP_NAME.charAt(0).toUpperCase() + AppConstants.MOZ_APP_NAME.slice(1),
- PREF_ENABLED: 'userChromeJS.enabled',
- PREF_SCRIPTSDISABLED: 'userChromeJS.scriptsDisabled',
-
- chromedir: Services.dirsvc.get('UChrm', Ci.nsIFile),
- scriptsDir: '',
-
- sss: Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService),
-
- getScripts: function () {
- this.scripts = {};
- let files = this.chromedir.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
- while (files.hasMoreElements()) {
- let file = files.getNext().QueryInterface(Ci.nsIFile);
- if (/\.uc\.js$/i.test(file.leafName)) {
- _uc.getScriptData(file);
- }
- }
- },
-
- getScriptData: function (aFile) {
- let aContent = this.readFile(aFile);
- let header = (aContent.match(/^\/\/ ==UserScript==\s*\n(?:.*\n)*?\/\/ ==\/UserScript==\s*\n/m) || [''])[0];
- let match, rex = {
- include: [],
- exclude: []
- };
- let findNextRe = /^\/\/ @(include|exclude)\s+(.+)\s*$/gm;
- while ((match = findNextRe.exec(header))) {
- rex[match[1]].push(match[2].replace(/^main$/i, _uc.BROWSERCHROME).replace(/\*/g, '.*?'));
- }
- if (!rex.include.length) {
- rex.include.push(_uc.BROWSERCHROME);
- }
- let exclude = rex.exclude.length ? '(?!' + rex.exclude.join('$|') + '$)' : '';
-
- let def = ['', ''];
- let author = (header.match(/\/\/ @author\s+(.+)\s*$/im) || def)[1];
- let filename = aFile.leafName || '';
-
- return this.scripts[filename] = {
- filename: filename,
- file: aFile,
- url: Services.io.getProtocolHandler('file').QueryInterface(Ci.nsIFileProtocolHandler).getURLSpecFromDir(this.chromedir) + filename,
- name: (header.match(/\/\/ @name\s+(.+)\s*$/im) || def)[1],
- description: (header.match(/\/\/ @description\s+(.+)\s*$/im) || def)[1],
- version: (header.match(/\/\/ @version\s+(.+)\s*$/im) || def)[1],
- author: (header.match(/\/\/ @author\s+(.+)\s*$/im) || def)[1],
- regex: new RegExp('^' + exclude + '(' + (rex.include.join('|') || '.*') + ')$', 'i'),
- id: (header.match(/\/\/ @id\s+(.+)\s*$/im) || ['', filename.split('.uc.js')[0] + '@' + (author || 'userChromeJS')])[1],
- homepageURL: (header.match(/\/\/ @homepageURL\s+(.+)\s*$/im) || def)[1],
- downloadURL: (header.match(/\/\/ @downloadURL\s+(.+)\s*$/im) || def)[1],
- updateURL: (header.match(/\/\/ @updateURL\s+(.+)\s*$/im) || def)[1],
- optionsURL: (header.match(/\/\/ @optionsURL\s+(.+)\s*$/im) || def)[1],
- startup: (header.match(/\/\/ @startup\s+(.+)\s*$/im) || def)[1],
- shutdown: (header.match(/\/\/ @shutdown\s+(.+)\s*$/im) || def)[1],
- onlyonce: /\/\/ @onlyonce\b/.test(header),
- isRunning: false,
- get isEnabled() {
- return (xPref.get(_uc.PREF_SCRIPTSDISABLED) || '').split(',').indexOf(this.filename) == -1;
- }
- }
- },
-
- readFile: function (aFile, metaOnly = false) {
- let stream = Cc['@mozilla.org/network/file-input-stream;1'].createInstance(Ci.nsIFileInputStream);
- stream.init(aFile, 0x01, 0, 0);
- let cvstream = Cc['@mozilla.org/intl/converter-input-stream;1'].createInstance(Ci.nsIConverterInputStream);
- cvstream.init(stream, 'UTF-8', 1024, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
- let content = '',
- data = {};
- while (cvstream.readString(4096, data)) {
- content += data.value;
- if (metaOnly && content.indexOf('// ==/UserScript==') > 0) {
- break;
- }
- }
- cvstream.close();
- return content.replace(/\r\n?/g, '\n');
- },
-
- everLoaded: [],
-
- loadScript: function (script, win) {
- if (!script.regex.test(win.location.href) || (script.filename != this.ALWAYSEXECUTE && !script.isEnabled)) {
- return;
- }
-
- if (script.onlyonce && script.isRunning) {
- if (script.startup) {
- eval(script.startup);
- }
- return;
- }
-
- try {
- Services.scriptloader.loadSubScript(script.url + '?' + script.file.lastModifiedTime,
- script.onlyonce ? { window: win } : win);
- script.isRunning = true;
- if (script.startup) {
- eval(script.startup);
- }
- if (!script.shutdown) {
- this.everLoaded.push(script.id);
- }
- } catch (ex) {
- Cu.reportError(ex);
- }
- },
-
- windows: function (fun, onlyBrowsers = true) {
- let windows = Services.wm.getEnumerator(onlyBrowsers ? this.BROWSERTYPE : null);
- while (windows.hasMoreElements()) {
- let win = windows.getNext();
- if (!win._uc)
- continue;
- if (!onlyBrowsers) {
- let frames = win.docShell.getAllDocShellsInSubtree(Ci.nsIDocShellTreeItem.typeAll, Ci.nsIDocShell.ENUMERATE_FORWARDS);
- let res = frames.some(frame => {
- let fWin = frame.domWindow;
- let {document, location} = fWin;
- if (fun(document, fWin, location))
- return true;
- });
- if (res)
- break;
- } else {
- let {document, location} = win;
- if (fun(document, win, location))
- break;
- }
- }
- },
-
- createElement: function (doc, tag, atts, XUL = true) {
- let el = XUL ? doc.createXULElement(tag) : doc.createElement(tag);
- for (let att in atts) {
- el.setAttribute(att, atts[att]);
- }
- return el
- }
-};
-
-if (xPref.get(_uc.PREF_ENABLED) === undefined) {
- xPref.set(_uc.PREF_ENABLED, true, true);
-}
-
-if (xPref.get(_uc.PREF_SCRIPTSDISABLED) === undefined) {
- xPref.set(_uc.PREF_SCRIPTSDISABLED, '', true);
-}
-
-let UserChrome_js = {
- observe: function (aSubject) {
- aSubject.addEventListener('DOMContentLoaded', this, {once: true});
- },
-
- handleEvent: function (aEvent) {
- let document = aEvent.originalTarget;
- let window = document.defaultView;
- this.load(window);
- },
-
- load: function (window) {
- let location = window.location;
-
- if (!this.sharedWindowOpened && location.href == 'chrome://extensions/content/dummy.xhtml') {
- this.sharedWindowOpened = true;
-
- Management.on('extension-browser-inserted', function (topic, browser) {
- browser.messageManager.addMessageListener('Extension:BackgroundViewLoaded', this.messageListener.bind(this));
- }.bind(this));
- } else if (/^(chrome:(?!\/\/global\/content\/commonDialog\.x?html)|about:(?!blank))/i.test(location.href)) {
- window.UC = UC;
- window._uc = _uc;
- window.xPref = xPref;
- if (window._gBrowser) // bug 1443849
- window.gBrowser = window._gBrowser;
-
- if (xPref.get(_uc.PREF_ENABLED)) {
- Object.values(_uc.scripts).forEach(script => {
- _uc.loadScript(script, window);
- });
- } else if (!UC.rebuild) {
- _uc.loadScript(_uc.scripts[_uc.ALWAYSEXECUTE], window);
- }
- }
- },
-
- messageListener: function (msg) {
- const browser = msg.target;
- const { addonId } = browser._contentPrincipal;
-
- browser.messageManager.removeMessageListener('Extension:BackgroundViewLoaded', this.messageListener);
-
- if (browser.ownerGlobal.location.href == 'chrome://extensions/content/dummy.xhtml') {
- UC.webExts.set(addonId, browser);
- Services.obs.notifyObservers(null, 'UCJS:WebExtLoaded', addonId);
- } else {
- let win = browser.ownerGlobal.windowRoot.ownerGlobal;
- UC.sidebar.get(addonId)?.set(win, browser) || UC.sidebar.set(addonId, new Map([[win, browser]]));
- Services.obs.notifyObservers(win, 'UCJS:SidebarLoaded', addonId);
- }
- }
-};
-
-if (!Services.appinfo.inSafeMode) {
- _uc.chromedir.append(_uc.scriptsDir);
- _uc.getScripts();
- let windows = Services.wm.getEnumerator(null);
- while (windows.hasMoreElements()) {
- let win = windows.getNext();
- if (!('UC' in win))
- UserChrome_js.load(win)
- }
- Services.obs.addObserver(UserChrome_js, 'chrome-document-global-created', false);
-}
diff --git a/modules/firefox.home/chrome/utils/xPref.jsm b/modules/firefox.home/chrome/utils/xPref.jsm
deleted file mode 100644
index dcb44b3..0000000
--- a/modules/firefox.home/chrome/utils/xPref.jsm
+++ /dev/null
@@ -1,85 +0,0 @@
-let EXPORTED_SYMBOLS = ['xPref'];
-
-var xPref = {
- get: function(prefPath, def = false, valueIfUndefined, setDefault = true) {
- let sPrefs = def ?
- Services.prefs.getDefaultBranch(null) :
- Services.prefs;
-
- try {
- switch (sPrefs.getPrefType(prefPath)) {
- case 0:
- if (valueIfUndefined != undefined)
- return this.set(prefPath, valueIfUndefined, setDefault);
- else
- return undefined;
- case 32:
- return sPrefs.getStringPref(prefPath);
- case 64:
- return sPrefs.getIntPref(prefPath);
- case 128:
- return sPrefs.getBoolPref(prefPath);
- }
- } catch (ex) {
- return undefined;
- }
- return;
- },
-
- set: function(prefPath, value, def = false) {
- let sPrefs = def ?
- Services.prefs.getDefaultBranch(null) :
- Services.prefs;
-
- try {
- switch (typeof value) {
- case 'string':
- return sPrefs.setStringPref(prefPath, value) || value;
- case 'number':
- return sPrefs.setIntPref(prefPath, value) || value;
- case 'boolean':
- return sPrefs.setBoolPref(prefPath, value) || value;
- }
- } catch (e) { console.error(e) }
- return;
- },
-
- lock: function(prefPath, value) {
- let sPrefs = Services.prefs;
- this.lockedBackupDef[prefPath] = this.get(prefPath, true);
- if (sPrefs.prefIsLocked(prefPath))
- sPrefs.unlockPref(prefPath);
-
- this.set(prefPath, value, true);
- sPrefs.lockPref(prefPath);
- },
-
- lockedBackupDef: {},
-
- unlock: function(prefPath) {
- Services.prefs.unlockPref(prefPath);
- let bkp = this.lockedBackupDef[prefPath];
- if (bkp == undefined)
- Services.prefs.deleteBranch(prefPath);
- else
- this.set(prefPath, bkp, true);
- },
-
- clear: Services.prefs.clearUserPref,
-
- addListener: function(prefPath, trat) {
- this.observer = function(aSubject, aTopic, prefPath) {
- return trat(xPref.get(prefPath), prefPath);
- }
-
- Services.prefs.addObserver(prefPath, this.observer);
- return {
- prefPath,
- observer: this.observer
- };
- },
-
- removeListener: function(obs) {
- Services.prefs.removeObserver(obs.prefPath, obs.observer);
- }
-}
diff --git a/modules/firefox.home/chrome/utils/xPref.sys.mjs b/modules/firefox.home/chrome/utils/xPref.sys.mjs
new file mode 100644
index 0000000..aba56db
--- /dev/null
+++ b/modules/firefox.home/chrome/utils/xPref.sys.mjs
@@ -0,0 +1,92 @@
+'use strict';
+
+export const xPref = {
+ // Retorna o valor da preferência, seja qual for o tipo, mas não
+ // testei com tipos complexos como nsIFile, não sei como detectar
+ // uma preferência assim, na verdade nunca vi uma
+ get: function (prefPath, def = false, valueIfUndefined, setDefault = true) {
+ let sPrefs = def ?
+ Services.prefs.getDefaultBranch(null) :
+ Services.prefs;
+
+ try {
+ switch (sPrefs.getPrefType(prefPath)) {
+ case 0:
+ if (valueIfUndefined != undefined)
+ return this.set(prefPath, valueIfUndefined, setDefault);
+ else
+ return undefined;
+ case 32:
+ return sPrefs.getStringPref(prefPath);
+ case 64:
+ return sPrefs.getIntPref(prefPath);
+ case 128:
+ return sPrefs.getBoolPref(prefPath);
+ }
+ } catch (ex) {
+ return undefined;
+ }
+ return;
+ },
+
+ set: function (prefPath, value, def = false) {
+ let sPrefs = def ?
+ Services.prefs.getDefaultBranch(null) :
+ Services.prefs;
+
+ switch (typeof value) {
+ case 'string':
+ return sPrefs.setStringPref(prefPath, value) || value;
+ case 'number':
+ return sPrefs.setIntPref(prefPath, value) || value;
+ case 'boolean':
+ return sPrefs.setBoolPref(prefPath, value) || value;
+ }
+ return;
+ },
+
+ lock: function (prefPath, value) {
+ let sPrefs = Services.prefs;
+ this.lockedBackupDef[prefPath] = this.get(prefPath, true);
+ if (sPrefs.prefIsLocked(prefPath))
+ sPrefs.unlockPref(prefPath);
+
+ this.set(prefPath, value, true);
+ sPrefs.lockPref(prefPath);
+ },
+
+ lockedBackupDef: {},
+
+ unlock: function (prefPath) {
+ Services.prefs.unlockPref(prefPath);
+ let bkp = this.lockedBackupDef[prefPath];
+ if (bkp == undefined)
+ Services.prefs.deleteBranch(prefPath);
+ else
+ this.set(prefPath, bkp, true);
+ },
+
+ clear: Services.prefs.clearUserPref,
+
+ // Detecta mudanças na preferência e retorna:
+ // return[0]: valor da preferência alterada
+ // return[1]: nome da preferência alterada
+ // Guardar chamada numa var se quiser interrompê-la depois
+ addListener: function (prefPath, trat) {
+ this.observer = function (aSubject, aTopic, prefPath) {
+ return trat(xPref.get(prefPath), prefPath);
+ }
+
+ Services.prefs.addObserver(prefPath, this.observer);
+ return {
+ prefPath,
+ observer: this.observer
+ };
+ },
+
+ // Encerra pref observer
+ // Só precisa passar a var definida quando adicionou
+ removeListener: function (obs) {
+ Services.prefs.removeObserver(obs.prefPath, obs.observer);
+ }
+}
diff --git a/modules/firefox.home/default.nix b/modules/firefox.home/default.nix
index 208d2e7..0d53fe9 100644
--- a/modules/firefox.home/default.nix
+++ b/modules/firefox.home/default.nix
@@ -1,10 +1,11 @@
{ config, pkgs, lib, ... }:
let
- unwrappedFirefoxPackage = pkgs.firefox-devedition-unwrapped;
-
- firefoxBinName = "firefox-devedition";
-
+ unwrappedFirefoxPackage = pkgs.firefox-unwrapped;
+ firefoxBinName = "firefox";
configDir = ".mozilla/firefox";
+ # unwrappedFirefoxPackage = pkgs.librewolf-unwrapped;
+ # firefoxBinName = "librewolf";
+ # configDir = ".config/librewolf/librewolf";
extensions = [
"https://addons.mozilla.org/firefox/downloads/file/3792127/firefox_dracula-1.0.xpi"
@@ -36,10 +37,8 @@ let
profilePath = "default";
in {
programs.firefox = {
- enable = false;
+ enable = true;
package = firefox;
-
- # nativeMessagingHosts = [ pkgs.tridactyl-native ];
policies = policies;
};
@@ -48,18 +47,11 @@ in {
] else [];
home.file = if config.programs.firefox.enable then {
- # ".config/tridactyl".source = ./tridactyl;
-
"${configDir}/${profilePath}/chrome".source = ./chrome;
"${configDir}/profiles.ini".text = lib.generators.toINI {} {
- Profile1 = {
- Name = "default";
- IsRelative = 1;
- Path = profilePath;
- };
Profile0 = {
- Name = "dev-edition-default";
+ Name = "default";
Default = 1;
IsRelative = 1;
Path = profilePath;
diff --git a/modules/firefox.home/policies.nix b/modules/firefox.home/policies.nix
index f18f3c8..cacc70d 100644
--- a/modules/firefox.home/policies.nix
+++ b/modules/firefox.home/policies.nix
@@ -4,8 +4,6 @@
ManagedBookmarks = [
{ toplevel_name = "Managed bookmarks"; }
{ name = "Daily Dev"; url = "https://app.daily.dev"; }
- { name = "Email: Microsoft Outlook"; url = "https://outlook.office365.com/mail/"; }
- { name = "Email: GMail"; url = "https://mail.google.com/mail/u/0/"; }
# { name = "Shtuff"; children = [] }
];
DisplayBookmarksToolbar = "never";
@@ -33,7 +31,6 @@
};
ShowHomeButton = false;
- # PopupBlocking = [];
SearchEngines = {
Default = "DuckDuckGo lite";
SearchSuggestEnabled = false;
diff --git a/modules/firefox.home/preferences.nix b/modules/firefox.home/preferences.nix
index accaa05..3d3dc45 100644
--- a/modules/firefox.home/preferences.nix
+++ b/modules/firefox.home/preferences.nix
@@ -37,7 +37,7 @@ in {
"browser.dataFeatureRecommendations.enabled" = false;
"extensions.htmlaboutaddons.recommendations.enabled" = false;
- "layout.css.has-selector.enabled" = true;
+ "layout.css.has-selector.enabled" = true;
"browser.toolbars.bookmarks.visibility" = "never";
"browser.tabs.insertAfterCurrent" = true;
"browser.urlbar.shortcuts.bookmarks" = false;
diff --git a/modules/firefox.home/tridactyl/themes/phenax.css b/modules/firefox.home/tridactyl/themes/phenax.css
deleted file mode 100644
index 43f2ad8..0000000
--- a/modules/firefox.home/tridactyl/themes/phenax.css
+++ /dev/null
@@ -1,173 +0,0 @@
-:root {
- /* Dracula Colors */
- --bg: #0f0c19;
- --currentline: #44475a;
- --fg: #f8f8f2;
- --comment: #6272a4;
- --cyan: #8be9fd;
- --green: #50fa7b;
- --orange: #ffb86c;
- --pink: #ff79c6;
- --violet: #4e3aA3;
- --red: #ff5555;
- --yellow: #f1fa8c;
- --font: "JetBrainsMono Nerd Font", "JetBrains Mono", sans-serif;
-
- --tridactyl-fg: var(--fg);
- --tridactyl-bg: var(--bg);
- --tridactyl-url-fg: var(--violet);
- --tridactyl-url-bg: var(--bg);
- --tridactyl-highlight-box-bg: var(--currentline);
- --tridactyl-highlight-box-fg: var(--fg);
- --tridactyl-of-fg: var(--fg);
- --tridactyl-of-bg: var(--currentline);
- --tridactyl-cmdl-fg: var(--bg);
- --tridactyl-cmdl-font-family: var(--font);
- --tridactyl-cmplt-font-family: var(--font);
- --tridactyl-hintspan-font-family: var(--font);
-
- /* Hint character tags */
- --tridactyl-hintspan-fg: var(--bg) !important;
- --tridactyl-hintspan-bg: var(--green) !important;
-
- /* Element Highlights */
- --tridactyl-hint-active-fg: none;
- --tridactyl-hint-active-bg: none;
- --tridactyl-hint-active-outline: none;
- --tridactyl-hint-bg: none;
- --tridactyl-hint-outline: none;
-}
-
-#command-line-holder {
- order: 1;
- border: 2px solid var(--violet);
- background: var(--tridactyl-bg);
-}
-
-#tridactyl-colon {
- color: var(--violet) !important;
- font-size: 1rem;
-}
-
-#tridactyl-input {
- color: var(--tridactyl-fg);
- width: 90%;
- font-size: 1.1rem !important;
- line-height: 1em;
- background: var(--tridactyl-bg);
- padding: 0.5rem 0.2rem !important;
-}
-
-#completions table {
- font-size: 0.8rem;
- font-weight: 200;
- border-spacing: 0;
- table-layout: fixed;
- padding: 0.5rem 1rem !important;
-}
-
-#completions > div {
- max-height: calc(20 * var(--option-height));
- min-height: calc(10 * var(--option-height));
-}
-
-/* COMPLETIONS */
-
-#completions {
- --option-height: 1.4em;
- color: var(--tridactyl-fg);
- background: var(--tridactyl-bg);
- display: inline-block;
- font-size: unset;
- font-weight: 200;
- overflow: hidden;
- width: 100%;
- border-top: unset;
- order: 2;
-}
-
-/* Olie doesn't know how CSS inheritance works */
-#completions .HistoryCompletionSource {
- max-height: unset;
- min-height: unset;
-}
-
-#completions .HistoryCompletionSource table {
- width: 100%;
- font-size: 9pt;
- border-spacing: 0;
- table-layout: fixed;
-}
-
-/* redundancy 2: redundancy 2: more redundancy */
-#completions .BmarkCompletionSource {
- max-height: unset;
- min-height: unset;
-}
-
-#completions table tr td.prefix,
-#completions table tr td.privatewindow,
-#completions table tr td.container,
-#completions table tr td.icon {
- display: none;
-}
-
-#completions .BufferCompletionSource table {
- width: unset;
- font-size: unset;
- border-spacing: unset;
- table-layout: unset;
-}
-
-#completions table tr .title {
- width: 50%;
-}
-
-#completions table tr {
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-#completions .sectionHeader {
- background: unset;
- font-weight: bold;
- border-bottom: unset;
- font-size: 0.8rem !important;
- color: var(--violet) !important;
- text-transform: uppercase;
- padding: 0.4rem 1rem !important;
-}
-
-#cmdline_iframe:not(.hidden) {
- position: fixed !important;
- bottom: unset;
- top: 25% !important;
- left: 10% !important;
- z-index: 2147483647 !important;
- transition: none !important;
- width: 80% !important;
- box-shadow: rgba(0, 0, 0, 0.5) 0px 0px 20px !important;
- border: 1px solid #1b1825 !important;
-}
-
-.TridactylStatusIndicator {
- position: fixed !important;
- bottom: 0 !important;
- background: var(--tridactyl-bg) !important;
- border: unset !important;
- border: 1px var(--violet) solid !important;
- font-size: 10pt !important;
- /*font-weight: 200 !important;*/
- padding: 0.3ex 0.8ex !important;
-}
-
-#completions .focused {
- background: var(--violet);
- color: var(--fg);
-}
-
-#completions .focused .url {
- background: var(--violet);
- color: var(--fg);
-}
diff --git a/modules/firefox.home/tridactyl/tridactylrc b/modules/firefox.home/tridactyl/tridactylrc
deleted file mode 100644
index f3373a8..0000000
--- a/modules/firefox.home/tridactyl/tridactylrc
+++ /dev/null
@@ -1,36 +0,0 @@
-colorscheme phenax
-
-set hintnames numeric
-set hintfiltermode vimperator-reflow
-set editorcmd sensible-terminal -e nvim
-set newtab about:blank
-set viewsource default
-set browsermaps { "<C-,>": "escapehatch", "<C-6>": "noh" }
-
-" Unbind default keys
-unbind d
-unbind D
-unbind <C-j>
-unbind <C-k>
-unbind t
-unbind tt
-unbind T
-unbind J
-unbind K
-unbind f
-unbind n
-unbind N
-unbind a
-unbind A
-unbind <C-f>
-
-bind o fillcmdline tabopen
-bind O fillcmdline open
-bind p clipboard tabopen
-bind P clipboard open
-bind n findnext
-bind N findprev
-
-bind --mode=normal J scrollpx 0 200
-bind --mode=normal K scrollpx 0 -200
-