From 0d9d26df9c01b026f3d8ca986799c6050ee9474f Mon Sep 17 00:00:00 2001 From: teramako Date: Sun, 6 Apr 2008 23:17:00 +0000 Subject: lang/javascript/vimperator-plugins/trunk/gmperator.js : めまぐるしく進化中... gmloadが動かなかったのを修正。 プラグイン開発者用にGreasemonkeyのsandboxにアクセスできるように変更。 gmloadですでにロードされている場合はエラーとし、代わりにgmload!で強制ロードとした。 gmlistの表示を改善。 git-svn-id: http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk@9038 d0d07461-0603-4401-acd4-de1884942a52 --- gmperator.js | 295 +++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 245 insertions(+), 50 deletions(-) (limited to 'gmperator.js') diff --git a/gmperator.js b/gmperator.js index e9d4821..a251576 100644 --- a/gmperator.js +++ b/gmperator.js @@ -2,9 +2,12 @@ * gmperator - vimperator plugin for Greasemonkey * For vimperator 0.6pre * @author teramako teramako@gmail.com - * @version 0.2a + * @version 0.3a * + * --------------------------- * Usage: + * --------------------------- + * {{{ * * :gmli[st] {filter} -> show user scripts matches {filter} * :gmli[st]! -> show all user scripts @@ -13,6 +16,7 @@ * :gmlo[ad] {name|filename} -> load the user script to the current page * but, don't dispatch load event * so maybe you should edit the scripts before load + * :gmlo[ad]! {name|filename} -> force load the user script * * :gmset! -> toggle enable/disable greasemonkey * :gmset! {filename} -> toogle enable/disable the script @@ -32,9 +36,158 @@ * name to "fooScriptName", * includes to "http://*" and "https://*", * and excludes to "http://example.com/*" + * + * }}} + * --------------------------- + * For plugin developer: + * --------------------------- + * {{{ + * + * 1). can access to the sandbox of Greasemonkey !!! + * 2). can register commands which execute + * when the user script is executed on the URI + * @see liberator.plugins.gmperator.addAutoCommand + * + * liberator.plugins.gmperator => ( + * allItem : return object of key : {panalID}, + * value : {GmContainer} + * {panelID} => @see gBrowser.mTags[].linkedPanel + * currentPanel + * currentContainer : return the current {GmContainer} object + * currentSandbox : return the current sandbox object + * gmScripts : return array of {userScripts} + * {userScripts} => ( + * filename : {String} + * name : {String} + * namespace : {String} + * description: {String} + * enabled : {Boolean} + * includes : {String[]} + * encludes : {String[]} + * ) + * addAutoCommand : function( uri, script, cmd ) + * If both of uri and script is match + * + * ) + * }}} */ (function(){ -commands.addUserCommand(['gmli[st]','lsgm'], 'list Greasemonkey scripts', + +const Cc = Components.classes; +const Ci = Components.interfaces; +const gmID = '@greasemonkey.mozdev.org/greasemonkey-service;1'; +if (!Cc[gmID]) { + log('Greasemonkey is not installed'); + return; +} +if(!liberator.plugins) liberator.plugins = {}; + + +liberator.plugins.gmperator = (function(){ //{{{ + // ----------------------- + // PUBLIC section + // ----------------------- + // {{{ + var manager = { + register: function (uri,sandbox,script){ + var panelID = getPanelID(sandbox.window); + var gmCon; + if (containers[panelID]){ + gmCon = containers[panelID]; + } else { + gmCon = new GmContainer(uri,sandbox); + containers[panelID] = gmCon; + this.__defineGetter__(panelID,function(){return gmCon;}); + log('gmpeartor: redisted: '+ panelID + ' - ' + uri); + } + gmCon.sandbox = sandbox; + gmCon.addScript(script); + gmCon.uri = uri; + autocommands.trigger('GMInjectedScript',uri+'\n'+script.filename); + }, + get gmScripts(){ + return getScripts(); + }, + get allItem(){ + return containers; + }, + get currentPanel(){ + return getBrowser().mCurrentTab.linkedPanel; + }, + get currentContainer(){ + return containers[this.currentPanel] || null; + }, + get currentSandbox(){ + var id = this.currentPanel; + return containers[id] ? containers[id].sandbox : null; + }, + getSandboxFromWindow: function(win){ + for each(var c in containers){ + if(c.sandbox.window === win) return sandbox; + } + return null; + }, + getContainersFromURI: function(uri){ + var list = []; + for each(var c in containers){ + if (c.uri == uri) list.push(c); + } + return list.length > 0 ? list : null; + }, + addAutoCommand: function(uri, script, cmd){ + var reg = uri+'.*\n'+script+'\.user\.js'; + autocommands.add('GMInjectedScript', reg, cmd); + }, + removeAutoCommand: function(uri, script){ + var reg = uri+'.*\n'+script+'\.user\.js'; + autocommands.remove('GMInjectedScript', reg); + }, + }; + // }}} + // ----------------------- + // PRIVATE section + // ----------------------- + // {{{ + var containers = {}; + var gmSvc = Cc[gmID].getService().wrappedJSObject; + + function appendCode(target,name,func){ + var original = target[name]; + target[name] = function(){ + var tmp = original.apply(target,arguments); + func.apply(this,arguments); + return tmp; + }; + } + appendCode(gmSvc, 'evalInSandbox', function(code,uri,sandbox,script){ + liberator.plugins.gmperator.register(uri,sandbox,script); + }); + function getPanelID(win){ + var tabs = getBrowser().mTabs; + for (var i=0; tabs.length; i++){ + var tab = tabs.item(i); + if (tab.linkedBrowser.contentWindow == win){ + return tab.linkedPanel; + } + } + liberator.log(win + 'is no found'); + } + function updateGmContainerList(e){ + var t = e.target; + if (t && t.localName == 'tab' && t.linkedPanel){ + delete containers[t.linkedPanel]; + delete plugins.gmperator[t.linkedPanel]; + } + } + getBrowser().mTabContainer.addEventListener('TabClose',updateGmContainerList,false); + // }}} + return manager; +})(); //}}} + +// --------------------------- +// User Command +// --------------------------- +commands.addUserCommand(['gmli[st]','lsgm'], 'list Greasemonkey scripts', //{{{ function(arg,special){ var str = ''; var scripts = getScripts(); @@ -45,40 +198,49 @@ commands.addUserCommand(['gmli[st]','lsgm'], 'list Greasemonkey scripts', reg = new RegExp(arg,'i'); } if (reg){ - for (var i=0; i' + str = ''; + for each(var s in scripts){ + if (s.enabled){ + str += '' } else { - str += scripts[i].name; + str += ''; } - str += ' (' + scripts[i].filename + ')\n' + str += '' } + str += '
'+ s.name + '
' + s.name + '(' + s.filename + ')
'; } - echo(str); + echo(str,true); function scriptToString(script){ + var thTag = ''; + var rs = '' + thTag; + var re = ''; + var sep = ''; return [ - '' + script.name + '::', - 'fileName: ' + script.filename, - 'nameSpace: ' + script.namespace, - 'description: ' + script.description, - 'includes:', - ' ' + script.includes.join('\n '), - 'excludes:', - ' ' + script.excludes.join('\n '), - 'enabled: ' + script.enabled - ].join('\n'); + '', + '', + rs, 'FileName', sep, script.filename, re, + rs, 'NameSpace', sep, script.namespace, re, + rs, 'Description', sep, script.description, re, + rs, 'Includes', sep, script.includes.join('
'), re, + rs, 'Excludes', sep, script.excludes.join('
'), re, + rs, 'Enabled', sep, script.enabled, re, + '
', script.name, '
' + ].join(''); } } -); -commands.addUserCommand(['gmlo[ad]'], 'load Greasemonkey script', - function(arg){ - if (!arg) return; +); //}}} +commands.addUserCommand(['gmlo[ad]'], 'load Greasemonkey script', //{{{ + function(arg, special){ + if (!arg) { + echoerr('Usage: :gmlo[ad][!] {name|filename}'); + return; + } var scripts = getScripts(); var script; for (var i=0; i 0){ - script.name = liberator.commands.getOption(res.opts, '-name', script.name); - script.includes = liberator.commands.getOption(res.opts, '-include', script.includes); - script.excludes = liberator.commands.getOption(res.opts, '-exclude', script.excludes); + script.name = commands.getOption(res.opts, '-name', script.name); + script.includes = commands.getOption(res.opts, '-include', script.includes); + script.excludes = commands.getOption(res.opts, '-exclude', script.excludes); } config.save(); },{ args: [ - [['-name','-n'], liberator.commands.OPTION_STRING], - [['-include','-i'], liberator.commands.OPTION_LIST], - [['-exclude','-e'], liberator.commands.OPTION_LIST] + [['-name','-n'], commands.OPTION_STRING], + [['-include','-i'], commands.OPTION_LIST], + [['-exclude','-e'], commands.OPTION_LIST] ], shortHelp: 'change setting a greasemonkey script', help: [ @@ -160,36 +325,66 @@ commands.addUserCommand(['gmset'], 'change setting a greasemonkey script', return scriptsCompleter(filter, false); } } -); -function getScripts(){ +); //}}} + +// --------------------------- +// Utils +// --------------------------- +/** Grasemonkey sandbox container {{{ + * @param {String} uri + * @param {Sandbox} sandbox + * @param {Array} scripts + */ +function GmContainer(uri,sandbox){ + this.uri = uri; + this.sandbox = sandbox; + this.scripts = []; +} +GmContainer.prototype = { + addScript : function(script){ + if (this.hasScript(script)) return false; + + return this.scripts.push(script); + }, + hasScript : function(script){ + var filename; + switch( typeof(script) ){ + case 'object': filename = script.filename; break; + case 'string': filename = script; break; + default: return null; + } + return this.scripts.some(function(s){ return s.filename == filename; }); + } +} // }}} +function getScripts(){ //{{{ var config = new Config(); config.load(); return config.scripts; -} -function scriptsCompleter(filter,flag){ +} //}}} +function scriptsCompleter(filter,flag){ //{{{ var candidates = []; var scripts = getScripts(); var isAll = false; if (!filter) isAll=true; if (flag){ - for (var i=0; i