aboutsummaryrefslogtreecommitdiffstats
path: root/exopen.js
blob: 3f6c82a435a484a9e5e422a7a2d698e6f5f45749 (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
/*
 * ==VimperatorPlugin==
 * @name            toggline.js
 * @description     toggle online/offline.
 * @description-ja  オンライン / オフラインを切り替える。
 * @author          janus_wel <janus_wel@fb3.so-net.ne.jp>
 * @version         0.10
 * @minversion      2.0pre
 * @maxversion      2.0pre
 * ==/VimperatorPlugin==
 *
 * LICENSE
 *  New BSD License
 *
 * USAGE
 *  this plugin provide you visualization of online/offline status
 *  and command that toggle online/offline.
 *
 *      :toggline   toggle online/offline
 *
 *  refer: https://developer.mozilla.org/ja/Online_and_offline_events
 *         http://builder.japan.zdnet.com/sp/firefox-3-for-developer-2008/story/0,3800087566,20384534,00.htm
 *
 * TODO
 *  need stylish icon.
 * */

( function () {
// define data
const onLineText  = 'status: online';
const offLineText = 'status: offline';
const onLineIcon = 'data:image/gif;base64,'+
    'R0lGODlhEAAQAMQfAHbDR0twLrPdlpHQaZGYjPn8983muYvSWIPNU3G/RNTtxTZZGn6TbVKCLJPm'+
    'V4nkTOz35ajld8LmqV16Rn7VR4DLT4zlUExgPHGLXIvOYKTad4DZSGm4PlJnQv///////yH5BAEA'+
    'AB8ALAAAAAAQABAAAAWE4Cd+Xml6Y0pORMswE6p6mGFIUR41skgbh+ABgag4eL4OkFisDAwZxwLl'+
    '6QiGzQHEM3AEqFZmJbNVICxfkjWjgAwUHkECYJmqBQNJYSuf18ECAABafQkJD3ZVGhyChoYcHH8+'+
    'FwcJkJccD2kjHpQPFKAbmh4FMxcNqKhTPSknJiqwsSMhADs=';
const offLineIcon = 'data:image/gif;base64,'+
    'R0lGODlhEAAQAMQfAOt0dP94eOFjY/a0tP/JyfFfX/yVlf6mppNtbf5qanknJ9dVVeZqat5eXpiM'+
    'jGo4OIUvL3pGRthWVuhvb1kaGv39/f1lZdg7O/7Y2F8/P+13d4tcXNRTU2dCQv///////yH5BAEA'+
    'AB8ALAAAAAAQABAAAAV/4Cd+Xml6Y0pGTosgEap6G0YQh6FDskhjGg0AMJkwAjxfBygkGhmCAAXl'+
    '6QyGnuLFI4g+qNbixLMNdBNfkpXBLncbial6AC17Gvg4eND1BPB3cHJVBguGhwsSHHo+GRqKHJGR'+
    'CQo9JI4WBZoFFpUV
var PLUGIN_INFO =
<VimperatorPlugin>
<name>{NAME}</name>
<description>Open URL from a template</description>
<description lang="ja">テンプレートからURLをOpenします</description>
<minVersion>2.0pre</minVersion>
<maxVersion>2.0pre</maxVersion>
<updateURL>http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk/exopen.js</updateURL>
<author homepage="http://vimperator.g.hatena.ne.jp/pekepekesamurai/">pekepekesamurai</author>
<version>0.10.1</version>
<detail lang="ja"><![CDATA[
== Command ==
:exopen [template_name]
  [template_name] で設定されたURLを開きます

=== Example ===
:exopen http://www.google.co.jp/search?q=%TITLE%:
  %TITLE%を現在開いているWebページのタイトルに展開してURLを開きます
:exopen [title]
  テンプレートで設定されたURLを開きます

== Keyword ==
%TITLE%:
  現在のWebページのタイトル
%URL%:
  現在のWebページのURL
%SEL%:
  選択中の文字列
%HTMLSEL%:
  選択中のHTMLソース

== .vimperatorrc ==
>||
javascript <<EOM
liberator.globalVariables.exopen_templates = [
  {
    label: 'vimpnightly',
    value: 'http://code.google.com/p/vimperator-labs/downloads/list?can=1&q=label:project-vimperator',
    description: 'open vimperator nightly xpi page',
    newtab: true
  }, {
    label: 'vimplab',
    value: 'http://www.vimperator.org/vimperator',
    description: 'open vimperator trac page',
    newtab: true
  }, {
    label: 'vimpscript',
    value: 'http://code.google.com/p/vimperator-labs/issues/list?can=2&q=label%3Aproject-vimperator+label%3Atype-plugin',
    description: 'open vimperator trac script page',
    newtab: true
  }, {
    label: 'coderepos',
    value: 'http://coderepos.org/share/browser/lang/javascript/vimperator-plugins/trunk/',
    description: 'open coderepos vimperator-plugin page',
    newtab: true
  }, {
    label: 'sldr',
    value: 'http://reader.livedoor.com/subscribe/%URL%'
  }
];
EOM
||<
label:
  テンプレート名コマンドの引数で指定してください
value:
  OpenするURL
custom:
  関数か配列で指定してください
  関数の場合return された文字列をオープンします
  配列の場合value で指定された文字列を置換します(条件Array[0]置換文字列Array[1])
description:
  補完時に表示する説明文
newtab:
  新規タブで開く場合は true を指定してください
escape:
  URLエンコードする場合true を指定してください
]]></detail>
</VimperatorPlugin>;

liberator.plugins.exOpen = (function() {
  var global = liberator.globalVariables.exopen_templates;
  if (!global) {
    global = [{
      label: 'vimpnightly',
      value: 'http://code.google.com/p/vimperator-labs/downloads/list?can=1&q=label:project-vimperator',
      description: 'open vimperator nightly xpi page',
      newtab: true
    }, {
      label: 'vimplab',
      value: 'http://www.vimperator.org/vimperator',
      description: 'open vimperator trac page',
      newtab: true
    }, {
      label: 'vimpscript',
      value: 'http://code.google.com/p/vimperator-labs/issues/list?can=2&q=label%3Aproject-vimperator+label%3Atype-plugin',
      description: 'open vimperator trac script page',
      newtab: true
    }, {
      label: 'coderepos',
      value: 'http://coderepos.org/share/browser/lang/javascript/vimperator-plugins/trunk/',
      description: 'open coderepos vimperator-plugin page',
      newtab: true
    }, {
      label: 'sldr',
      value: 'http://reader.livedoor.com/subscribe/%URL%'
    }];
  }

  function openTabOrSwitch(url) {
    var tabs = gBrowser.mTabs;
    for (let i=0, l=tabs.length; i<l; i++)
      if (tabs[i].linkedBrowser.contentDocument.location.href == url) return (gBrowser.tabContainer.selectedIndex = i);
    return liberator.open(url, liberator.NEW_TAB);
  }

  function replacer(str, isEscape) {
    if (!str) return '';
    var win = new XPCNativeWrapper(window.content.window);
    var sel = '', htmlsel = '';
    var selection = win.getSelection();
    function __replacer(val) {
      switch (val) {
        case '%TITLE%':
          return buffer.title;
        case '%URL%':
          return buffer.URL;
        case '%SEL%':
          if (sel) return sel;
          else if (selection.rangeCount < 1) return '';
          for (let i=0, c=selection.rangeCount; i<c;
            sel += selection.getRangeAt(i++).toString());
          return sel;
        case '%HTMLSEL%':
          if (htmlsel) return sel;
          if (selection.rangeCount < 1) return '';

          let serializer = new XMLSerializer();
          for (let i=0, c=selection.rangeCount; i<c;
            htmlsel += serializer.serializeToString(selection.getRangeAt(i++).cloneContents()));
          return htmlsel;
      }
      return '';
    }
    var _replacer = __replacer;
    if (isEscape) _replacer = function(val) escape( __replacer(val) );

    return str.replace(/%(TITLE|URL|SEL|HTMLSEL)%/g, _replacer);
  }

  var ExOpen = function() this.initialize.apply(this, arguments);
  ExOpen.prototype = {
    initialize: function() {
      this.createCompleter();
      this.registerCommand();
    },
    createCompleter: function() {
        this.completer = global.map(
          function(t) [t.label, util.escapeString((t.description ? t.description + ' - ' : '') + t.value)]
        );
    },
    registerCommand: function() {
      var self = this;
      commands.addUserCommand(['exopen'], 'Open byextension URL',
        function(args) self.open(args), {
          completer: function(context, args) {
            context.title = ['Template', 'Description - Value'];
            if (!context.filter) {
              context.completions = self.completer;
              return;
            }
            var filter = context.filter.toLowerCase();
            context.completions = self.completer.filter( function( t ) t[0].toLowerCase().indexOf(filter) == 0 );
          }
      });
    },
    find: function(label) {
      var ret = null;
      global.some(function(template) (template.label == label) && (ret = template));
      return ret;
    },
    open: function(args) {
      var url = '';
      if (!args) return;
      var name = args.string;
      if (args instanceof Array) {
        name = args.shift();
        args.string = args.string.replace(new RegExp(name.replace(/(\W)/g,'\\$1')+'\\s+'),'');
      }
      var template = this.find(name) || {value: name};
      if (typeof template.custom == 'function') {
        url = template.custom.call(this, template.value, args);
      } else if (template.custom instanceof Array) {
        url = replacer(template.value).replace(template.custom[0], template.custom[1], template.escape);
      } else {
        url = replacer(template.value, template.escape);
      }
      if (!url) return;
      if (template.newtab || args.bang) openTabOrSwitch(url);
      else liberator.open(url);
    },
  };
  return new ExOpen();
})();