[Ext] userChrome.js<a href="http://www.haslo.ch/zeniko/software/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 browser window is opened (onLoad). If you want this to become a standard part of Firefox in the future, go and vote for bug 332529 and/or contribute to the discussion about how to fix this... Download <a href="http://www.haslo.ch/zeniko/software/userchrome.js.xpi">userChrome.js 0.7</a> This release should work for Firefox and Thunderbird 1.0 and newer, Mozilla Suite, SeaMonkey, Netscape and Netscape Browser, Nvu, Sunbird and Flock - about just as long as extensions can be installed. In case you're using Firefox or Thunderbird 2.0 or any newer Mozilla application and want to run code in other windows than the main ones (without the WindowHook hack from below), get userChrome.js 0.8 instead. Code Samples Basics (should work for all applications): <li><a href="data:text/javascript,%2F*%20%3A%3A%3A%3A%3A%3A%3A%3A%20Sub-Script%2FXUL%20Loader%20%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%20*%2F%0A%0A%2F%2F%20automatically%20includes%20all%20files%20ending%20in%20.uc.js%20and%20.uc.xul%20from%20the%20profile's%20chrome%20folder%0A%0A(function()%20%7B%0A%09var%20getURLSpecFromFile%20%3D%20Components.classes%5B%22%40mozilla.org%2Fnetwork%2Fio-service%3B1%22%5D.getService(Components.interfaces.nsIIOService).getProtocolHandler(%22file%22).QueryInterface(Components.interfaces.nsIFileProtocolHandler).getURLSpecFromFile%3B%0A%09var%20chromeDir%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%09var%20files%20%3D%20chromeDir.directoryEntries.QueryInterface(Components.interfaces.nsISimpleEnumerator)%3B%0A%09var%20xul_files%20%3D%20%5B%5D%3B%0A%09%0A%09while%20(files.hasMoreElements())%0A%09%7B%0A%09%09var%20file%20%3D%20files.getNext().QueryInterface(Components.interfaces.nsIFile)%3B%0A%09%09if%20(%2F%5C.uc%5C.js%24%2Fi.test(file.leafName))%0A%09%09%7B%0A%09%09%09setTimeout(function(aFile)%20%7B%0A%09%09%09%09Components.classes%5B%22%40mozilla.org%2Fmoz%2Fjssubscript-loader%3B1%22%5D.getService(Components.interfaces.mozIJSSubScriptLoader).loadSubScript(getURLSpecFromFile(aFile))%3B%0A%09%09%09%7D%2C%200%2C%20file)%3B%0A%09%09%7D%0A%09%09else%20if%20(%2F(%5EuserChrome%7C%5C.uc)%5C.xul%24%2Fi.test(file.leafName))%0A%09%09%7B%0A%09%09%09xul_files.push(file)%3B%0A%09%09%7D%0A%09%7D%0A%09%0A%09setTimeout(function()%20%7B%0A%09%09if%20(xul_files.length%20%3E%200)%0A%09%09%7B%0A%09%09%09document.loadOverlay(getURLSpecFromFile(xul_files.shift())%2C%20null)%3B%0A%09%09%09setTimeout(arguments.callee%2C%200)%3B%0A%09%09%7D%0A%09%7D%2C%200)%3B%0A%7D)()%3B%0A%0A">Sub-Script/XUL Loader</a> (automatically includes all scripts ending in .uc.js and .uc.xul from the profile's chrome folder - this allows you to keep your code snippets somewhat ordered) <li><a href="data:text/javascript,%2F*%20%3A%3A%3A%3A%3A%3A%3A%3A%20WindowHook%20%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%20*%2F%0A%0Avar%20WindowHook%20%3D%20%7B%0A%09observe%3A%20function(aSubject%2C%20aTopic%2C%20aData)%0A%09%7B%0A%09%09if%20(!aSubject._WindowHook)%0A%09%09%7B%0A%09%09%09aSubject._WindowHook%20%3D%20this%3B%0A%09%09%09aSubject.addEventListener(%22load%22%2C%20this.onLoad_window%2C%20false)%3B%0A%09%09%7D%0A%09%7D%2C%0A%0A%09onLoad_window%3A%20function()%0A%09%7B%0A%09%09this.removeEventListener(%22load%22%2C%20this._WindowHook.onLoad_window%2C%20false)%3B%0A%09%09var%20funcs%20%3D%20this._WindowHook.mFuncs%5Bthis.document.location.href%5D%20%7C%7C%20null%3B%0A%09%09if%20(funcs)%0A%09%09%7B%0A%09%09%09funcs.forEach(function(aFunc)%20%7B%20aFunc(this)%3B%20%7D%2C%20this)%3B%0A%09%09%7D%0A%09%09delete%20this._WindowHook%3B%0A%09%7D%2C%0A%0A%09register%3A%20function(aURL%2C%20aFunc)%0A%09%7B%0A%09%09if%20(!this.mFuncs)%0A%09%09%7B%0A%09%09%09this.mFuncs%20%3D%20%7B%7D%3B%0A%09%09%09Components.classes%5B%22%40mozilla.org%2Fobserver-service%3B1%22%5D.getService(Components.interfaces.nsIObserverService).addObserver(this%2C%20%22domwindowopened%22%2C%20false)%3B%0A%09%09%7D%0A%09%09if%20(!this.mFuncs%5BaURL%5D)%0A%09%09%7B%0A%09%09%09this.mFuncs%5BaURL%5D%20%3D%20%5B%5D%3B%0A%09%09%7D%0A%09%09this.mFuncs%5BaURL%5D.push(aFunc)%3B%0A%09%7D%0A%7D%3B%0A">WindowHook</a> (allows to target all windows / not only the main window) Extension replacements (for Firefox 1.5 and 2.0) <li><a href="data:text/javascript,%2F*%20%3A%3A%3A%3A%3A%3A%3A%3A%20Tabs%20to%20the%20Right%20(cf.%20Tabs%20Open%20Relative)%20%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%20*%2F%0A%0A(function()%20%7B%0A%09getBrowser().__uc_addedTabs%20%3D%200%3B%0A%09eval(%22gBrowser.addTab%20%3D%20%22%20%2B%20gBrowser.addTab.toString().replace(%2F%5C%7B%2F%2C%20%22%24%26%20var%20__oldTabPos%20%3D%20this.mCurrentTab._tPos%3B%22).replace(%2Freturn%20%2F%2C%20%22if%20(!blank)%20this.moveTabTo(t%2C%20__oldTabPos%20%2B%201%20%2B%20this.__uc_addedTabs%2B%2B)%3B%20%24%26%22))%3B%0A%09eval(%22gBrowser.moveTabTo%20%3D%20%22%20%2B%20gBrowser.moveTabTo.toString().replace(%2F%7B%2F%2C%20%22%24%26%20if%20(aTab%20%3D%3D%20this.mCurrentTab)%20this.__uc_addedTabs%20%3D%200%3B%22))%3B%0A%09gBrowser.mTabContainer.addEventListener(%22select%22%2C%20function()%20%7B%20gBrowser.__uc_addedTabs%20%3D%200%3B%20%7D%2C%20false)%3B%0A%7D)()%3B%0A">Tabs to the Right</a> (Tabs Open Relative light) <li><a href="data:text/javascript,%2F*%20%3A%3A%3A%3A%3A%3A%3A%3A%20Drag'n'go%20(cf.%20Super%20DragAndGo)%20%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%20*%2F%0A%0AcontentAreaDNDObserver.onDragOver%20%3D%20function(aEvent%2C%20aFlavour%2C%20aDragSession)%20%7B%0A%09aEvent.target.setAttribute(%22dragover%22%2C%20%22true%22)%3B%0A%09%0A%09return%20(aDragSession.canDrop%20%3D%20true)%3B%0A%7D%3B%0A%0AcontentAreaDNDObserver.__preDnG_onDrop%20%3D%20contentAreaDNDObserver.onDrop%20%7C%7C%20null%3B%0AcontentAreaDNDObserver.onDrop%20%3D%20function(aEvent%2C%20aXferData%2C%20aDragSession)%20%7B%0A%09var%20url%20%3D%20(%2F%5E%5Cs*(.*%3F)%5Cs*%24%2Fm.test(aXferData.data))%3FRegExp.%241%3Anull%3B%0A%09if%20(!url)%0A%09%7B%0A%09%09this.__preDnG_onDrop(aEvent%2C%20aXferData%2C%20aDragSession)%3B%0A%09%09return%3B%0A%09%7D%0A%09aEvent.preventDefault()%3B%0A%09%0A%09if%20(%2F%5Efile%3A%5C%2F%7B3%7D(%3F%3A.*%5C%2F)%3F(.%2B%5C.xpi)%24%2F.test(url))%20%2F%2F%20local%20XPI%20-%3E%20installation%0A%09%7B%0A%09%09var%20xpinstallObj%20%3D%20%7B%7D%3B%0A%09%09xpinstallObj%5BRegExp.%241%5D%20%3D%20url%3B%0A%09%09%0A%09%09for%20(var%20i%20%3D%201%3B%20i%20%3C%20aDragSession.numDropItems%3B%20i%2B%2B)%0A%09%09%7B%20%2F%2F%20allow%20to%20install%20several%20extensions%20at%20once%0A%09%09%09if%20((url%20%3D%20this.__DnG_getDroppedURL(aDragSession%2C%20i))%20%26%26%20%2F%5Efile%3A%5C%2F%7B3%7D(%3F%3A.*%5C%2F)%3F(.%2B%5C.xpi)%24%2F.test(url))%0A%09%09%09%7B%0A%09%09%09%09xpinstallObj%5BRegExp.%241%5D%20%3D%20url%3B%0A%09%09%09%7D%0A%09%09%7D%0A%09%09%0A%09%09InstallTrigger.install(xpinstallObj)%3B%0A%09%09return%3B%0A%09%7D%0A%09%0A%09if%20(aDragSession.numDropItems%20%3D%3D%201%20%26%26%20!%2F%5Efile%3A%5C%2F%7B3%7D%7C%5Edata%3A.%2B%7C%5E(%3F!javascript%3A)%5CS*%3F((%3F%3A%5B%5Cw-%5D%5C.)%2B%5Cw%7B2%2C7%7D%7Clocalhost(%5B%3A%5C%2F%5D%7C%24))%5CS*%24%2F.test(url))%20%2F%2F%20text%20string%20-%3E%20web%20search%0A%09%7B%0A%09%09try%0A%09%09%7B%0A%09%09%09var%20searchURL%20%3D%20gPrefService.getComplexValue(%22browser.search.defaulturl%22%2C%20Components.interfaces.nsIPrefLocalizedString).data%3B%0A%09%09%7D%0A%09%09catch%20(ex)%0A%09%09%7B%0A%09%09%09searchURL%20%3D%20%22http%3A%2F%2Fwww.google.com%2Fsearch%3Fq%3D%22%3B%0A%09%09%7D%0A%09%09url%20%3D%20searchURL%20%2B%20encodeURIComponent(url)%3B%0A%09%7D%0A%09else%20if%20(%2F%5Ettps%3F%3A%2F.test(url))%0A%09%7B%0A%09%09url%20%3D%20%22h%22%20%2B%20url%3B%0A%09%7D%0A%09%0A%09gBrowser.dragDropSecurityCheck(aEvent%2C%20aDragSession%2C%20url)%3B%0A%09%0A%09if%20(gBrowser.currentURI.spec%20%3D%3D%20%22about%3Ablank%22)%0A%09%7B%0A%09%09loadURI(url%2C%20null%2C%20null)%3B%0A%09%7D%0A%09else%0A%09%7B%0A%09%09var%20newTab%20%3D%20gBrowser.addTab(url%2C%20gBrowser.currentURI)%3B%0A%09%09if%20(getBoolPref(%22browser.tabs.loadInBackground%22)%20!%3D%20!(aEvent%20%26%26%20aEvent.shiftKey))%0A%09%09%7B%0A%09%09%09gBrowser.selectedTab%20%3D%20newTab%3B%0A%09%09%7D%0A%09%7D%0A%09%0A%09for%20(i%20%3D%201%3B%20i%20%3C%20aDragSession.numDropItems%3B%20i%2B%2B)%0A%09%7B%0A%09%09if%20((url%20%3D%20this.__DnG_getDroppedURL(aDragSession%2C%20i)))%0A%09%09%7B%0A%09%09%09gBrowser.dragDropSecurityCheck(aEvent%2C%20aDragSession%2C%20url)%3B%0A%09%09%09gBrowser.addTab(url%2C%20gBrowser.currentURI)%3B%0A%09%09%7D%0A%09%7D%0A%7D%3B%0A%0AcontentAreaDNDObserver.__preDnG_onDragStart%20%3D%20contentAreaDNDObserver.onDragStart%20%7C%7C%20null%3B%0AcontentAreaDNDObserver.onDragStart%20%3D%20function(aEvent%2C%20aXferData%2C%20aDragAction)%20%7B%0A%09var%20target%20%3D%20aEvent.originalTarget%3B%0A%09if%20(!(target%20instanceof%20HTMLImageElement%20%26%26%20target.src))%0A%09%7B%0A%09%09contentAreaDNDObserver.__preDnG_onDragStart(aEvent%2C%20aXferData%2C%20aDragAction)%3B%0A%09%09return%3B%0A%09%7D%0A%09for%20(var%20obj%20%3D%20target.parentNode%3B%20obj%20%26%26%20!obj.href%3B%20obj%20%3D%20obj.parentNode)%3B%0A%09%0A%09var%20url%20%3D%20(obj)%3Fobj.href%3Atarget.src%3B%0A%09var%20caption%20%3D%20((obj)%3Fobj.title%3Anull)%20%7C%7C%20target.title%20%7C%7C%20target.alt%20%7C%7C%20url.replace(%2F%5E.*%5C%2F%2F%2C%20%22%22)%20%7C%7C%20url%3B%0A%09%0A%09aXferData.data%20%3D%20new%20TransferData()%3B%0A%09aXferData.data.addDataForFlavour(%22text%2Fx-moz-url%22%2C%20url%20%2B%20%22%5Cn%22%20%2B%20caption)%3B%0A%09aXferData.data.addDataForFlavour(%22text%2Funicode%22%2C%20url)%3B%0A%09aXferData.data.addDataForFlavour(%22text%2Fhtml%22%2C%20'%3Ca%20href%3D%22'%20%2B%20url%20%2B%20'%22%3E'%20%2B%20caption%20%2B%20'%3C%2Fa%3E')%3B%0A%09%0A%09const%20nsIDragService%20%3D%20Components.interfaces.nsIDragService%3B%0A%09aDragAction.action%20%3D%20nsIDragService.DRAGDROP_ACTION_COPY%20%7C%20nsIDragService.DRAGDROP_ACTION_MOVE%20%7C%20nsIDragService.DRAGDROP_ACTION_LINK%3B%0A%7D%3B%0A%0AcontentAreaDNDObserver.__DnG_getDroppedURL%20%3D%20function(aDragSession%2C%20aIx)%20%7B%0A%09try%0A%09%7B%0A%09%09var%20xfer%20%3D%20Components.classes%5B%22%40mozilla.org%2Fwidget%2Ftransferable%3B1%22%5D.createInstance(Components.interfaces.nsITransferable)%3B%0A%09%09xfer.addDataFlavor(%22application%2Fx-moz-file%22%2C%20%22nsIFile%22)%3B%0A%09%09xfer.addDataFlavor(%22text%2Fx-moz-url%22)%3B%0A%09%09xfer.addDataFlavor(%22text%2Funicode%22)%3B%0A%09%09aDragSession.getData(xfer%2C%20aIx)%3B%0A%09%09%0A%09%09var%20flavour%20%3D%20%7B%7D%2C%20data%20%3D%20%7B%7D%2C%20length%20%3D%20%7B%7D%3B%0A%09%09xfer.getAnyTransferData(flavour%2C%20data%2C%20length)%3B%0A%09%09var%20xferData%20%3D%20new%20FlavourData(data.value%2C%20length.value%2C%20this.getSupportedFlavours().flavourTable%5Bflavour.value%5D)%3B%0A%09%09%0A%09%09return%20transferUtils.retrieveURLFromData(xferData.data%2C%20xferData.flavour.contentType)%3B%0A%09%7D%0A%09catch%20(ex)%0A%09%7B%0A%09%09return%20null%3B%0A%09%7D%0A%7D%3B%0A%0Aeval(%22nsDragAndDrop.checkCanDrop%20%3D%20%22%20%2B%20nsDragAndDrop.checkCanDrop.toString().replace(%22aEvent.target%22%2C%20%22%24%26%20%7C%7C%20this.mDragSession.sourceNode%20instanceof%20HTMLImageElement%22))%3B%0A%0AgetBrowser().addEventListener(%22dragover%22%2C%20function(aEvent)%20%7B%0A%09nsDragAndDrop.dragOver(aEvent%2C%20contentAreaDNDObserver)%3B%0A%7D%2C%20false)%3B%0AgBrowser.addEventListener(%22drop%22%2C%20function(aEvent)%20%7B%0A%09nsDragAndDrop.dragOver(aEvent%2C%20contentAreaDNDObserver)%3B%0A%7D%2C%20false)%3B%0AgBrowser.addEventListener(%22draggesture%22%2C%20function(aEvent)%20%7B%0A%09nsDragAndDrop.startDrag(aEvent%2C%20contentAreaDNDObserver)%3B%0A%7D%2C%20true)%3B%0A">Drag'n'go</a> (Super DragAndGo without UI) <li><a href="data:text/javascript,%2F*%20%3A%3A%3A%3A%3A%3A%3A%3A%20LaunchIE%20(cf.%20IE%20View)%20%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%20*%2F%0A%0Avar%20LaunchIE%20%3D%20%7B%0A%09mSchemes%3A%20%5B%22file%22%2C%20%22ftp%22%2C%20%22http%22%2C%20%22https%22%5D%2C%0A%0A%09init%3A%20function()%0A%09%7B%0A%09%09this.mItem%20%3D%20document.createElement(%22menuitem%22)%3B%0A%09%09this.mItem.setAttribute(%22label%22%2C%20%22LaunchIE%22)%3B%0A%09%09this.mItem.setAttribute(%22accesskey%22%2C%20%22u%22)%3B%0A%09%09%0A%09%09document.getElementById(%22contentAreaContextMenu%22).addEventListener(%22popupshowing%22%2C%20function()%20%7B%20LaunchIE.onPopupShowing(this)%3B%20%7D%2C%20false)%3B%0A%09%7D%2C%0A%0A%09onPopupShowing%3A%20function(aPopup)%0A%09%7B%0A%09%09aPopup.insertBefore(this.mItem%2C%20document.getElementById(%22context-sep-%22%20%2B%20((gContextMenu.onLink)%3F%22open%22%3A%22stop%22)))%3B%0A%09%09this.mItem.setAttribute(%22oncommand%22%2C%20%22LaunchIE.launch(%22%20%2B%20((gContextMenu.onLink)%3F%22gContextMenu.linkURI%22%3A%22gBrowser.currentURI%22)%20%2B%20%22)%3B%22)%3B%0A%09%09this.mItem.hidden%20%3D%20!gContextMenu.onLink%20%26%26%20(gContextMenu.isTextSelected%20%7C%7C%20gContextMenu.onImage%20%7C%7C%20gContextMenu.onTextInput)%3B%0A%09%09this.mItem.setAttribute(%22disabled%22%2C%20this.mItem.hidden%20%7C%7C%20!this.isSupported((gContextMenu.onLink)%3FgContextMenu.linkURI%3AgBrowser.currentURI))%3B%0A%09%7D%2C%0A%0A%09launch%3A%20function(aURI%2C%20aApp)%0A%09%7B%0A%09%09if%20(!this.isSupported(aURI))%0A%09%09%7B%0A%09%09%09throw%20new%20Error(%22LaunchIE%3A%20unsupported%20URI%20scheme%20'%22%20%2B%20aURI.scheme%20%2B%20%22'!%22)%3B%0A%09%09%7D%0A%09%09%0A%09%09var%20iexplore%20%3D%20Components.classes%5B%22%40mozilla.org%2Ffile%2Flocal%3B1%22%5D.createInstance(Components.interfaces.nsILocalFile)%3B%0A%09%09try%0A%09%09%7B%0A%09%09%09var%20regkey%20%3D%20Components.classes%5B%22%40mozilla.org%2Fwindows-registry-key%3B1%22%5D.createInstance(Components.interfaces.nsIWindowsRegKey)%3B%0A%09%09%09regkey.open(Components.interfaces.nsIWindowsRegKey.ROOT_KEY_LOCAL_MACHINE%2C%20%22SOFTWARE%5C%5CMicrosoft%5C%5CWindows%5C%5CCurrentVersion%5C%5CApp%20Paths%5C%5C%22%20%2B%20(aApp%20%7C%7C%20%22IEXPLORE.EXE%22)%2C%20Components.interfaces.nsIWindowsRegKey.ACCESS_READ)%3B%0A%09%09%09iexplore.initWithPath(regkey.readStringValue(%22%22))%3B%0A%09%09%09regkey.close()%3B%0A%09%09%7D%0A%09%09catch%20(ex)%0A%09%09%7B%0A%09%09%09iexplore.initWithPath((Components.classes%5B%22%40mozilla.org%2Fprocess%2Fenvironment%3B1%22%5D.getService(Components.interfaces.nsIEnvironment).get(%22PROGRAMFILES%22)%20%7C%7C%20%22C%3A%5C%5CProgram%20Files%22)%20%2B%20%22%5C%5CInternet%20Explorer%5C%5Ciexplore.exe%22)%3B%0A%09%09%7D%0A%09%09%0A%09%09var%20process%20%3D%20Components.classes%5B%22%40mozilla.org%2Fprocess%2Futil%3B1%22%5D.createInstance(Components.interfaces.nsIProcess)%3B%0A%09%09process.init(iexplore)%3B%0A%09%09process.run(false%2C%20%5BaURI.spec%5D%2C%201)%3B%0A%09%7D%2C%0A%0A%09isSupported%3A%20function(aURI)%0A%09%7B%0A%09%09return%20this.mSchemes.indexOf(aURI.scheme)%20%3E%20-1%3B%0A%09%7D%0A%7D%3B%0A%0ALaunchIE.init()%3B%0A">LaunchIE</a> (IEView without UI) User interface enhancements (for Firefox 2.0) <li><a href="data:text/javascript,%2F*%20%3A%3A%3A%3A%3A%3A%3A%3A%20Fashion%20Tabs%20%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%20*%2F%0A%0A(%7B%0A%09init%3A%20function()%0A%09%7B%0A%09%09Array.forEach(getBrowser().mTabs%2C%20function(aTab)%20%7B%0A%09%09%09aTab.linkedBrowser.addProgressListener(this)%3B%0A%09%09%7D%2C%20this)%3B%0A%09%09%0A%09%09gBrowser.addEventListener(%22TabOpen%22%2C%20this%2C%20false)%3B%0A%09%09gBrowser.addEventListener(%22TabSelect%22%2C%20this%2C%20false)%3B%0A%09%09gBrowser.addEventListener(%22TabMove%22%2C%20this%2C%20false)%3B%0A%09%09gBrowser.addEventListener(%22TabClose%22%2C%20this%2C%20false)%3B%0A%09%7D%2C%0A%0A%09handleEvent%3A%20function(aEvent)%0A%09%7B%0A%09%09var%20tab%20%3D%20aEvent.originalTarget%3B%0A%09%09%0A%09%09switch%20(aEvent.type)%0A%09%09%7B%0A%09%09case%20%22TabOpen%22%3A%0A%09%09%09tab.linkedBrowser.addProgressListener(this)%3B%0A%09%09%09break%3B%0A%09%09case%20%22TabMove%22%3A%0A%09%09case%20%22TabSelect%22%3A%0A%09%09%09this.colorizeTab(tab)%3B%0A%09%09%09break%3B%0A%09%09case%20%22TabClose%22%3A%0A%09%09%09tab.linkedBrowser.removeProgressListener(this)%3B%0A%09%09%09break%3B%0A%09%09%7D%0A%09%7D%2C%0A%0A%09onLocationChange%3A%20function(aProgress%2C%20aRequest%2C%20aURI)%20%7B%0A%09%09var%20doc%20%3D%20aProgress.DOMWindow.document%3B%0A%09%09var%20tab%20%3D%20gBrowser.mTabs%5BgBrowser.getBrowserIndexForDocument(doc)%5D%3B%0A%09%09%0A%09%09this.colorizeTab(tab)%3B%0A%09%7D%2C%0A%0A%09onStateChange%3A%20function()%20%7B%20%7D%2C%0A%09onProgressChange%3A%20function()%20%7B%20%7D%2C%0A%09onStatusChange%3A%20function()%20%7B%20%7D%2C%0A%09onSecurityChange%3A%20function()%20%7B%20%7D%2C%0A%09onLinkIconAvailable%3A%20function()%20%7B%20%7D%2C%0A%0A%09colorizeTab%3A%20function(aTab)%0A%09%7B%0A%09%09function%20djb2hash(aString)%0A%09%09%7B%0A%09%09%09var%20hashvalue%20%3D%205381%3B%0A%09%09%09for%20(var%20i%20%3D%200%3B%20i%20%3C%20aString.length%3B%20i%2B%2B)%0A%09%09%09%7B%0A%09%09%09%09hashvalue%20%3D%20((hashvalue%20%3C%3C%205)%20%2B%20hashvalue)%20%2B%20aString.charCodeAt(i)%3B%0A%09%09%09%7D%0A%09%09%09return%20hashvalue%3B%0A%09%09%7D%0A%09%09%0A%09%09try%0A%09%09%7B%0A%09%09%09var%20host%20%3D%20aTab.linkedBrowser.currentURI.host%3B%0A%09%09%7D%0A%09%09catch%20(ex)%20%7B%20%7D%0A%09%09%0A%09%09if%20(host%20%26%26%20host%20!%3D%20%22about%3Ablank%22)%0A%09%09%7B%0A%09%09%09var%20hue%20%3D%20djb2hash(host.replace(%2F%5Ewww%5C.(%3F%3D.%2B%5C..)%2F%2C%20%22%22))%20%25%20360%3B%0A%09%09%7D%0A%09%09var%20color%20%3D%20(hue)%3F%22hsl(%22%20%2B%20hue%20%2B%20%22%2C%2050%25%2C%2050%25)%22%3Anull%3B%0A%09%09%0A%09%09Array.forEach(aTab.ownerDocument.getAnonymousNodes(aTab)%2C%20function(aNode)%20%7B%0A%09%09%09aNode.style.backgroundColor%20%3D%20color%3B%0A%09%09%7D)%3B%0A%09%09%0A%09%09if%20(gBrowser.selectedTab%20%3D%3D%20aTab)%0A%09%09%7B%0A%09%09%09var%20node%20%3D%20aTab.ownerDocument.getAnonymousElementByAttribute(aTab.parentNode%2C%20%22class%22%2C%20%22tabs-bottom%22)%3B%0A%09%09%09if%20(color)%0A%09%09%09%09node.setAttribute(%22style%22%2C%20%22background-color%3A%20%22%20%2B%20color%20%2B%20%22%20!important%22)%3B%0A%09%09%09else%0A%09%09%09%09node.removeAttribute(%22style%22)%3B%0A%09%09%7D%0A%09%7D%2C%0A%0A%09QueryInterface%3A%20function(aIID)%20%7B%0A%09%09var%20Ci%20%3D%20Components.interfaces%3B%0A%09%09if%20(!%5BCi.nsIDOMEventListener%2C%20Ci.nsIWebProgressListener%2C%20Ci.nsISupportsWeakReference%2C%20Ci.nsISupports%5D.some(aIID.equals))%0A%09%09%7B%0A%09%09%09throw%20Components.results.NS_NOINTERFACE%3B%0A%09%09%7D%0A%09%09return%20this%3B%0A%09%7D%0A%7D).init()%3B%0A">Fashion Tabs</a> (Chromatabs lite; only tested with the default theme under Windows) <li><a href="data:text/javascript,%2F*%20%3A%3A%3A%3A%3A%3A%3A%3A%20Undo%20Close%20Tab%20Menu%20%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%20*%2F%0A%0Avar%20UndoCloseTabMenu%20%3D%20%7B%0A%09mSavePref%3A%20%22extensions.userchrome_js.uctm_state%22%2C%0A%0A%09init%3A%20function()%0A%09%7B%0A%09%09this.mSS%20%3D%20Components.classes%5B%22%40mozilla.org%2Fbrowser%2Fsessionstore%3B1%22%5D.getService(Components.interfaces.nsISessionStore)%3B%0A%09%09%0A%09%09var%20dts%20%3D%20document.getElementById(%22devToolsSeparator%22)%3B%0A%09%09var%20menu%20%3D%20dts.parentNode.insertBefore(document.createElement(%22menu%22)%2C%20dts.parentNode.firstChild)%3B%0A%09%09%0A%09%09menu.setAttribute(%22label%22%2C%20%22Undo%20Close%20Tab%22)%3B%0A%09%09menu.setAttribute(%22accesskey%22%2C%20%22U%22)%3B%0A%09%09%0A%09%09this._popup%20%3D%20menu.appendChild(document.createElement(%22menupopup%22))%3B%0A%09%09this._popup.setAttribute(%22onpopupshowing%22%2C%20%22UndoCloseTabMenu.onPopupShowing()%3B%22)%3B%0A%09%7D%2C%0A%0A%09onPopupShowing%3A%20function()%0A%09%7B%0A%09%09while%20(this._popup.hasChildNodes())%0A%09%09%7B%0A%09%09%09this._popup.removeChild(this._popup.lastChild)%3B%0A%09%09%7D%0A%09%09%0A%09%09var%20undoItems%20%3D%20eval(%22(%22%20%2B%20this.mSS.getClosedTabData(window)%20%2B%20%22)%22)%3B%0A%09%09for%20(var%20i%20%3D%200%3B%20i%20%3C%20undoItems.length%3B%20i%2B%2B)%0A%09%09%7B%0A%09%09%09var%20key%20%3D%20(i%20%3C%209)%3Fi%20%2B%201%3A(i%20%3D%3D%209)%3F%220%22%3A%22%22%3B%0A%09%09%09var%20menuitem%20%3D%20this._popup.appendChild(document.createElement(%22menuitem%22))%3B%0A%09%09%09menuitem.setAttribute(%22label%22%2C%20((key)%3Fkey%20%2B%20%22)%20%22%3A%22%22)%20%2B%20undoItems%5Bi%5D.title)%3B%0A%09%09%09menuitem.setAttribute(%22accesskey%22%2C%20key)%3B%0A%09%09%09menuitem.setAttribute(%22oncommand%22%2C%20%22undoCloseTab(%22%20%2B%20i%20%2B%20%22)%3B%22)%3B%0A%09%09%7D%0A%09%09if%20(undoItems.length%20%3E%200)%0A%09%09%7B%0A%09%09%09this._popup.appendChild(document.createElement(%22menuseparator%22))%3B%0A%09%09%7D%0A%09%09%0A%09%09var%20savedTabs%20%3D%20gPrefService.prefHasUserValue(this.mSavePref)%3B%0A%09%09menuitem%20%3D%20this._popup.appendChild(document.createElement(%22menuitem%22))%3B%0A%09%09menuitem.setAttribute(%22label%22%2C%20(savedTabs)%3F%22Restore%20Saved%20Window%22%3A%22Save%20Current%20Window%22)%3B%0A%09%09menuitem.setAttribute(%22accesskey%22%2C%20(savedTabs)%3F%22R%22%3A%22S%22)%3B%0A%09%09menuitem.setAttribute(%22oncommand%22%2C%20%22UndoCloseTabMenu.saveRestore(event)%3B%22)%3B%0A%09%09if%20(savedTabs)%0A%09%09%7B%0A%09%09%09menuitem.setAttribute(%22style%22%2C%20%22font-weight%3A%20bold%3B%22)%3B%0A%09%09%7D%0A%09%7D%2C%0A%0A%09saveRestore%3A%20function(aEvent)%0A%09%7B%0A%09%09if%20(gPrefService.prefHasUserValue(this.mSavePref))%0A%09%09%7B%0A%09%09%09var%20state%20%3D%20gPrefService.getCharPref(this.mSavePref)%3B%0A%09%09%09if%20(aEvent.ctrlKey)%0A%09%09%09%7B%0A%09%09%09%09var%20tabcount%20%3D%20gBrowser.mTabs.length%20%2B%20(eval(state).windows%5B0%5D.selected%20%7C%7C%201)%20-%201%3B%0A%09%09%09%7D%0A%09%09%09this.mSS.setWindowState(window%2C%20state%2C%20!aEvent.ctrlKey)%3B%0A%09%09%09if%20(aEvent.ctrlKey)%0A%09%09%09%7B%0A%09%09%09%09setTimeout(function(aTab)%20%7B%0A%09%09%09%09%09gBrowser.selectedTab%20%3D%20aTab%3B%0A%09%09%09%09%7D%2C%20100%2C%20gBrowser.mTabs%5Btabcount%5D)%3B%0A%09%09%09%7D%0A%09%09%09gPrefService.deleteBranch(this.mSavePref)%3B%0A%09%09%7D%0A%09%09else%0A%09%09%7B%0A%09%09%09gPrefService.setCharPref(this.mSavePref%2C%20%22(%22%20%2B%20this.mSS.getWindowState(window)%20%2B%20%22)%22)%3B%0A%09%09%7D%0A%09%7D%0A%7D%3B%0A%0Aif%20(Components.interfaces.nsISessionStore)%0A%7B%0A%09UndoCloseTabMenu.init()%3B%0A%09%0A%09getBrowser().undoRemoveTab%20%3D%20undoCloseTab%3B%0A%7D%0A">Undo Close Tab Menu</a> (moves the Recently Closed Tabs menu over to Tools for when you've hidden the History menu; and adds a one-shot session saving/restoring function) <li><a href="data:text/javascript,%2F*%20%3A%3A%3A%3A%3A%3A%3A%3A%20Drag'n'Duplicate%20%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%3A%20*%2F%0A%0AgBrowser.duplicateTab%20%3D%20function(aTab)%20%7B%0A%09var%20ss%20%3D%20Components.classes%5B%22%40mozilla.org%2Fbrowser%2Fsessionstore%3B1%22%5D.getService(Components.interfaces.nsISessionStore)%3B%0A%09var%20state%20%3D%20ss.getWindowState(aTab.ownerDocument.defaultView)%3B%0A%09state%20%3D%20eval(%22(%22%20%2B%20state%20%2B%20%22)%22)%3B%0A%09state.windows%5B0%5D.tabs%20%3D%20state.windows%5B0%5D.tabs.splice(aTab._tPos%2C%201)%3B%0A%09ss.setWindowState(window%2C%20state.toSource()%2C%20false)%3B%0A%09%0A%09return%20document.getAnonymousElementByAttribute(this%2C%20%22linkedpanel%22%2C%20this.mPanelContainer.lastChild.id)%3B%0A%7D%3B%0A%0AgBrowser.__preUC_onDrop%20%3D%20gBrowser.onDrop%3B%0AgBrowser.onDrop%20%3D%20function(aEvent%2C%20aXferData%2C%20aDragSession)%20%7B%0A%09if%20(aDragSession.sourceNode%20%26%26%20aDragSession.sourceNode.localName%20%3D%3D%20%22tab%22)%0A%09%7B%0A%09%09var%20oldTab%20%3D%20aDragSession.sourceNode%3B%0A%09%09if%20(aEvent.ctrlKey)%0A%09%09%7B%0A%09%09%09var%20tab%20%3D%20this.duplicateTab(oldTab)%3B%0A%09%09%09if%20(oldTab.parentNode%20!%3D%20this.mTabContainer)%0A%09%09%09%7B%0A%09%09%09%09this.selectedTab%20%3D%20tab%3B%0A%09%09%09%7D%0A%09%09%09this.moveTabTo(tab%2C%20this.getNewIndex(aEvent))%3B%0A%09%09%09return%3B%0A%09%09%7D%0A%09%09if%20(oldTab.parentNode%20!%3D%20this.mTabContainer)%0A%09%09%7B%0A%09%09%09this.selectedTab%20%3D%20this.duplicateTab(oldTab)%3B%0A%09%09%09this.moveTabTo(this.selectedTab%2C%20this.getNewIndex(aEvent))%3B%0A%09%09%09oldTab.ownerDocument.defaultView.gBrowser.removeTab(oldTab)%3B%0A%09%09%09window.focus()%3B%0A%09%09%09return%3B%0A%09%09%7D%0A%09%7D%0A%09gBrowser.__preUC_onDrop(aEvent%2C%20aXferData%2C%20aDragSession)%3B%0A%7D%3B%0A%0AgBrowser.__preUC_onDragOver%20%3D%20gBrowser.onDragOver%3B%0AgBrowser.onDragOver%20%3D%20function(aEvent%2C%20aFlavour%2C%20aDragSession)%20%7B%0A%09if%20(aDragSession.sourceNode%20%26%26%20aDragSession.sourceNode.localName%20%3D%3D%20%22tab%22%20%26%26%20aDragSession.sourceNode.parentNode%20!%3D%20this.mTabContainer)%0A%09%7B%0A%09%09aDragSession%20%3D%20%7B%20canDrop%3A%20aDragSession.canDrop%2C%20sourceNode%3A%20this.selectedTab%20%7D%3B%0A%09%7D%0A%09this.__preUC_onDragOver(aEvent%2C%20aFlavour%2C%20aDragSession)%3B%0A%7D%3B%0A">Drag'n'Duplicate</a> (allows to move tabs between windows and copy tabs through drag&drop; cf. Copy Dragged Tab) Convenient access to userChrome.js (for Firefox, Thunderbird and possibly others) <li><a href="data:text/javascript,var%20UserChromeJSEditor%20%3D%20%7B%0A%09init%3A%20function()%0A%09%7B%0A%09%09var%20menuitem%20%3D%20document.createElement(%22menuitem%22)%3B%0A%09%09menuitem.setAttribute(%22label%22%2C%20%22Edit%20userChrome.js%22)%3B%0A%09%09menuitem.setAttribute(%22accesskey%22%2C%20%22u%22)%3B%0A%09%09menuitem.setAttribute(%22oncommand%22%2C%20%22UserChromeJSEditor.open()%3B%22)%3B%0A%09%09%0A%09%09var%20optionsitem%20%3D%20document.getElementById(%22menu_preferences%22)%3B%0A%09%09optionsitem.parentNode.insertBefore(menuitem%2C%20optionsitem)%3B%0A%09%7D%2C%0A%0A%09open%3A%20function(aFileName%2C%20aAbsolutePath)%0A%09%7B%0A%09%09if%20(!aAbsolutePath)%0A%09%09%7B%0A%09%09%09var%20file%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%09%09file.append(aFileName%20%7C%7C%20%22userChrome.js%22)%3B%0A%09%09%7D%0A%09%09else%0A%09%09%7B%0A%09%09%09file%20%3D%20Components.classes%5B%22%40mozilla.org%2Ffile%2Flocal%3B1%22%5D.createInstance(Components.interfaces.nsILocalFile)%3B%0A%09%09%09file.initWithPath(aFilePath)%3B%0A%09%09%7D%0A%09%09%0A%09%09var%20info%20%3D%20Components.classes%5B%22%40mozilla.org%2Furiloader%2Fexternal-helper-app-service%3B1%22%5D.getService(Components.interfaces.nsIMIMEService).getFromTypeAndExtension(%22text%2Fplain%22%2C%20%22txt%22)%3B%0A%09%09try%0A%09%09%7B%0A%09%09%09var%20editorPath%20%3D%20gPrefService.getCharPref(%22extensions.userchrome_js.editor%22)%3B%0A%09%09%7D%0A%09%09catch%20(ex)%0A%09%09%7B%0A%09%09%09var%20nsIFilePicker%20%3D%20Components.interfaces.nsIFilePicker%3B%0A%09%09%09var%20filePicker%20%3D%20Components.classes%5B%22%40mozilla.org%2Ffilepicker%3B1%22%5D.createInstance(nsIFilePicker)%3B%0A%09%09%09%0A%09%09%09filePicker.init(window%2C%20%22Select%20userChrome.js%20editor%20path%22%2C%20nsIFilePicker.modeOpen)%3B%0A%09%09%09filePicker.appendFilters(nsIFilePicker.filterApps)%3B%0A%09%09%09%0A%09%09%09if%20(filePicker.show()%20!%3D%20nsIFilePicker.returnOK)%0A%09%09%09%7B%0A%09%09%09%09return%3B%0A%09%09%09%7D%0A%09%09%09%0A%09%09%09editorPath%20%3D%20filePicker.file.path%3B%0A%09%09%09gPrefService.setCharPref(%22extensions.userchrome_js.editor%22%2C%20editorPath)%3B%0A%09%09%7D%0A%09%09%0A%09%09try%0A%09%09%7B%0A%09%09%09var%20editor%20%3D%20Components.classes%5B%22%40mozilla.org%2Ffile%2Flocal%3B1%22%5D.createInstance(Components.interfaces.nsILocalFile)%3B%0A%09%09%09editor.initWithPath(editorPath)%3B%0A%09%09%09%0A%09%09%09info.preferredAction%20%3D%20info.useHelperApp%3B%0A%09%09%09info.preferredApplicationHandler%20%3D%20editor%3B%0A%09%09%09info.launchWithFile(file)%3B%0A%09%09%7D%0A%09%09catch%20(ex)%0A%09%09%7B%0A%09%09%09info.preferredAction%20%3D%20info.useSystemDefault%3B%0A%09%09%09info.launchWithFile(file)%3B%0A%09%09%7D%0A%09%7D%0A%7D%3B%0A%0AUserChromeJSEditor.init()%3B%0A">Tools menu entry to edit userChrome.js</a> <li><a href="data:text/javascript,(function()%20%7B%0A%09var%20menuitem%20%3D%20document.createElement(%22menuitem%22)%3B%0A%09menuitem.setAttribute(%22label%22%2C%20%22Open%20'chrome'%20Folder%22)%3B%0A%09menuitem.setAttribute(%22accesskey%22%2C%20%22h%22)%3B%0A%09menuitem.setAttribute(%22oncommand%22%2C%20'Components.classes%5B%22%40mozilla.org%2Ffile%2Fdirectory_service%3B1%22%5D.getService(Components.interfaces.nsIProperties).get(%22UChrm%22%2C%20Components.interfaces.nsILocalFile).launch()%3B')%3B%0A%09%0A%09var%20optionsitem%20%3D%20document.getElementById(%22menu_preferences%22)%3B%0A%09optionsitem.parentNode.insertBefore(menuitem%2C%20optionsitem)%3B%0A%7D)()%3B%0A">Tools menu entry to open the chrome folder</a> Snippets requiring other extensions (for Firefox 1.5) <li>Undo Close Tab tab context menu item (requires Crash Recovery) <li>Tab History for the context menu (requires Unified Back-/Forward Button) <li>Customize address completion for [Shift]+[Enter] Snippet collections by other authors <li>A growing collection of snippets by the author of the ScrapBook extension <li>Snippet collection from the MozillaZine Knowledge Base <li>Snippets collected from this thread by Pirlouy Revisions ~~ 0.8 (more info) ~~~~ <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:16 am, edited 38 times in total.
clever....
edit by moderator SKopischke: This topic is continued at http://forums.mozillazine.org/viewtopic.php?t=594331 Neat idea.
Out of curiosity, what's the difference between this and user.js? Works with Bon Echo also, at least Drag'n'go. Thanks.
(quick hack into Super DrangAndGo 2.4d1 didn't work.) Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8) Gecko/20060325 Firefox/2.0a1 - Build ID: 2006032506 nice, but is it somehow better then GreaseMonkey?
user.js just describes what preferences should be overwritten at start. It (and also prefs.js) may look like JavaScript files (and once were), but are plain configuration files now. In contrast, userChrome.js is mainly aimed at UI modifications (see the Code Samples section in the first post).
GreaseMonkey targets website content, while userChrome.js targets the browser chrome (i.e. GreaseMonkey is what userContent.js could have been). Have a look at the Code Samples section in the first post for an idea what this extension might be for. Needed:
A hack to edit userChrome.js from the Tools menu using editor of my choice.
but you can also use for website content - window.content~ - or not?
Added to the Code Samples section.
Sure you can - but GreaseMonkey does that much more comfortably.
for anyone who wants to differentiate between opening the target OR current tab/window ~line 20 this.mItem.setAttribute("oncommand", "LaunchIE.launch(" + ((gContextMenu.onLink)?"gContextMenu.linkURI":"gBrowser.currentURI") + ");"); ieLabel = (gContextMenu.onLink) ? "LaunchIE for Target" : "LaunchIE for Tab"; this.mItem.setAttribute("label", ieLabel); I gotta love this extension. Usually I use Contextmenu Extensions to execute custom scripts automatically at browser startup, but sometimes it doesn't work. Good work
Great, thanks. userChrome.css allows you to call other .css files using @import url.
Will userChrome.js allow calling other .js files in some manner? Also I'm thinking I might be able to make use of some of the scripts at http://userscripts.org/ Last edited by dougeeebear on March 26th, 2006, 12:23 pm, edited 1 time in total.
dougeebear, see the Sub-Script Loader sample script above. Return to Extension/Theme Releases Who is onlineUsers browsing this forum: _Dexter_ and 6 guests |
|