PK!>¶ÖI••chrome.manifestcontent InboxInfluence content/ overlay chrome://browser/content/browser.xul chrome://InboxInfluence/content/script-compiler-overlay.xul PK!>j! çQ Q content/prefman.jsfunction InboxInfluence_PrefManager() { var startPoint="InboxInfluence."; var pref=Components.classes["@mozilla.org/preferences-service;1"]. getService(Components.interfaces.nsIPrefService). getBranch(startPoint); var observers={}; // whether a preference exists this.exists=function(prefName) { return pref.getPrefType(prefName) != 0; } // returns the named preference, or defaultValue if it does not exist this.getValue=function(prefName, defaultValue) { var prefType=pref.getPrefType(prefName); // underlying preferences object throws an exception if pref doesn't exist if (prefType==pref.PREF_INVALID) { return defaultValue; } switch (prefType) { case pref.PREF_STRING: return pref.getCharPref(prefName); case pref.PREF_BOOL: return pref.getBoolPref(prefName); case pref.PREF_INT: return pref.getIntPref(prefName); } } // sets the named preference to the specified value. values must be strings, // booleans, or integers. this.setValue=function(prefName, value) { var prefType=typeof(value); switch (prefType) { case "string": case "boolean": break; case "number": if (value % 1 != 0) { throw new Error("Cannot set preference to non integral number"); } break; default: throw new Error("Cannot set preference with datatype: " + prefType); } // underlying preferences object throws an exception if new pref has a // different type than old one. i think we should not do this, so delete // old pref first if this is the case. if (this.exists(prefName) && prefType != typeof(this.getValue(prefName))) { this.remove(prefName); } // set new value using correct method switch (prefType) { case "string": pref.setCharPref(prefName, value); break; case "boolean": pref.setBoolPref(prefName, value); break; case "number": pref.setIntPref(prefName, Math.floor(value)); break; } } // deletes the named preference or subtree this.remove=function(prefName) { pref.deleteBranch(prefName); } // call a function whenever the named preference subtree changes this.watch=function(prefName, watcher) { // construct an observer var observer={ observe:function(subject, topic, prefName) { watcher(prefName); } }; // store the observer in case we need to remove it later observers[watcher]=observer; pref.QueryInterface(Components.interfaces.nsIPrefBranchInternal). addObserver(prefName, observer, false); } // stop watching this.unwatch=function(prefName, watcher) { if (observers[watcher]) { pref.QueryInterface(Components.interfaces.nsIPrefBranchInternal) .removeObserver(prefName, observers[watcher]); } } } PK!>yo„§§#content/script-compiler-overlay.xul PK!>fÒp» » content/script-compiler.jsvar InboxInfluence_gmCompiler={ // getUrlContents adapted from Greasemonkey Compiler // http://www.letitblog.com/code/python/greasemonkey.py.txt // used under GPL permission // // most everything else below based heavily off of Greasemonkey // http://greasemonkey.devjavu.com/ // used under GPL permission getUrlContents: function(aUrl){ var ioService=Components.classes["@mozilla.org/network/io-service;1"] .getService(Components.interfaces.nsIIOService); var scriptableStream=Components .classes["@mozilla.org/scriptableinputstream;1"] .getService(Components.interfaces.nsIScriptableInputStream); var unicodeConverter=Components .classes["@mozilla.org/intl/scriptableunicodeconverter"] .createInstance(Components.interfaces.nsIScriptableUnicodeConverter); unicodeConverter.charset="UTF-8"; var channel=ioService.newChannel(aUrl, "UTF-8", null); var input=channel.open(); scriptableStream.init(input); var str=scriptableStream.read(input.available()); scriptableStream.close(); input.close(); try { return unicodeConverter.ConvertToUnicode(str); } catch (e) { return str; } }, isGreasemonkeyable: function(url) { var scheme=Components.classes["@mozilla.org/network/io-service;1"] .getService(Components.interfaces.nsIIOService) .extractScheme(url); return ( (scheme == "http" || scheme == "https" || scheme == "file") && !/hiddenWindow\.html$/.test(url) ); }, contentLoad: function(e) { var unsafeWin=e.target.defaultView; if (unsafeWin.wrappedJSObject) unsafeWin=unsafeWin.wrappedJSObject; var unsafeLoc=new XPCNativeWrapper(unsafeWin, "location").location; var href=new XPCNativeWrapper(unsafeLoc, "href").href; if ( InboxInfluence_gmCompiler.isGreasemonkeyable(href) && ( /http:\/\/mail.google.com\/mail.*/.test(href) || /https:\/\/mail.google.com\/mail.*/.test(href) || /http:\/\/mail.google.com\/a\/.*/.test(href) || /https:\/\/mail.google.com\/a\/.*/.test(href) ) && true ) { var script=InboxInfluence_gmCompiler.getUrlContents( 'chrome://InboxInfluence/content/InboxInfluence.js' ); InboxInfluence_gmCompiler.injectScript(script, href, unsafeWin); } }, injectScript: function(script, url, unsafeContentWin) { var sandbox, script, logger, storage, xmlhttpRequester; var safeWin=new XPCNativeWrapper(unsafeContentWin); sandbox=new Components.utils.Sandbox(safeWin); var storage=new InboxInfluence_ScriptStorage(); xmlhttpRequester=new InboxInfluence_xmlhttpRequester( unsafeContentWin, window//appSvc.hiddenDOMWindow ); sandbox.window=safeWin; sandbox.document=sandbox.window.document; sandbox.unsafeWindow=unsafeContentWin; // patch missing properties on xpcnw sandbox.XPathResult=Components.interfaces.nsIDOMXPathResult; // add our own APIs sandbox.GM_addStyle=function(css) { InboxInfluence_gmCompiler.addStyle(sandbox.document, css) }; sandbox.GM_setValue=InboxInfluence_gmCompiler.hitch(storage, "setValue"); sandbox.GM_getValue=InboxInfluence_gmCompiler.hitch(storage, "getValue"); sandbox.GM_openInTab=InboxInfluence_gmCompiler.hitch(this, "openInTab", unsafeContentWin); sandbox.GM_xmlhttpRequest=InboxInfluence_gmCompiler.hitch( xmlhttpRequester, "contentStartRequest" ); //unsupported sandbox.GM_registerMenuCommand=function(){}; sandbox.GM_log=function(){}; sandbox.GM_getResourceURL=function(){}; sandbox.GM_getResourceText=function(){}; sandbox.__proto__=sandbox.window; try { this.evalInSandbox( "(function(){"+script+"})()", url, sandbox); } catch (e) { var e2=new Error(typeof e=="string" ? e : e.message); e2.fileName=script.filename; e2.lineNumber=0; //GM_logError(e2); alert(e2); } }, evalInSandbox: function(code, codebase, sandbox) { if (Components.utils && Components.utils.Sandbox) { // DP beta+ Components.utils.evalInSandbox(code, sandbox); } else if (Components.utils && Components.utils.evalInSandbox) { // DP alphas Components.utils.evalInSandbox(code, codebase, sandbox); } else if (Sandbox) { // 1.0.x evalInSandbox(code, sandbox, codebase); } else { throw new Error("Could not create sandbox."); } }, openInTab: function(unsafeContentWin, url) { var tabBrowser = getBrowser(), browser, isMyWindow = false; for (var i = 0; browser = tabBrowser.browsers[i]; i++) if (browser.contentWindow == unsafeContentWin) { isMyWindow = true; break; } if (!isMyWindow) return; var loadInBackground, sendReferrer, referrer = null; loadInBackground = tabBrowser.mPrefs.getBoolPref("browser.tabs.loadInBackground"); sendReferrer = tabBrowser.mPrefs.getIntPref("network.http.sendRefererHeader"); if (sendReferrer) { var ios = Components.classes["@mozilla.org/network/io-service;1"] .getService(Components.interfaces.nsIIOService); referrer = ios.newURI(content.document.location.href, null, null); } tabBrowser.loadOneTab(url, referrer, null, null, loadInBackground); }, hitch: function(obj, meth) { var unsafeTop = new XPCNativeWrapper(unsafeContentWin, "top").top; for (var i = 0; i < this.browserWindows.length; i++) { this.browserWindows[i].openInTab(unsafeTop, url); } }, apiLeakCheck: function(allowedCaller) { var stack=Components.stack; var leaked=false; do { if (2==stack.language) { if ('chrome'!=stack.filename.substr(0, 6) && allowedCaller!=stack.filename ) { leaked=true; break; } } stack=stack.caller; } while (stack); return leaked; }, hitch: function(obj, meth) { if (!obj[meth]) { throw "method '" + meth + "' does not exist on object '" + obj + "'"; } var hitchCaller=Components.stack.caller.filename; var staticArgs = Array.prototype.splice.call(arguments, 2, arguments.length); return function() { if (InboxInfluence_gmCompiler.apiLeakCheck(hitchCaller)) { return; } // make a copy of staticArgs (don't modify it because it gets reused for // every invocation). var args = staticArgs.concat(); // add all the new arguments for (var i = 0; i < arguments.length; i++) { args.push(arguments[i]); } // invoke the original function with the correct this obj and the combined // list of static and dynamic arguments. return obj[meth].apply(obj, args); }; }, addStyle:function(doc, css) { var head, style; head = doc.getElementsByTagName('head')[0]; if (!head) { return; } style = doc.createElement('style'); style.type = 'text/css'; style.innerHTML = css; head.appendChild(style); }, onLoad: function() { var appcontent=window.document.getElementById("appcontent"); if (appcontent && !appcontent.greased_InboxInfluence_gmCompiler) { appcontent.greased_InboxInfluence_gmCompiler=true; appcontent.addEventListener("DOMContentLoaded", InboxInfluence_gmCompiler.contentLoad, false); } }, onUnLoad: function() { //remove now unnecessary listeners window.removeEventListener('load', InboxInfluence_gmCompiler.onLoad, false); window.removeEventListener('unload', InboxInfluence_gmCompiler.onUnLoad, false); window.document.getElementById("appcontent") .removeEventListener("DOMContentLoaded", InboxInfluence_gmCompiler.contentLoad, false); }, }; //object InboxInfluence_gmCompiler function InboxInfluence_ScriptStorage() { this.prefMan=new InboxInfluence_PrefManager(); } InboxInfluence_ScriptStorage.prototype.setValue = function(name, val) { this.prefMan.setValue(name, val); } InboxInfluence_ScriptStorage.prototype.getValue = function(name, defVal) { return this.prefMan.getValue(name, defVal); } window.addEventListener('load', InboxInfluence_gmCompiler.onLoad, false); window.addEventListener('unload', InboxInfluence_gmCompiler.onUnLoad, false); PK!> úÙõ¡¡content/xmlhttprequester.jsfunction InboxInfluence_xmlhttpRequester(unsafeContentWin, chromeWindow) { this.unsafeContentWin = unsafeContentWin; this.chromeWindow = chromeWindow; } // this function gets called by user scripts in content security scope to // start a cross-domain xmlhttp request. // // details should look like: // {method,url,onload,onerror,onreadystatechange,headers,data} // headers should be in the form {name:value,name:value,etc} // can't support mimetype because i think it's only used for forcing // text/xml and we can't support that InboxInfluence_xmlhttpRequester.prototype.contentStartRequest = function(details) { // important to store this locally so that content cannot trick us up with // a fancy getter that checks the number of times it has been accessed, // returning a dangerous URL the time that we actually use it. var url = details.url; // make sure that we have an actual string so that we can't be fooled with // tricky toString() implementations. if (typeof url != "string") { throw new Error("Invalid url: url must be of type string"); } var ioService=Components.classes["@mozilla.org/network/io-service;1"] .getService(Components.interfaces.nsIIOService); var scheme = ioService.extractScheme(url); // This is important - without it, GM_xmlhttpRequest can be used to get // access to things like files and chrome. Careful. switch (scheme) { case "http": case "https": case "ftp": this.chromeWindow.setTimeout( InboxInfluence_gmCompiler.hitch(this, "chromeStartRequest", url, details), 0); break; default: throw new Error("Invalid url: " + url); } } // this function is intended to be called in chrome's security context, so // that it can access other domains without security warning InboxInfluence_xmlhttpRequester.prototype.chromeStartRequest=function(safeUrl, details) { var req = new this.chromeWindow.XMLHttpRequest(); this.setupRequestEvent(this.unsafeContentWin, req, "onload", details); this.setupRequestEvent(this.unsafeContentWin, req, "onerror", details); this.setupRequestEvent(this.unsafeContentWin, req, "onreadystatechange", details); req.open(details.method, safeUrl); if (details.headers) { for (var prop in details.headers) { req.setRequestHeader(prop, details.headers[prop]); } } req.send(details.data); } // arranges for the specified 'event' on xmlhttprequest 'req' to call the // method by the same name which is a property of 'details' in the content // window's security context. InboxInfluence_xmlhttpRequester.prototype.setupRequestEvent = function(unsafeContentWin, req, event, details) { if (details[event]) { req[event] = function() { var responseState = { // can't support responseXML because security won't // let the browser call properties on it responseText:req.responseText, readyState:req.readyState, responseHeaders:(req.readyState==4?req.getAllResponseHeaders():''), status:(req.readyState==4?req.status:0), statusText:(req.readyState==4?req.statusText:'') } // Pop back onto browser thread and call event handler. // Have to use nested function here instead of GM_hitch because // otherwise details[event].apply can point to window.setTimeout, which // can be abused to get increased priveledges. new XPCNativeWrapper(unsafeContentWin, "setTimeout()") .setTimeout(function(){details[event](responseState);}, 0); } } } PK!>‰R©e‚‚ install.rdf oxtail@sunlightfoundation.com Inbox Influence 0.4.4 Sunlight Foundation's Gmail extension to add political influence information to your inbox. Sunlight user script compiler, adapted from Greasemonkey Compiler by Anthony Lieuallen http://arantius.com/ https://inbox.influenceexplorer.com https://inbox.influenceexplorer.com/update.rdf MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC0g1J8cDferyxJWrsjZGPu0lgs16p1vBNMgtU5u8A4EQJzU0YX8B2elVjsWSoPBlKPgYepWWaDjMWhanLj/tK3T/b7lnR3p781jH4be9bBQ1+AJZ1GXnm+zRxKxN5HbepmJqnmDL0FpZ+aPhIaGmqPWRt7lQeXMXZjmOdzuI2sVwIDAQAB {ec8030f7-c20a-464f-9b0e-13a3a9e97384} 1.5 12.0.* PK!>Û% Å Å content/InboxInfluence.jsvar doc = document; var oxtailInterval = setInterval(function() { var frame = doc.getElementById('canvas_frame'); if (frame && frame.contentDocument) { var document = frame.contentDocument; if (document.getElementsByClassName('w-as0').length) { clearInterval(oxtailInterval); var submit = document.getElementById('oxtail-submit'); if (!submit) { var searchTable = document.querySelectorAll('.no .nn .oy8Mbf')[0]; var userArea = document.createElement('td'); searchTable.childNodes[0].appendChild(userArea); userArea.innerHTML = userArea.innerHTML + ''; } var loader = document.createElement('script'); loader.setAttribute('type', 'text/javascript'); loader.src = 'data:text/javascript;charset=utf-8,' + encodeURIComponent("var submit \u003D document.getElementById(\u0027oxtail\u002Dsubmit\u0027)\u003B\u000Aif (submit) {\u000A var initialOffset \u003D window.globalStorage \u003D\u003D\u003D undefined ? 0 : \u002D17\u003B\u000A var submitImg \u003D document.getElementById(\u0027oxtail\u002Dsubmit\u002Dimg\u0027)\u003B\u000A \u000A submitImg.style.top \u003D initialOffset + \u0027px\u0027\u003B\u000A \u000A submit.onmouseover \u003D function() {\u000A submitImg.style.clip \u003D \u0027rect(34px,166px,68px,0px)\u0027\u003B\u000A submitImg.style.top \u003D (initialOffset \u002D 34) + \u0027px\u0027\u003B\u000A }\u003B\u000A submit.onmouseout \u003D function() {\u000A submitImg.style.clip \u003D \u0027rect(0px,166px,34px,0px)\u0027\u003B\u000A submitImg.style.top \u003D initialOffset + \u0027px\u0027\u003B\u000A }\u003B\u000A \u000A submit.onclick \u003D (function() {\u000A if (window.poligraftParser) {\u000A window.poligraftParser.fetchData()\u003B\u000A } else {\u000A var s \u003D document.createElement(\u0027script\u0027)\u003B\u000A s.setAttribute(\u0027src\u0027, \u0027https://inbox.influenceexplorer.com/oxtail.js\u0027)\u003B\u000A s.setAttribute(\u0027type\u0027, \u0027text/javascript\u0027)\u003B\u000A submit.parentNode.appendChild(s)\u003B\u000A document.defaultView.window.poligraftEnabled \u003D true\u003B\u000A }\u000A })\u003B\u000A submit.removeAttribute(\u0027disabled\u0027)\u003B\u000A}\u000A\u000Aif (window.poligraftParser) {\u000A window.poligraftParser.loadPage()\u003B\u000A}\u000A"); document.getElementsByTagName('head')[0].appendChild(loader); } } }, 250); PK!>¶ÖI••chrome.manifestPK!>j! çQ Q Âcontent/prefman.jsPK!>yo„§§#C content/script-compiler-overlay.xulPK!>fÒp» » +content/script-compiler.jsPK!> úÙõ¡¡0content/xmlhttprequester.jsPK!>‰R©e‚‚ ø>install.rdfPK!>Û% Å Å £Dcontent/InboxInfluence.jsPKߟP