// // Copyright (c) 2012 Stefan Bolte // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // /* * TODO not finished yet * * userscripts extension, load userscripts and injects them into websites, this * extension is mostly greasemonkey compatible. Scripts can be loaded by either * specifying a path with using the configuration or putting them into * $XDG_CONFIG_HOME/dwb/scripts/. * * * To use this extension load it with a userscript in * $HOME/.config/dwb/userscripts/, e.g. * * ------------------------------------------------------------------------------ * |#!javascript | * | | * |extensions.load("userscripts"); | * ------------------------------------------------------------------------------ * * * Config: An array of paths to userscripts * * Example (loading with extensions load): * * ------------------------------------------------------------------------------ * |extensions.load("userscripts", [ "/path/to/script1", "/path/to/script2" ]); | | * ------------------------------------------------------------------------------ * * Example (extensionsrc): * * ------------------------------------------------------------------------------ * |return { | * | ... : { ... }, // other config objects | * | | * | userscripts : [ "/path/to/script1", "/path/to/script2" ], | * | | * | ... : { ... } // other config objects | * |} | * ------------------------------------------------------------------------------ * * */ var me = "userscripts"; var onStart = []; var onEnd = []; var sigDocument = -1; var sigCommitted = -1; /* //DEFAULT_CONFIG */ var metaData = {}; const DATA_DIR = data.userDataDir + "/extension_data/userscripts/resources"; const META_DATA = DATA_DIR + "/.metadata"; UserScript.prototype = new Function(); UserScript.prototype.constructor = UserScript; function UserScript() { this.description = null; this.downloadURL = null; this.exclude = []; this.icon = null; this.include = []; this.match = []; this.name = null; this.namespace = null; this.require = []; this.resource = []; this.runAt = "document-end"; this.unwrap = false; this.updateURL = null; this.version = null; this.script = null; this.scriptId = null; // scriptish this.delay = 0; this.noframes = false; this.priority = 0; } // Reused regular expressions var regexes = { isTld : /\.tld(?:\/|:|$)/, isRegExp : /^\/.*\/$/ }; var GM_compatability = function () { var DWB_scriptPrefix = "dwb_userscript_"; if (DWB_scriptId !== undefined) { DWB_scriptPrefix = DWB_scriptPrefix + DWB_scriptId + "_"; } var GM_addStyle = function (styles) { var style = document.createElement("style"); style.setAttribute("type", "text/css"); style.appendChild(document.createTextNode(styles)); document.getElementsByTagName("head")[0].appendChild(style); }; var GM_log = function (text) { console.log(text); }; var GM_setValue = function (key, value) { if (localStorage !== null && (typeof value === "string" || typeof value === "number" || typeof value == "boolean") ) localStorage.setItem(DWB_scriptPrefix + key, value); else GM_log("GM_setValue only works with enabled localStorage and only for strings, numbers and booleans"); }; var GM_getValue = function (key, def) { if (localStorage !== null) return localStorage.getItem(DWB_scriptPrefix + key) || def; else GM_log("GM_getValue only works with enabled localStorage"); return undefined; }; var GM_deleteValue = function (key) { if (localStorage !== null) localStorage.removeItem(DWB_scriptPrefix + key); else GM_log("GM_deleteValue only works with enabled localStorage"); }; var GM_listValues = function () { var i; var a = []; for (i=0; i 0) { timerStart(item.delay, function() { frame.inject(item.script, item.unwrap); return false; }); } else { frame.inject(item.script, item.unwrap); } } function handle(frame, array, isMainFrame) //{{{ { var i, item; for (i=0; i") { return { allUrls : true }; } var o = uriSplit(m); if (o === null) { extensions.warning(me, "Invalid or unsupported match rule: " + m); return null; } if (!(/\*|http|https|file/.test(o.scheme))) { extensions.warning(me, "Invalid scheme pattern: " + m); return null; } else { o.scheme = new RegExp(o.scheme.replace("*", ".*")); } if (! (/^(?:\*\.[^*\/]*|[^*]*|\*)$/.test(o.host))) { extensions.warning(me, "Invalid host pattern: " + m); return null; } else { o.host = new RegExp(o.host.replace(/([.?+^$[\]\\(){}|-])/g, "\\$1").replace("*", ".*")); } if (! (/^\/.*/.test(o.path))) { extensions.warning(me, "Invalid path pattern: " + m); return null; } else if (o.path !== null) { o.path = new RegExp(o.path.replace(/([.?+^$[\]\\(){}|-])/g, "\\$1").replace("*", ".*")); } return { host : o.host, scheme : o.scheme, path : o.path, allUrls : false }; } function getRequirements(userscript) {//{{{ var i; for (i=0; i= 0 ? meta[i].substring(idx+1).trim() : null; if (key == "description" || key == "downloadURL" || key == "icon" || key == "name" || key == "namespace" || key == "updateURL" || key == "version") { userscript[key] = value; } else if (typeof userscript[key] == "number") { try { numVal = parseInt(value, 10); if (!isNaN(numVal)) userscript[key] = numVal; } catch (e) { extensions.debug(me, e); } } else if (key == "unwrap") userscript.unwrap = true; else if (key == "noframes") userscript.noframes = true; else if (key == "run-at") userscript.runAt = value; else if (userscript[key] instanceof Array) { userscript[key] = userscript[key].concat(value.match(/\S+/g)); } } catch(e) { extensions.debug(me, e); } } if (userscript.include.length === 0) userscript.include.push({regExp : /.*/, isTld : false}); else parseIncludeExclude(userscript.include); parseIncludeExclude(userscript.exclude); // TODO resources var scriptId = new String(); if (userscript.namespace === null || userscript.name === null) userscript.scriptId = path; else userscript.scriptId = userscript.namespace + "::" + userscript.name; userscript.scriptId = userscript.scriptId.replace(/\s+/g, "_"); userscript.script = "var DWB_scriptId = '" + userscript.scriptId + "';" + util.getBody(GM_compatability) + script.substring(0, metaStart) + script.substring(scriptStart); getRequirements(userscript); for (i=0; i 0) { onStart.sort(function(a, b) { return b.priority - a.priority; }); sigCommitted = signals.connect("loadCommitted", loadCommittedCallback); ret = true; } if (onEnd.length > 0) { onEnd.sort(function(a, b) { return b.priority - a.priority; }); sigDocument = signals.connect("documentLoaded", loadFinishedCallback); ret = true; } //metaData = {}; //onStart.concat(onEnd).forEach(function (v, k, obj) { // var o = { // require : obj[k].require, // downloadURL : obj[k].downloadURL, // updateURL : obj[k].updateURL, // version : obj[k].version, // resource : obj[k].resource // }; // metaData[obj[k].scriptId] = o; //}); //io.write(META_DATA, "w", JSON.stringify(metaData)); return ret; } function parseScripts(scripts) //{{{ { var i, path; var scriptDir = data.configDir + "/scripts"; for (i=0; i= 0) { signals.disconnect(sigDocument); sigDocument = -1; } if (sigCommitted >= 0) { signals.disconnect(sigCommitted); sigCommitted = -1; } } }; // vim: set ft=javascript: