/* :::::::: Sub-Script/Overlay Loader v3.0 ::::::::::::::: */ // automatically includes all files ending in .uc.xul and .uc.js from the profile's chrome folder // New Features: // supports Greasemonkey-style metadata for userChrome scripts and 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 //if (location.href != "chrome://browser/content/browser.xul") throw "stop"; var userChrome = {js: {}}; (function() { // URL of the main browser window; var mainWindowURL = "chrome://browser/content/browser.xul"; var chromeDir = Components.classes["@mozilla.org/file/directory_service;1"] .getService(Components.interfaces.nsIProperties) .get("UChrm", Components.interfaces.nsILocalFile); var files = chromeDir.directoryEntries.QueryInterface(Components.interfaces.nsISimpleEnumerator); var filepathhandler = Components.classes["@mozilla.org/network/io-service;1"] .getService(Components.interfaces.nsIIOService).getProtocolHandler("file") .QueryInterface(Components.interfaces.nsIFileProtocolHandler); var istream = Components.classes["@mozilla.org/network/file-input-stream;1"] .createInstance(Components.interfaces.nsIFileInputStream); userChrome.js.scripts = []; userChrome.js.overlays = []; (function loadFiles() { if(!files.hasMoreElements()) return; var file = files.getNext().QueryInterface(Components.interfaces.nsIFile); if(/\.uc\.(js|xul)$|^userChrome\.xul$/i.test(file.leafName)) { // This code is adapted/simplified from Greasemonkey's scriptdownloader.js and convert2RegExp.js var script = { filename: file.leafName, name: file.leafName, namespace: "", description: "", includes: [], excludes: [] }; // read the file line by line var line = {}, foundMeta = false, match = null; istream.init(file, 0x01, 0444, 0); istream.QueryInterface(Components.interfaces.nsILineInputStream); while(istream.readLine(line)) { if(!foundMeta && line.value.indexOf("// ==UserScript==") == 0) { foundMeta = true; } else if(foundMeta && (match = line.value.match(/\/\/ \@(\S+)\s+([^\n]+)/))) switch(match[1]) { case "name" : case "namespace" : case "description" : script[match[1]] = match[2]; break; case "include" : case "exclude" : script[match[1] + "s"].push(match[2] == "main" ? mainWindowURL : match[2]); break; } else if(foundMeta && line.value.indexOf("// ==/UserScript==") == 0) { break; } } istream.close(); // make scripts without metadata run in the main window if(!script.includes.length) script.includes.push(mainWindowURL); // decide whether to run the script var i, run = false, list; for(i = 0, list = script.includes; i < list.length; i++) if(checkURL(list[i])) { run = true; break; } for(i = 0, list = script.excludes; i < list.length; i++) if(checkURL(list[i])) { run = false; break; } if(run) { if(/\.js$/.test(script.filename)) { Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader) .loadSubScript(filepathhandler.getURLSpecFromFile(file)); userChrome.js.scripts.push(script); } else { document.loadOverlay(filepathhandler.getURLSpecFromFile(file), null); userChrome.js.overlays.push(script); } } } setTimeout(loadFiles, 0); })(); // check url for match function checkURL(url) { return url == "*" || url[0] == "/" && eval(url.replace(/^\/\*/, "\/\/")).test(location.href) || convert2RegExp(url).test(location.href); } // Converts a pattern in this programs simple notation to a regular expression. // thanks AdBlock! http://www.mozdev.org/source/browse/adblock/adblock/ function convert2RegExp( pattern ) { var s = new String(pattern); var res = new String("^"); for (var i = 0 ; i < s.length ; i++) { switch(s[i]) { case '*' : res += ".*"; break; case '.' : case '?' : case '^' : case '$' : case '+' : case '{' : case '[' : case '|' : case '(' : case ')' : case ']' : res += "\\" + s[i]; break; case '\\' : res += "\\\\"; break; case ' ' : // Remove spaces from URLs. break; default : res += s[i]; break; } } // fortunately, we don't need .tld in chrome :) return new RegExp(res + '$', "i"); } })();