[Ext] userChrome.js 0.8

Announce and Discuss the Latest Theme and Extension Releases.
old zeniko
Posts: 0
Joined: December 31st, 1969, 5:00 pm

[Ext] userChrome.js 0.8

Post by old zeniko »

<a href="http://mozilla.zeniko.ch/userchrome.js.xpi">userChrome.js</a> allows to easily customize Firefox through JavaScript.

What userChrome.css is for CSS customization, userChrome.js is for JavaScript. Simply edit the file userChrome.js (in the same place as userChrome.css) and its content will be run whenever a new chrome window is opened (onLoad).

Download
<a href="http://mozilla.zeniko.ch/userchrome.js.xpi">userChrome.js 0.8</a>
This release should work for Firefox and Thunderbird 2.0 as well as version 1.5.0.7 and later and all Gecko 1.9 applications such as Firefox 3 nightlies.

Update from version 0.7
If you're updating from version 0.7, please add the following line to the top of your userChrome.js before restarting Firefox or else your code will be run in places you might not expect:

Code: Select all

if (location != "chrome://browser/content/browser.xul") throw "stop";

(obviously you'll want to replace that URL for applications other than Firefox)

Snippet collections
<li>The original userChrome.js snippet collection
<li>A growing collection of snippets by the author of the ScrapBook extension
<li>Snippet collection from the MozillaZine Knowledge Base
<li>Snippets collected by Pirlouy from the original userChrome.js thread

Revisions
~~ 0.8 ~~~~
<li>userChrome.js is now run for every chrome window, not just the main one
<li>Suggested for inclusion into one of the next Firefox versions (see bug 332529)
~~ 0.7 ~~~~
<li>Added support for most current Gecko applications
~~ 0.6 ~~~~
<li>The file userChrome.js is automatically created
~~ 0.5 ~~~~
<li>Initial release (2006-01-24)
Last edited by old zeniko on September 7th, 2007, 9:15 am, edited 4 times in total.
User avatar
Philip Chee
Posts: 6475
Joined: March 1st, 2005, 3:03 pm
Contact:

Re: [Ext] userChrome.js 0.8

Post by Philip Chee »

zeniko wrote:This release should work for Firefox and Thunderbird 2.0.
What no SeaMonkey support? Not even SuiteRunner?
zeniko wrote:Update from version 0.7
If you're updating from version 0.7, please add the following line to the top of your userChrome.js before restarting Firefox or else your code will be run in places you might not expect:

Code: Select all

if (location != "chrome://browser/content/browser.xul") throw "stop";
If you do that in Thunderbird, it won't run scripts anywhere :)

Phil
old zeniko
Posts: 0
Joined: December 31st, 1969, 5:00 pm

Re: [Ext] userChrome.js 0.8

Post by old zeniko »

Philip Chee wrote:What no SeaMonkey support? Not even SuiteRunner?

SeaMonkey is indeed unofficially supported starting with version 2.0a1pre (AKA SuiteRunner). I just don't mention it since there's no official release available yet.

Philip Chee wrote:If you do that in Thunderbird, it won't run scripts anywhere :)

Obviously. :) OTOH most scripts I've seen were exclusively for Firefox - and non-Firefox users will be clever enough to figure out where to use <kbd>chrome://messenger/content/messenger.xul</kbd> or <kbd>chrome://navigator/content/navigator.xul</kbd> or <kbd>chrome://editor/content/editor.xul</kbd> etc...
pile0nades
Posts: 756
Joined: May 15th, 2005, 2:31 am

Post by pile0nades »

Here's something cool.

Sub-Script/Overlay Loader v3.0

Features:
supports Greasemonkey-style metadata for userChrome scripts and XUL overlays
supports a "main" shortcut for the main browser window in include/exclude lines
supports regexes in the include/exclude lines
scripts without metadata will run only on the main browser window, for backwards compatibility


Here's a sample script that runs in the Options window:

Code: Select all

// ==UserScript==
// @name           Test
// @namespace      http://pile0nades.wordpress.com/
// @description    Test script, pops an alert in the Options window.
// @include        chrome://browser/content/preferences/preferences.xul
// ==/UserScript==

alert("Hello from the Firefox Options!");



For XUL Overlays, put the metadata in a comment after the doctype (if you have one):

Code: Select all

<?xml version="1.0"?>

<!DOCTYPE overlay>
<!--
// ==UserScript==
// @name           Test XUL
// @namespace      http://pile0nades.wordpress.com/
// @description    Test.
// @include        main
// ==/UserScript==
 -->


The "main" keyword is a shortcut for the main browser window.

download here

Bugs reports/feature requests welcome.

Edit: some code cleanup.
Last edited by pile0nades on June 30th, 2007, 11:51 am, edited 2 times in total.
Linkify bug numbers - test: bug 258287
old zeniko
Posts: 0
Joined: December 31st, 1969, 5:00 pm

Post by old zeniko »

pile0nades wrote:Here's something cool.

Very sweet! =D>

A similar, slightly hackier idea: <a href="data:text/javascript,%2F*%20%3A%3A%3A%3A%3A%3A%3A%3A%20Auto-Overlays%20%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%20*%2F%0A%0A(function()%20%7B%0A%09var%20overlay%20%3D%20Components.classes%5B%22%40mozilla.org%2Ffile%2Fdirectory_service%3B1%22%5D.getService(Components.interfaces.nsIProperties).get(%22UChrm%22%2C%20Components.interfaces.nsILocalFile)%3B%0A%09overlay.append(location.host%20%2B%20location.pathname.replace(%2F%5C%2F%2Fg%2C%20%22_%22).replace(%2F%5E_content_%2F%2C%20%22__%22))%3B%0A%09if%20(overlay.exists())%0A%09%7B%0A%09%09document.loadOverlay(Components.classes%5B%22%40mozilla.org%2Fnetwork%2Fio-service%3B1%22%5D.getService(Components.interfaces.nsIIOService).getProtocolHandler(%22file%22).QueryInterface(Components.interfaces.nsIFileProtocolHandler).getURLSpecFromFile(overlay)%2C%20null)%3B%0A%09%7D%0A%7D)()%3B">Auto-Overlays</a> - loads XUL overlays which are named after the chrome URL of the current window. E.g. for <kbd>chrome://browser/content/browser.xul</kbd> the file has to be named <kbd>browser__browser.xul</kbd> (note that "content" is dropped for shorter filenames).

And since we're already talking about Greasemonkey: <a href="data:text/javascript,%2F%2F%20userscripts%20-%20runs%20all%20files%20in%20the%20userscripts%20subfolder%20as%20Greasemonkey%20would%0A%0A(%7B%0A%09init%3A%20function()%0A%09%7B%0A%09%09var%20scripts%20%3D%20%5B%5D%3B%0A%09%09%0A%09%09var%20files%20%3D%20Components.classes%5B%22%40mozilla.org%2Ffile%2Fdirectory_service%3B1%22%5D.getService(Components.interfaces.nsIProperties).get(%22UChrm%22%2C%20Components.interfaces.nsILocalFile)%3B%0A%09%09files.append(%22userscripts%22)%3B%0A%09%09files%20%3D%20files.directoryEntries.QueryInterface(Components.interfaces.nsISimpleEnumerator)%3B%0A%09%09while%20(files.hasMoreElements())%0A%09%09%7B%0A%09%09%09var%20file%20%3D%20files.getNext().QueryInterface(Components.interfaces.nsIFile)%3B%0A%09%09%09scripts.push(this.getScriptData(this.readFile(file)%2C%20file.leafName))%3B%0A%09%09%7D%0A%09%09%0A%09%09getBrowser().addEventListener(%22DOMContentLoaded%22%2C%20function(aEvent)%20%7B%0A%09%09%09var%20doc%20%3D%20new%20XPCNativeWrapper(aEvent.originalTarget)%3B%0A%09%09%09var%20code%20%3D%20scripts.filter(function(aScript)%20%7B%0A%09%09%09%09return%20aScript.regex.test(doc.location)%3B%0A%09%09%09%7D).map(function(aScript)%20%7B%0A%09%09%09%09return%20%22try%20%7B%20(function()%20%7B%5Cn%22%20%2B%20aScript.code%20%2B%20%22%5Cn%7D)()%3B%20%7D%20catch%20(ex)%20%7B%20throw%20ex.message%20%2B%20'%20in%20%22%20%2B%20aScript.filename%20%2B%20%22'%3B%20%7D%5Cn%22%3B%0A%09%09%09%7D).join(%22%22)%3B%0A%09%09%09%0A%09%09%09var%20sandbox%20%3D%20new%20Components.utils.Sandbox(doc)%3B%0A%09%09%09sandbox.document%20%3D%20doc%3B%0A%09%09%09sandbox.__proto__%20%3D%20sandbox.window%20%3D%20doc.defaultView%3B%0A%09%09%09sandbox.XPathResult%20%3D%20Components.interfaces.nsIDOMXPathResult%3B%0A%09%09%09Components.utils.evalInSandbox(code%2C%20sandbox)%3B%0A%09%09%7D%2C%20true)%3B%0A%09%7D%2C%0A%0A%09getScriptData%3A%20function(aContent%2C%20aFilename)%0A%09%7B%0A%09%09var%20header%20%3D%20(aContent.match(%2F%5E%5C%2F%5C%2F%20%3D%3DUserScript%3D%3D%5B%20%5Ct%5D*%5Cn(%3F%3A.*%5Cn)*%3F%5C%2F%5C%2F%20%3D%3D%5C%2FUserScript%3D%3D%5B%20%5Ct%5D*%5Cn%2Fm)%20%7C%7C%20%5B%22%22%5D)%5B0%5D%3B%0A%09%09var%20findNextRe%20%3D%20%2F%5E%5C%2F%5C%2F%20%40(include%7Cexclude)%5B%20%5Ct%5D%2B(%5CS%2B)%2Fgm%3B%0A%09%09var%20match%2C%20rex%20%3D%20%7B%20include%3A%20%5B%5D%2C%20exclude%3A%20%5B%5D%20%7D%3B%0A%09%09%0A%09%09while%20((match%20%3D%20findNextRe.exec(header)))%0A%09%09%7B%0A%09%09%09rex%5Bmatch%5B1%5D%5D.push(match%5B2%5D.replace(%2F%5CW%2Fg%2C%20%22%5C%5C%24%26%22).replace(%2F%5C%5C%5C*%2Fg%2C%20%22.*%3F%22))%3B%0A%09%09%7D%0A%09%09%0A%09%09var%20exclude%20%3D%20rex.exclude.length%20%3E%200%20%3F%20%22(%3F!%22%20%2B%20rex.exclude.join(%22%24%7C%22)%20%2B%20%22%24)%22%20%3A%20%22%22%3B%0A%09%09return%20%7B%0A%09%09%09code%3A%20aContent.replace(header%2C%20%22%22)%2C%0A%09%09%09regex%3A%20new%20RegExp(%22%5E%22%20%2B%20exclude%20%2B%20%22(%22%20%2B%20(rex.include.join(%22%7C%22)%20%7C%7C%20%22.*%22)%20%2B%20%22)%24%22%2C%20%22i%22)%2C%0A%09%09%09filename%3A%20aFilename%0A%09%09%7D%3B%0A%09%7D%2C%0A%0A%09readFile%3A%20function(aFile)%0A%09%7B%0A%09%09var%20stream%20%3D%20Components.classes%5B%22%40mozilla.org%2Fnetwork%2Ffile-input-stream%3B1%22%5D.createInstance(Components.interfaces.nsIFileInputStream)%3B%0A%09%09stream.init(aFile%2C%200x01%2C%200%2C%200)%3B%0A%09%09var%20cvstream%20%3D%20Components.classes%5B%22%40mozilla.org%2Fintl%2Fconverter-input-stream%3B1%22%5D.createInstance(Components.interfaces.nsIConverterInputStream)%3B%0A%09%09cvstream.init(stream%2C%20%22UTF-8%22%2C%201024%2C%20Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER)%3B%0A%09%09%0A%09%09var%20content%20%3D%20%22%22%2C%20data%20%3D%20%7B%7D%3B%0A%09%09while%20(cvstream.readString(4096%2C%20data))%0A%09%09%7B%0A%09%09%09content%20%2B%3D%20data.value%3B%0A%09%09%7D%0A%09%09cvstream.close()%3B%0A%09%09%0A%09%09return%20content.replace(%2F%5Cr%5Cn%3F%2Fg%2C%20%22%5Cn%22)%3B%0A%09%7D%0A%7D).init()%3B%0A">userscripts</a> runs all files in the userscripts subfolder in the same way Greasemonkey would (although it actually lacks the GM_* functions and isn't that great for debugging - but hey, it's simple and notably faster).
User avatar
pirlouy
Posts: 232
Joined: February 11th, 2005, 6:29 am
Location: France

Post by pirlouy »

How to proceed with Sub-Script/Overlay Loader v3.0 ?
I mean there could be scripts for all windows and others only usable for the main window.

If we put Sub-Script/Overlay Loader v3.0 AFTER if location..., I suppose we lose the ability to have .uc.js for others windows. So we have to delete this condition (if location...) in userchrome.js, and put it before all sub-scripts. Am I right ?

I hope I'm clear enought...

Edit: I've just seen pile0nades explanations. Sorry, I can't delete my post.
User avatar
dougeeebear
Posts: 548
Joined: September 15th, 2005, 4:17 pm

Post by dougeeebear »

pirlouy wrote:Sorry, I can't delete my post.

Sure you can.
select Edit, check [ ] Delete this post, and Submit.
User avatar
Philip Chee
Posts: 6475
Joined: March 1st, 2005, 3:03 pm
Contact:

Post by Philip Chee »

dougeeebear wrote:
pirlouy wrote:Sorry, I can't delete my post.
Sure you can.
select Edit, check [ ] Delete this post, and Submit.
But only if there aren't any posts after his (like yours).

Phil
User avatar
dougeeebear
Posts: 548
Joined: September 15th, 2005, 4:17 pm

Post by dougeeebear »

Philip Chee wrote:
dougeeebear wrote:
pirlouy wrote:Sorry, I can't delete my post.
Sure you can.
select Edit, check [ ] Delete this post, and Submit.
But only if there aren't any posts after his (like yours).

Phil

You're right ... I stand corrected.
DMCrimson
Posts: 1025
Joined: February 13th, 2004, 6:11 am

Post by DMCrimson »

seems to break secure login's selection dialog.


Gah... with that oneliner above, it works again as expected...
deathburger
Posts: 20
Joined: April 28th, 2006, 9:58 pm

Post by deathburger »

Clicking the link to install displayed zip garbage in the browser window so I downloaded it. Dragging to a browser window caused a crash but dragging it to the EM worked - I have an "Edit userChrome.js" option in Tools now which is the second thing in the file so I know it's working. Probably not the extension causing it but I figured I'd mention it anyway since it didn't happen when installing others.

Build identifier: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9a8pre) Gecko/2007082801 SeaMonkey/2.0a1pre

Using userChrome.js 0.8
old zeniko
Posts: 0
Joined: December 31st, 1969, 5:00 pm

Post by old zeniko »

deathburger wrote:Clicking the link to install displayed zip garbage in the browser window

Thanks for mentioning this - should now work as expected.

deathburger wrote:Dragging to a browser window caused a crash but dragging it to the EM worked

That was an issue with certain Gecko 1.9a8pre nightly builds. Updating to a more recent build should prevent this from happening again.
deathburger
Posts: 20
Joined: April 28th, 2006, 9:58 pm

Post by deathburger »

A small inspiration. It's probably been done. It has an advantage I forgot to mention in the readme, debugging is slightly easier since Console² says which file the error is in.
<a href="http://deathburger.jottit.com/ucjs">http://deathburger.jottit.com/ucjs</a>
Last edited by deathburger on September 19th, 2007, 9:50 am, edited 1 time in total.
alta88
Posts: 1029
Joined: January 28th, 2006, 3:08 pm

Post by alta88 »

most recent Tb nightlies throw this error:

Code: Select all

Error: 'Component is not available' when calling method: [nsIHandlerService::getTypeFromExtension] = NS_ERROR_NOT_AVAILABLE
Source file: file:///E:/Appdata/Mozilla/Thunderbird/Profiles/clean/extensions/%7B1280606b-2510-4fe0-97ef-9b5a22eafe64%7D/components/userChrome_js.js
Line: 109


don't use Fx nightlies so unknown whether it's gecko1.9 or Tb specific.
User avatar
Philip Chee
Posts: 6475
Joined: March 1st, 2005, 3:03 pm
Contact:

Post by Philip Chee »

I get this in Minefield and SuiteRunner nightlies too.

Phil
Locked