aboutsummaryrefslogtreecommitdiffstats
path: root/applauncher.js
blob: ae28700bf9e2fe5256db9563588047bbe1d22bf0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
var PLUGIN_INFO =
<VimperatorPlugin>
  <name>AppLauncher</name>
  <name lang='ja'>アプリケーションランチャー</name>
  <description>Launch defined application</description>
  <description lang='ja'>アプリケーションを起動します</description>
  <version>0.12</version>
  <author>pekepeke</author>
  <minVersion>2.0pre</minVersion>
  <maxVersion>2.0pre</maxVersion>
  <updateURL>http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk/applauncher.js</updateURL>
  <detail lang='ja'><![CDATA[
  == Commands ==
    :applaunch [name]:
    :runapp [name]:
      [name] で指定されたアプリケーションを起動します
  == .vimperatorrc example ==
    >||
    js <<EOM
    liberator.globalVariables.applauncher_list = [
      [ 'name', 'application path', ['arguments', '%URL%', '%SEL%']],
      [ 'Internet Explorer', 'C:\\Program Files\\Internet Explorer\\iexplore.exe', '%URL%'],
      [ 'Internet Explorer(Search)', 'C:\\Program Files\\Internet Explorer\\iexplore.exe', '%SEL%'],
    ];
    liberator.globalVariables.applauncher_charset = 'Shift_JIS';
    EOM
    ||<
    %URL% は実行時に選択中のリンクURLもしくは開いているページのURLに置き換えられます
    %SEL% は選択中の文字列に置き換えられます
    %TITLE% はページのタイトルに置き換えられます
    引数を複数指定する場合は配列形式で指定してください
    applauncher_charset を指定すると渡される文字列が指定の文字セットに変換されます
  ]]></detail>
</VimperatorPlugin>

liberator.plugins.AppLauncher = (function(){
  const UConv = Cc['@mozilla.org/intl/scriptableunicodeconverter'].getService(Ci.nsIScriptableUnicodeConverter);
  const AppName = 'AppLauncher';

  var global = liberator.globalVariables;
  var settings = global.applauncher_list || [];
  var defaultCharset = global.applauncher_charset;
  if (!settings || settings.length <= 0) return;
  var completer = settings.map( function([name, app, args]) [name, args ? app + ' ' + args.toString(): app] );

  var Class = function() function(){ this.initialize.apply(this, arguments); };
  var AppLauncher = new Class();

  AppLauncher.prototype = {
    initialize: function(){
      this.buildMenu();
      this.registerCommand();
    },
    registerCommand: function(){
      var self = this;
      commands.addUserCommand(['applaunch', 'runapp'], 'Run Defined Application',
        function(arg){
          arg = (typeof arg.string == 'undefined' ? arg : arg.string);
          self.launch(arg);
        }, {
          completer: function( context, arg, special){
            var filter = context.filter;
            context.title = [ 'Name', 'Description'];
            if (!filter){
              context.completions = completer;
              return;
            }
            filter = filter.toLowerCase();
            context.completions = completer.filter( function(el) el[0].toLowerCase().indexOf(filter) == 0);
          }
        });
    },
    buildMenu: function(){
      var self = this;
      var menu = document.getElementById('contentAreaContextMenu')
                         .appendChild(document.createElement('menu'));
      menu.setAttribute('id', AppName + 'Context');
      menu.setAttribute('label', AppName);
      menu.setAttribute('accesskey', 'L');

      var menupopup = menu.appendChild(document.createElement('menupopup'));
      menupopup.setAttribute('id', AppName + 'ContextMenu');
      for (let i=0, l=settings.length; i<l; i++){
        let [name, app, args] = settings[i];
        let menuitem = menupopup.appendChild(document.createElement('menuitem'));
        menuitem.setAttribute('id', AppName + i);
        menuitem.setAttribute('label', name + '\u3092\u8D77\u52D5');
        menuitem.addEventListener('command', function() self.launch(name), false);
      }
    },
    variables: {
      __noSuchMethod__: function(name) name,
      URL: function() gContextMenu && gContextMenu.onLink ? gContextMenu.getLinkURL() : buffer.URL,
      SEL: function(){
        var selection = window.content.window.getSelection();
        var sel = '';
        for (let i=0, l=selection.rangeCount; i<l; i++) sel+=selection.getRangeAt(i).toString();
        return sel;
      },
      TITLE: function() buffer.title
    },
    launch: function(appName){
      var self = this;
      appName = appName.replace(/\\+/g, '');                // fix commandline input ' ' -> '\ '
      settings.some( function([name, app, args]){
        args = args instanceof Array ? args : args ? [args] : [];
        args = args.map( function( val ) val.replace(/%([A-Z]+)%/g, function( _, name ) self.variables[name]()) );
        if (defaultCharset){
          UConv.charset = defaultCharset;
          args = args.map( function( val ) UConv.ConvertFromUnicode(val) );
        }
        if (appName == name){
          io.run(app, args);
          return true;
        }
        return false;
      });
    }
  }
  return new AppLauncher();
})();
- name : {String} - namespace : {String} - description: {String} - enabled : {Boolean} - includes : {String[]} - encludes : {String[]} ) ]]></detail> </VimperatorPlugin>; (function(){ const Cc = Components.classes; const Ci = Components.interfaces; const gmID = '@greasemonkey.mozdev.org/greasemonkey-service;1'; if (!Cc[gmID]){ liberator.log('Greasemonkey is not installed',0); return; } liberator.plugins.gmperator = (function(){ //{{{ // ----------------------- // PUBLIC section // ----------------------- // {{{ var manager = { register: function (uri,sandbox,script){ var panelID = getPanelID(sandbox.window); if (!panelID) return; var gmCon; if (containers[panelID] && containers[panelID].uri == uri){ gmCon = containers[panelID]; } else { gmCon = new GmContainer(uri,sandbox); containers[panelID] = gmCon; this.__defineGetter__(panelID,function() gmCon); //liberator.log('gmpeartor: Registered: ' + panelID + ' - ' + uri,8); } gmCon.sandbox = sandbox; gmCon.addScript(script); gmCon.uri = uri; triggerGMEvent('GMInjectedScript',uri,script._filename); if (panelID == this.currentPanel){ triggerGMEvent('GMActiveScript',uri,script._filename); } }, get gmScripts() GM_getConfig().scripts, get allItem() containers, get currentPanel() getBrowser().mCurrentTab.linkedPanel, get currentContainer() containers[this.currentPanel] || null, get currentSandbox(){ var id = this.currentPanel; return containers[id] ? containers[id].sandbox : null; }, getSandboxFromWindow: function(win){ for each (let c in containers){ if (c.sandbox.window == win) return sandbox; } return null; }, getContainersFromURI: function(uri){ var list = []; for each (let c in containers){ if (c.uri == uri) list.push(c); } return list.length > 0 ? list : null; } }; // }}} // ----------------------- // 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 (let i=0,l=tabs.length; i<l; i++){ let tab = tabs.item(i); if (tab.linkedBrowser.contentWindow == win){ return tab.linkedPanel; } } } function updateGmContainerList(event){ var t = event.target; if (t && t.localName == 'tab' && t.linkedPanel){ delete containers[t.linkedPanel]; delete liberator.plugins.gmperator[t.linkedPanel]; } } function dispatchGMTabSelect(event){ var panelID = event.originalTarget.linkedPanel; var container; if (container = containers[panelID]){ liberator.log(panelID + '\n' + container.uri +'\n'+ container.scripts.length,8); container.scripts.forEach(function(script){ triggerGMEvent('GMActiveScript',container.uri,script._filename); }); } } /** * trigger autocommand * @param {String} name Event name * @param {String} uri * @param {String} filename script filename */ function triggerGMEvent(name,uri,filename){ autocommands.trigger(name, {url: uri+'\n'+filename }); liberator.log('gmpeartor: '+ name + ' ' + uri+'\n'+filename,8); } getBrowser().mTabContainer.addEventListener('TabClose',updateGmContainerList,false); getBrowser().mTabBox.addEventListener('TabSelect',dispatchGMTabSelect,false); config.autocommands.push(['GMInjectedScript','Triggered when UserScript is injected']); config.autocommands.push(['GMActiveScript','Triggered when location is changed and injected UserScripts are exist']); config.dialogs.push(['userscriptmanager','Greasemonkey Manager',function(){GM_openUserScriptManager();}]); // }}} return manager; })(); //}}} // --------------------------- // User Command // --------------------------- commands.addUserCommand(['gmli[st]','lsgm'],'list Greasemonkey scripts', //{{{ function(args){ var xml = <></>; var scripts = GM_getConfig().scripts; var reg; if (args.bang || args.string == 'full'){ reg = new RegExp(); } else if (args.string){ reg = new RegExp(args.string,'i'); } if (reg){ for each (let s in scripts){ if (reg.test(s.name) || reg.test(s._filename)){ xml += scriptToString(s); } } } else { let table = <table/>; let tr; for each (let script in scripts){ tr = <tr/>; if (script.enabled){ tr.* += <td style="font-weight:bold;">{script.name}</td>; } else { tr.* += <td>{script.name}</td>; } tr.* += <td>({script._filename})</td>; table.* += tr; } xml += table; } liberator.echo(xml,true); function scriptToString(script){ var table = <table> <caption class="hl-Title" style="text-align:left">{script.name}</caption> </table>; [['FileName','_filename'],['NameSpace','namespace'],['Description','description'], ['Includes','includes'],['Excludes','excludes'],['Enabled','enabled']].forEach(function(prop){ let tr = <tr> <th style="font-weight:bold;text-align:left;vertical-align:top">{prop[0]}</th> </tr>; let contents = script[prop[1]]; if (typeof contents == 'string' || typeof contents == 'boolean'){ tr.* += <td>{contents}</td>; } else { let td = <td/>; for (let i=0,l=contents.length; i<l; i++){ td.* += contents[i]; if (contents[i+1]) td.* += <br/>; } tr.* += td; } table.* += tr; }); return table; } },{ bang:true } ); //}}} commands.addUserCommand(['gmlo[ad]'],'load Greasemonkey scripts', //{{{ function(args){ if (!args.string){ liberator.echoerr('Usage: :gmlo[ad][!] {name|filename}'); return; } var scripts = GM_getConfig().scripts; var script; for (let i=0,l=scripts.length; i<l; i++){ if (scripts[i]._filename == args.string || scripts[i].name == args.string){ script = scripts[i]; break; } } if (!script){ liberator.echoerr('no such a user script'); return; } else if (liberator.plugins.gmperator.currentContainer.hasScript(script._filename) && !args.bang){ liberator.echoerr(script._filename + ' is already loaded!'); return; } else { liberator.echo('loading: ' +script._filename); } var href,unsafewin; try { href = buffer.URL; unsafewin = window.content.document.defaultView.wrappedJSObject; GM_BrowserUI.gmSvc.wrappedJSObject.injectScripts([script],href,unsafewin,window); } catch (e){ liberator.log(e); liberator.echoerr(e); } /* // do you have idea how to dispatch load event to only the script ? window.setTimeout(function(){ var loadEvent = document.createEvent('Event'); loadEvent.initEvent('load',true,true,window.content.document,1); window.content.document.dispatchEvent(loadEvent); },100); */ },{ completer: function(context) scriptsCompleter(context.filter,true) } ); //}}} commands.addUserCommand(['gmset'],'change settings for Greasemonkey scripts', //{{{ function(args){ if (args.length == 0){ if (args.bang) GM_setEnabled(!GM_getEnabled()); // toggle enable/disable Greasemonkey return; } var filename = args[0]; var config = GM_getConfig(); var script; for (let i=0,l=config.scripts.length; i<l; i++){ if (config.scripts[i]._filename == filename){ script = config.scripts[i]; break; } } if (!script) return; if (args.bang){ // toggle enable/disable the script if {filename} is exist script.enabled = !script.enabled; } if (args['-name']) script.name = args['-name']; if (args['-include']) script.include = args['-include']; if (args['-exclude']) script.exclude = args['-exclude']; config._save(); },{ completer: function(context) scriptsCompleter(context.filter,false), options: [ [['-name','-n'], commands.OPTION_STRING], [['-include','-i'], commands.OPTION_LIST], [['-exclude','-e'], commands.OPTION_LIST] ], bang:true } ); //}}} commands.addUserCommand(['gmcommand','gmcmd'],'run Greasemonkey Command', //{{{ function(args){ var commander = GM_BrowserUI.getCommander(content); var commandName = args[0]; for (let i=0,l=commander.menuItems.length; i<l; i++){ let menuItem = commander.menuItems[i]; if (menuItem.getAttribute('label') == commandName){ menuItem._commandFunc(); return; } } liberator.echoerr(commandName + ' is not defined userscript command.'); }, { completer: function(context){ var items = GM_BrowserUI.getCommander(content).menuItems; var completions = []; var exp = new RegExp(context.filter,'i'); context.title = ["UserScript's Commands"]; context.completions = [[items[i].getAttribute('label'),'-'] for (i in items)].filter(function(item){ return this.test(item[0]); },exp); }, argCount: "1" } ); //}}} // --------------------------- // 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 this.scripts.push(script); } return false; }, 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) s._filename == filename); } }; // }}} function scriptsCompleter(filter,flag){ //{{{ var candidates = []; var scripts = GM_getConfig().scripts; var isAll = false; if (!filter) isAll=true; if (flag){ for each (let s in scripts){ if (isAll || s.name.toLowerCase().indexOf(filter) == 0 || s._filename.indexOf(filter) == 0) { candidates.push([s.name,s.description]); candidates.push([s._filename,s.description]); } } } else { for each (let s in scripts){ if (isAll || s._filename.indexOf(filter) == 0) { candidates.push([s._filename,s.description]); } } } return [0,candidates]; } //}}} })(); // vim: fdm=marker sw=4 ts=4 et: