userChrome.js hacks
-
- Posts: 6404
- Joined: February 3rd, 2009, 6:29 pm
userChrome.js hacks
Are userChrome.js hacks using the -moz-binding property still possible in Fx 71 and Fx 72?
My hacks still work in Fx 70.
What is userChrome.js?
http://www.userchrome.org/what-is-userchrome-js.html
userChrome.js hack example
http://github.com/Sporif/firefox-quantu ... Chrome.css
http://github.com/Sporif/firefox-quantu ... Chrome.xml
http://gist.github.com/Sporif/ad6e917d8 ... 80d3c8918c
Remove XBL implementation
http://bugzilla.mozilla.org/show_bug.cgi?id=1566221
My hacks still work in Fx 70.
What is userChrome.js?
http://www.userchrome.org/what-is-userchrome-js.html
userChrome.js hack example
http://github.com/Sporif/firefox-quantu ... Chrome.css
http://github.com/Sporif/firefox-quantu ... Chrome.xml
http://gist.github.com/Sporif/ad6e917d8 ... 80d3c8918c
Remove XBL implementation
http://bugzilla.mozilla.org/show_bug.cgi?id=1566221
- therube
- Posts: 21703
- Joined: March 10th, 2004, 9:59 pm
- Location: Maryland USA
Re: userChrome.js hacks
What is http://github.com/Sporif/firefox-quantu ... Chrome.css supposed to do?
copy code, put into /chrome/userChrome.css
enable "chrome" in FF ("stylesheets", about:config, toolkit.legacyUserProfileCustomizations.stylesheets)
restart FF
I'm not seeing any difference, assuming I've done things correctly (72 Nightly).
(The word legacy in there is telling, but then we all knew that.)
copy code, put into /chrome/userChrome.css
enable "chrome" in FF ("stylesheets", about:config, toolkit.legacyUserProfileCustomizations.stylesheets)
restart FF
I'm not seeing any difference, assuming I've done things correctly (72 Nightly).
(The word legacy in there is telling, but then we all knew that.)
Fire 750, bring back 250.
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.19) Gecko/20110420 SeaMonkey/2.0.14 Pinball CopyURL+ FetchTextURL FlashGot NoScript
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.19) Gecko/20110420 SeaMonkey/2.0.14 Pinball CopyURL+ FetchTextURL FlashGot NoScript
-
- Posts: 6404
- Joined: February 3rd, 2009, 6:29 pm
Re: userChrome.js hacks
Is there an error involving the -moz-binding property in the browser console?
Instructions:
* start firefox
* set toolkit.legacyUserProfileCustomizations.stylesheets pref to true
* exit firefox
* create userChrome.css file in chrome folder
* create userChrome.xml file in chrome folder
* create RestartFirefoxButton_Movable.uc.js file in chrome folder
* start firefox
* test restart button on nav bar next to hamburger button
Firefox Quantum compatible userChrome.js
http://github.com/Sporif/firefox-quantum-userchromejs
Instructions:
* start firefox
* set toolkit.legacyUserProfileCustomizations.stylesheets pref to true
* exit firefox
* create userChrome.css file in chrome folder
* create userChrome.xml file in chrome folder
* create RestartFirefoxButton_Movable.uc.js file in chrome folder
* start firefox
* test restart button on nav bar next to hamburger button
Firefox Quantum compatible userChrome.js
http://github.com/Sporif/firefox-quantum-userchromejs
-
- Posts: 205
- Joined: March 17th, 2006, 1:52 pm
Re: userChrome.js hacks
With XBL gone, any code that relies on it, so everything involving -moz-binding, indeed does not work anymore. So say goodbye to userChrome.js. There doesn't seem to be any replacement, there's no other way to load custom code like this anymore.
-
- Posts: 6404
- Joined: February 3rd, 2009, 6:29 pm
Re: userChrome.js hacks
I tested...
The userChrome.js hack succeeds in the Firefox Portable 71.0b8 beta build.
The userChrome.js hack fails in the Firefox Portable 72.0a1 nightly build.
There are no errors in the browser console.
@Gusar
You can do similar hacks with the AutoConfig file.
Customizing Firefox using AutoConfig
http://support.mozilla.org/kb/customizi ... autoconfig
Example
http://github.com/alice0775/userChrome. ... /master/72
AutoConfig is sandboxed by default on the release build. (i.e. can't use the Components object)
You can disable the sandbox by setting the general.config.sandbox_enabled pref to false in the autoconfig.js file.
http://www.mozilla.org/firefox/62.0/releasenotes/
The userChrome.js hack succeeds in the Firefox Portable 71.0b8 beta build.
The userChrome.js hack fails in the Firefox Portable 72.0a1 nightly build.
There are no errors in the browser console.
@Gusar
You can do similar hacks with the AutoConfig file.
Customizing Firefox using AutoConfig
http://support.mozilla.org/kb/customizi ... autoconfig
Example
http://github.com/alice0775/userChrome. ... /master/72
AutoConfig is sandboxed by default on the release build. (i.e. can't use the Components object)
You can disable the sandbox by setting the general.config.sandbox_enabled pref to false in the autoconfig.js file.
Firefox 62 Release NotesOur long term plan is to remove the ability to turn off the sandboxing.
http://www.mozilla.org/firefox/62.0/releasenotes/
Last edited by morat on November 17th, 2019, 8:40 am, edited 1 time in total.
- therube
- Posts: 21703
- Joined: March 10th, 2004, 9:59 pm
- Location: Maryland USA
Re: userChrome.js hacks
(When I initially looked, didn't realize that all three files were need.
When looking later, yes I found the same as you.
Nothing noted in Error Console & the code no longer worked.)
When looking later, yes I found the same as you.
Nothing noted in Error Console & the code no longer worked.)
Fire 750, bring back 250.
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.19) Gecko/20110420 SeaMonkey/2.0.14 Pinball CopyURL+ FetchTextURL FlashGot NoScript
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.19) Gecko/20110420 SeaMonkey/2.0.14 Pinball CopyURL+ FetchTextURL FlashGot NoScript
-
- Posts: 6404
- Joined: February 3rd, 2009, 6:29 pm
Re: userChrome.js hacks
Here are my config files in Firefox 117.
* <install directory>\defaults\pref\autoconfig.js
* <install directory>\mozilla.cfg
* <profile directory>\chrome\RestartFirefoxButton_Movable.uc.js
* <profile directory>\chrome\StylesFirefox.as.css
Troubleshooting info: http://forums.mozillazine.org/viewtopic ... #p14886674
Deploying Firefox in an enterprise environment
http://web.archive.org/web/201910060610 ... _before_60
Observer Notifications
http://web.archive.org/web/201910060345 ... ifications
CustomizableUI
http://web.archive.org/web/201910021231 ... ableUI.jsm
http://web.archive.org/web/201910021231 ... ed_widgets
Agent Sheet
http://www.userchrome.org/adding-style- ... agentsheet
http://web.archive.org/web/201909301025 ... et_Service
Services.jsm is going to be removed in Firefox 117
http://groups.google.com/a/mozilla.org/ ... RgKcXmGd5M
Another example: http://forums.mozillazine.org/viewtopic ... &t=3084974
* <install directory>\defaults\pref\autoconfig.js
Code: Select all
pref("general.config.sandbox_enabled", false);
pref("general.config.filename", "mozilla.cfg");
pref("general.config.obscure_value", 0);
Code: Select all
// mozilla.cfg file needs to start with a comment line
// mozilla.cfg file is sandboxed by default i.e. can't use Components object
// disable sandbox by setting general.config.sandbox_enabled pref to false in autoconfig.js file
// run userChrome.js example.uc.js example.as.css example.css files in chrome folder
// do not run userChrome.css userContent.css example.js files in chrome folder
// browser-delayed-startup-finished topic supports browser window only
// Firefox 68 uses browser.xul page
// Firefox 69 uses browser.xhtml page
// Firefox 116 uses Components.utils.import("resource://gre/modules/Services.jsm");
// Firefox 117 uses var Services = globalThis.Services;
var Services = globalThis.Services;
Services.console.logStringMessage("mozilla.cfg script loaded");
Services.obs.addObserver(function (aSubject, aTopic, aData) {
var chromeWindow = aSubject;
chromeWindow.setTimeout(function () {
try {
if (chromeWindow.userChromeJsMod) return;
chromeWindow.userChromeJsMod = true;
var chromeFiles = chromeWindow.FileUtils.getDir("UChrm", []).directoryEntries;
var sss = Components.classes["@mozilla.org/content/style-sheet-service;1"].
getService(Components.interfaces.nsIStyleSheetService);
while (chromeFiles.hasMoreElements()) {
var file = chromeFiles.getNext().QueryInterface(Components.interfaces.nsIFile);
var fileURI = Services.io.newFileURI(file);
if (file.isFile()) {
if (/(^userChrome|\.uc)\.js$/i.test(file.leafName)) {
Services.scriptloader.loadSubScriptWithOptions(fileURI.spec, {
target: chromeWindow,
charset: "UTF-8",
ignoreCache: true,
});
} else if (/\.as\.css$/i.test(file.leafName)) {
if (!sss.sheetRegistered(fileURI, sss.AGENT_SHEET)) {
sss.loadAndRegisterSheet(fileURI, sss.AGENT_SHEET);
}
} else if (/^(?!(userChrome|userContent)\.css$).+\.css$/i.test(file.leafName)) {
if (!sss.sheetRegistered(fileURI, sss.USER_SHEET)) {
sss.loadAndRegisterSheet(fileURI, sss.USER_SHEET);
}
}
}
}
} catch (aError) {
Components.utils.reportError(aError);
}
}, 10);
}, "browser-delayed-startup-finished", false);
Code: Select all
(function () {
if (location != "chrome://browser/content/browser.xul" &&
location != "chrome://browser/content/browser.xhtml") return;
try {
CustomizableUI.createWidget({
id: "__unique_identifier_restart_button", // should match id below
type: "custom",
defaultArea: CustomizableUI.AREA_MENUBAR,
// defaultArea: CustomizableUI.AREA_NAVBAR,
onBuild: function (aDocument) {
var XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var toolbarbutton = aDocument.createElementNS(XUL_NS, "toolbarbutton");
toolbarbutton.onclick = function (aEvent) {
var win = aEvent.target.ownerDocument.defaultView;
if (aEvent.button == 0) {
if (aEvent.shiftKey) {
Services.appinfo.invalidateCachesOnRestart();
Services.prompt.alert(win, "Restart", "Invalidate caches on restart.");
}
var os = Components.classes["@mozilla.org/observer-service;1"].
getService(Components.interfaces.nsIObserverService);
var cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"].
createInstance(Components.interfaces.nsISupportsPRBool);
os.notifyObservers(cancelQuit, "quit-application-requested", "restart");
if (cancelQuit.data) {
Services.prompt.alert(win, "Restart", "Abort restart process.");
} else {
var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"].
getService(Components.interfaces.nsIAppStartup);
appStartup.quit(appStartup.eAttemptQuit | appStartup.eRestart);
}
} else if (aEvent.button == 1) {
if (aEvent.shiftKey) {
Services.appinfo.invalidateCachesOnRestart();
Services.prompt.alert(win, "Restart", "Invalidate caches on startup.");
}
var os = Components.classes["@mozilla.org/observer-service;1"].
getService(Components.interfaces.nsIObserverService);
var cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"].
createInstance(Components.interfaces.nsISupportsPRBool);
os.notifyObservers(cancelQuit, "quit-application-requested", null);
if (cancelQuit.data) {
Services.prompt.alert(win, "Restart", "Abort quit process.");
} else {
var prefBranch = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefBranch);
var pref = "browser.sessionstore.resume_session_once";
prefBranch.setBoolPref(pref, true);
var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"].
getService(Components.interfaces.nsIAppStartup);
appStartup.quit(appStartup.eAttemptQuit);
}
}
};
var dataUrl = "data:image/png;base64," +
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAANbY1E9YMgAAAB" +
"h0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjM2qefiJQAAA2hJREFUOE9tkm1MU1ccxg9F" +
"YKIIxbdgw4e9GEQYoomArRVYwsIoEakUsRQ3KQpiF8SXMDdtajL8gho+TKeJyYxaFGyltg" +
"ZK1bkurg4uQ0QMgjSbOrbwUoIglPbe9tm5NdGgO8mT3PM/9/md/8sJIv+3JOYwGk6miolY" +
"HB4y5ZqeIcDfxD87SH4vmg5YJOZk4veOvm+XmOOE+XfOZp7qfya/+Ny7/dq/KNAPTafoHv" +
"VH5LZdJWmNnxKxKSE8xzYQuvHCl3MBEnNSwv7OkVKrC0rrBDabXiLX7EbhbQ6VncCBLi9S" +
"dT2TCdXM5PbGIURlndv7FiAxR0fm3W4qu+VC0c1RyJpGkWucQLZxGjKLF1tsfqjuAYcesj" +
"ja60F568hcQFhWqyL95JNXiisvkHGyF+LaHmSfcXKlLS5UOGZRbGex7RcOOxwc1AyLCus7" +
"gCWKuz/FVTH+5UrjhFDeMB68qamPrD2tjSk0n19/5IHr4B9uVHR6UeLwYGeHB5Vtw3MzEE" +
"hNTuGWyz+LSs7r53924Rz5sCyF1hcVKtWvj69qZ3R9s9AOsPj2iRdHn7LQ2N4BhGU21IiK" +
"6nct2/pDSfCaY2JqXkAVLJBa7CuK7b41BxgkH2Sw9hCDdVQrd//GhaTUVxBaez7dsHyQP+" +
"R/4iVS2X1BEuN9CllEtVQQ93XaUlmtIkZ+XBkiPn2YxlbwcbJkm12hsY1AO+jDdwMcjjk5" +
"fN/vQbzmXve8xJovApmk6mM/yDJoY3deqovKbzQESU2DfHl8hgHA3rYRqLt8+IrhoOnmUN" +
"PtBm3cmEjZdoaIm8sFm0y/CuVXB5crm5+vqmJ80Xk3DNQcTRUUAFRSQHk3oO6ks3ZQkIM2" +
"qd2NMusYZD862Y3HH/kyTz32FdIRp5/omwlNqddQc/gbAD9TXZ8Hh3tZlHb46bxZyK0z2G" +
"yZhNwyjvzmYRS3DENtG8OiHFMLiZGtpmZB4BXyGRQ3DSGxumMqTfdw6pseD/bRMlR33Sho" +
"nULBzXHsuDUONc1m9b52F1lZzfeFb+zrRaewNTy75U/yieZzEn9EGpFjuZ6q7XIW6l/MqA" +
"z/oODiX96MusdDUTnGBvJxZSa1RL65PUDYYBCRxNoM+iWkmkc+Ko8mSSckJLletSD97B6S" +
"VLebgvNIZGIsPV8410zIfzl/yL/mmVpFAAAAAElFTkSuQmCC";
var tooltip = [];
tooltip.push("", "", "L: restart application with previous windows and tabs");
tooltip.push("M: quit application, open previous windows and tabs on startup");
tooltip.push("R: open button context popup", "");
tooltip.push("S+L: left click option and invalidate caches on restart");
tooltip.push("S+M: middle click option and invalidate caches on startup", "");
tooltip.push("The middle click option is for users that do not normally restore sessions.");
var props = {
id: "__unique_identifier_restart_button",
class: "toolbarbutton-1 chromeclass-toolbar-additional",
label: "Restart",
tooltiptext: "Restart" + tooltip.join("\n"),
style: 'list-style-image: url("' + dataUrl + '"); -moz-image-region: auto;',
};
for (var p in props) toolbarbutton.setAttribute(p, props[p]);
return toolbarbutton;
},
});
} catch (aError) {
// [check] Show Content Messages in Firefox 109
// [select] Browser Console Mode Multiprocess in Firefox 110
Components.utils.reportError(aError);
};
})();
Code: Select all
/* AGENT_SHEET */
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
@namespace html url("http://www.w3.org/1999/xhtml");
/* Firefox fails to set correct order on startup, see browser.uiCustomization.state pref */
/* use -moz-box-ordinal-group property in Firefox 112 */
/* use order property in Firefox 113 */
@-moz-document url-prefix("chrome://browser/content/browser.xhtml") {
toolbaritem#menubar-items { order: 1 !important; }
toolbarbutton#__unique_identifier_restart_button { order: 2 !important; }
}
Deploying Firefox in an enterprise environment
http://web.archive.org/web/201910060610 ... _before_60
Observer Notifications
http://web.archive.org/web/201910060345 ... ifications
CustomizableUI
http://web.archive.org/web/201910021231 ... ableUI.jsm
http://web.archive.org/web/201910021231 ... ed_widgets
Agent Sheet
http://www.userchrome.org/adding-style- ... agentsheet
http://web.archive.org/web/201909301025 ... et_Service
Services.jsm is going to be removed in Firefox 117
http://groups.google.com/a/mozilla.org/ ... RgKcXmGd5M
Another example: http://forums.mozillazine.org/viewtopic ... &t=3084974
Last edited by morat on September 14th, 2023, 4:32 pm, edited 13 times in total.
-
- Posts: 77
- Joined: November 11th, 2011, 5:43 am
Re: userChrome.js hacks
Thank you very much. Works perfect for me.
-
- Posts: 20
- Joined: December 28th, 2007, 9:53 pm
Re: userChrome.js hacks
Dont work on 78.3 esr, sad
-
- Posts: 200
- Joined: August 30th, 2013, 3:50 pm
Re: userChrome.js hacks
It works using autoconfig as it always has. userChromeJS by XBL binding was an ugly hack and was removed.
- JAB Creations
- Posts: 394
- Joined: December 28th, 2003, 10:21 pm
- Location: Sarasota Florida
- Contact:
Re: userChrome.js hacks
Morat, this worked fantastic in Firefox 115 ESR however I'm having trouble with Firefox 102 ESR.
With the exact same setup I get this in the Browser Toolbox / console:
So I did a bit more research and came across the following at https://wiki.mozilla.org/UserChrome.js:
With the exact same setup I get this in the Browser Toolbox / console:
Well, so I start to try to debug. If I manually run the script in the Toolbox / console it doesn't throw any errors in Firefox 102 ESR.TypeError: Services is undefined
So I did a bit more research and came across the following at https://wiki.mozilla.org/UserChrome.js:
So now I'm thinking about setTimeout however I know it's not going to be available in a website developer content. Well, looked at the script you referenced earlier and I see chromeWindow.setTimeout. However it is already defined once globalThis.Services is already called so yeah... I'm at a dead-end here. How do we modify this to delay until globalThis.Services becomes available please?userChrome.js might be run either as soon as possible or onLoad. Most customization I've seen so far requires for the chrome to be fully loaded. Applying it ASAP will require further boilerplate code to delay some code until the chrome is ready.
Here to mostly fix the browser's broken GUI. I maintain the Fixed Firefox website to share the things I've confirmed work.
-
- Posts: 6404
- Joined: February 3rd, 2009, 6:29 pm
Re: userChrome.js hacks
See files like aboutPage.js in Firefox 115 ESR for possible backward compatibility with ESR versions.
Reference
http://searchfox.org/mozilla-esr115/sou ... outPage.js
i.e.
I use the following code in Firefox 102 ESR and Firefox 115 ESR.
I use the following code in Firefox 117.
Please don't post in old threads.
Reference
http://searchfox.org/mozilla-esr115/sou ... outPage.js
i.e.
Code: Select all
var Services = globalThis.Services || ChromeUtils.import("resource://gre/modules/Services.jsm").Services;
Services.console.logStringMessage("mozilla.cfg script loaded");
Code: Select all
Components.utils.import("resource://gre/modules/Services.jsm");
Services.console.logStringMessage("mozilla.cfg script loaded");
Code: Select all
var Services = globalThis.Services;
Services.console.logStringMessage("mozilla.cfg script loaded");
- JAB Creations
- Posts: 394
- Joined: December 28th, 2003, 10:21 pm
- Location: Sarasota Florida
- Contact:
Re: userChrome.js hacks
Morat, thank you! So Firefox 102 ESR and 115 ESR both work using different code combined (for anyone looking to clean/fix 102 ESR and 115 ESR as well):
So globalThis.Services works in 115 ESR+ while ChromeUtils.import("resource://gre/modules/Services.jsm").Services works in 102 ESR and I confirmed 91 ESR as well.
Code: Select all
var Services = globalThis.Services || ChromeUtils.import("resource://gre/modules/Services.jsm").Services;
Here to mostly fix the browser's broken GUI. I maintain the Fixed Firefox website to share the things I've confirmed work.
-
- Posts: 20
- Joined: June 28th, 2011, 1:47 am
- Location: Minsk, Belarus
Re: userChrome.js hacks
Services are always available in FF 115+, but can be rewritten by another script, for a access to original Services, you need to query globalThis.ServicesSo globalThis.Services works in 115 ESR+
Life sometimes throws this what you want to find ...