/*** BEGIN LICENSE BLOCK {{{ Copyright (c) 2008 suVene distributable under the terms of an MIT-style license. http://www.opensource.jp/licenses/mit-license.html }}} END LICENSE BLOCK ***/ // PLUGIN_INFO//{{{ var PLUGIN_INFO = libly(filename _libly.js) Vimperator plugins library? 適当なライブラリっぽいものたち。 suVene MIT 0.1.21 1.2 2.0pre http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk/_libly.js ※1 ※1 の文字列を取得します。 stripTags(str, tags): str から tags で指定されたタグを取り除いて返却します。 tags は文字列、または配列で指定して下さい。 createHTMLDocument(str, xmlns): 引数 str より、HTMLFragment を作成します。 getFirstNodeFromXPath(xpath, context): xpath を評価しオブジェクトをを返却します。 getNodesFromXPath(xpath, context, callback, thisObj): xpath を評価し snapshot の配列を返却します。 xmlSerialize(xml): xml を文字列化します。 xmlToDom(node, doc, nodes): for vimperator1.2. @see vimperator2.0pre util. getElementPosition(elem): elem の offset を返却します。 return {top: 0, left: 0} toStyleText(style): スタイルが格納されているオブジェクトを >|| position: fixed; left: 10px; ||< のような文字列に変換します。 ]]> ; //}}} //if (!liberator.plugins.libly) { liberator.plugins.libly = {}; var libly = liberator.plugins.libly; libly.$U = {//{{{ // Logger {{{ getLogger: function(prefix) { return new function() { this.log = function(msg, level) { if (typeof msg == 'object') msg = util.objectToString(msg); liberator.log(libly.$U.dateFormat(new Date()) + ': ' + (prefix || '') + ': ' + msg, (level || 0)); }; this.echo = function(msg, flg) { flg = flg || commandline.FORCE_MULTILINE; // this.log(msg); liberator.echo(msg, flg); }; this.echoerr = function(msg) { this.log('error: ' + msg); liberator.echoerr(msg); }; } }, // }}} // Object Utility {{{ extend: function(dst, src) { for (let prop in src) dst[prop] = src[prop]; return dst; }, A: function(iterable) { var ret = []; if (!iterable) return ret; if (typeof iterable == 'string') return [iterable]; if (!(typeof iterable == 'function' && iterable == '[object NodeList]') && iterable.toArray) return iterable.toArray(); if (typeof iterable.length != 'undefined') { for (let i = 0, len = iterable.length; i < len; ret.push(iterable[i++])); } else { for each (let item in iterable) ret.push(item); } return ret; }, around: function around (obj, name, func) { let next = obj[name]; let current = obj[name] = function () { let self = this, args = arguments; return func.call(self, function () next.apply(self, args), args); }; return [next, current]; }, bind: function(obj, func) { return function() { return func.apply(obj, arguments); } }, eval: function(text) { var fnc = window.eval; var sandbox; try { sandbox = new Components.utils.Sandbox(window); if (Components.utils.evalInSandbox('true', sandbox) === true) { fnc = function(text) { return Components.utils.evalInSandbox(text, sandbox); }; } } catch (e) { liberator.log('warning: _libly.js is working with unsafe sandbox.'); } return fnc(text); }, evalJson: function(str, toRemove) { var json; try { json = Components.classes['@mozilla.org/dom/json;1'].getService(Components.interfaces.nsIJSON); if (toRemove) str = str.substring(1, str.length - 1); return json.decode(str); } catch (e) { return null; } }, dateFormat: function(dtm, fmt) { var d = { y: dtm.getFullYear(), M: dtm.getMonth() + 1, d: dtm.getDate(), h: dtm.getHours(), m: dtm.getMinutes(), s: dtm.getSeconds(), '%': '%' }; for (let [n, v] in Iterator(d)) { if (v < 10) d[n] = '0' + v; } return (fmt || '%y/%M/%d %h:%m:%s').replace(/%([yMdhms%])/g, function (_, n) d[n]); }, /** * example) * $U.runnable(function(resume) { * // execute asynchronous function. * // goto next yield; * var val = yield setTimeout(function() { resume('value!'), 1000) }); * alert(val); // value! * yield; * }); */ runnable: function(generator) { var it = generator(function(value) { try { it.send(value); } catch (e) {} }); it.next(); }, // }}} // Browser {{{ getSelectedString: function() { return (new XPCNativeWrapper(window.content.window)).getSelection().toString(); }, getUserAndPassword: function(hostname, formSubmitURL, username) { var passwordManager, logins; try { passwordManager = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager); logins = passwordManager.findLogins({}, hostname, formSubmitURL, null); if (logins.length) { if (username) { for (let i = 0, len = logins.lengh; i < len; i++) { if (logins[i].username == username) return [logins[i].username, logins[i].password] } liberator.log(this.dateFormat(new Date()) +': [getUserAndPassword] username notfound'); //throw 'username notfound.'; return []; } else { return [logins[0].username, logins[0].password]; } } else { liberator.log(this.dateFormat(new Date()) + ': [getUserAndPassword] account notfound'); return []; } } catch (e) { liberator.log(this.dateFormat(new Date()) + ': [getUserAndPassword] error: ' + e, 0); return null; } }, // }}} // System {{{ readDirectory: function(path, filter, func) { var d = io.getFile(path); if (d.exists() && d.isDirectory()) { let enm = d.directoryEntries; let flg = false; while (enm.hasMoreElements()) { let item = enm.getNext(); item.QueryInterface(Components.interfaces.nsIFile); flg = false; if (typeof filter == 'string') { if ((new RegExp(filter)).test(item.leafName)) flg = true; } else if (typeof filter == 'function') { flg = filter(item); } if (flg) func(item); } } }, // }}} // HTML, XML, DOM, E4X {{{ pathToURL: function(a, baseURL, doc) { if (!a) return ''; var XHTML_NS = "http://www.w3.org/1999/xhtml"; var XML_NS = "http://www.w3.org/XML/1998/namespace"; //var path = (a.href || a.getAttribute('src') || a.action || a.value || a); var path = (a.getAttribute('href') || a.getAttribute('src') || a.action || a.value || a); if (/^https?:\/\//.test(path)) return path; var link = (doc || window.content.documtent).createElementNS(XHTML_NS, 'a'); link.setAttributeNS(XML_NS, 'xml:base', baseURL); link.href = path; return link.href; }, getHTMLFragment: function(html) { if (!html) return html; return html.replace(/^[\s\S]*?]*)?>|<\/html[ \t\r\n]*>[\S\s]*$/ig, ''); }, stripTags: function(str, tags) { var ignoreTags = '(?:' + [].concat(tags).join('|') + ')'; return str.replace(new RegExp('<' + ignoreTags + '(?:[ \\t\\n\\r][^>]*|/)?>([\\S\\s]*?)<\/' + ignoreTags + '[ \\t\\r\\n]*>', 'ig'), ''); }, createHTMLDocument: function(str, xmlns, doc) { let root = document.createElementNS("http://www.w3.org/1999/xhtml", "html"); let uhService = Cc["@mozilla.org/feed-unescapehtml;1"].getService(Ci.nsIScriptableUnescapeHTML); let text = str.replace(/^[\s\S]*?]*)?>[\s]*|<\/body[ \t\r\n]*>[\S\s]*$/ig, ''); let fragment = uhService.parseFragment(text, false, null, root); let htmlFragment = document.implementation.createDocument(null, 'html', null); htmlFragment.documentElement.appendChild(htmlFragment.importNode(fragment,true)); return htmlFragment; /* うまく動いていない場合はこちらに戻してください doc = doc || window.content.document; var htmlFragment = doc.implementation.createDocument(null, 'html', null); var range = doc.createRange(); range.setStartAfter(doc.body); htmlFragment.documentElement.appendChild(htmlFragment.importNode(range.createContextualFragment(str), true)); return htmlFragment; */ }, getFirstNodeFromXPath: function(xpath, context) { if (!xpath) return null; context = context || window.content.document; var result = (context.ownerDocument || context).evaluate(xpath, context, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); return result.singleNodeValue || null; }, getNodesFromXPath: function(xpath, context, callback, thisObj) { var ret = []; if (!xpath) return ret; context = context || window.content.document; var nodesSnapshot = (context.ownerDocument || context).evaluate(xpath, context, null, XPathResult.ORDERED_NODE_SNAPSHOT_T
var PLUGIN_INFO =
<VimperatorPlugin>
  <name>autoproxychanger</name>
  <description>setting proxy</description>
  <description lang="ja">proxyの設定自動切り替え</description>
  <version>0.1.3</version>
  <author homepage="http://d.hatena.ne.jp/pekepekesamurai/">pekepeke</author>
  <minVersion>2.0pre</minVersion>
  <maxVersion>2.0pre</maxVersion>
  <updateURL>http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk/autoproxychanger.js</updateURL>
  <detail><![CDATA[
    == Usage ==
      :proxy [setting_name]:
        set proxy setting to setting_name
      :proxy!:
        set proxy setting to default setting
      :toggleautoproxy:
        proxy autochanger on/off toggle

      The proxy_settings is a string variable which can set on
      vimperatorrc as following.

      >||
      let autochanger_proxy_settings = "[{ name:'disable', usage: 'direct connection', proxy:{type:0} }]"
      let autochanger_proxy_enabled = "true"
      ||<

      or your can set it using inline JavaScript.

      >||
      liberator.globalVariables.autochanger_proxy_enabled = true;
      liberator.globalVariables.autochanger_proxy_settings = [{
          name  : 'disable',
          usage : 'direct connection',
          proxy :{
            type      :0,
          },
        },{
          name  : 'http',
          usage : 'localhost proxy',
          proxy :{
            type      : 1,
            http      : 'localhost',
            http_port : 8080,
          },
          url   : /http:\/\/www.nicovideo.jp/,
          run   : 'java.exe',
          args  : ['C:\Personal\Apps\Internet\NicoCacheNl\NicoCache_nl.jar'],
        }];
      EOM
      ||<
  ]]></detail>
</VimperatorPlugin>;

liberator.plugins.AutoProxyChanger = (function() {
var gVar = liberator.globalVariables;
var proxy_settings = gVar.autochanger_proxy_settings;
if (!proxy_settings) {
  proxy_settings = [{
    name  : 'disable',
    usage : 'direct connection',
    proxy : {
      type      : 0,
    },
  }, {
    name  : 'http',
    usage : 'localhost:8080',
    proxy : {
      type      : 1,
      http      : 'localhost',
      http_port : 8080,
    },
  }];
}

const ENABLE_ICON = 'data:image/png;base64,'
  + 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMA/wAAAIBJekM9AAAB'
  + 'mElEQVR4nIWS3StDYRzHv895njOvaWy4WWPJcquE8nIrbSW54mrGjWsppbQtCuXajZd/QDKs'
  + 'UNxoLpYbKc1b2zm4mJ2NsGPNOC6OnHXGfO+eb8/neX6fp4e43aNWax3+iCgKK6uW3IZZrXXT'
  + '01OEkPzdiqL4fLPja04Al6H97aU3AAwAIcTmmMsHIoFJAIvDfgDja31Y8n8Dapw97cUGSilH'
  + 'CUlnshuB41+H1IDMJ5QsMb2cc3LMALha4fXOAPB6KIAKYcfroaIoaMBTKltaSqvlWGElDQgd'
  + 'nwBwtf6jxFRUXQDfYxRQYqIo+Hyz+eepSm/y+3MqI6czmvTVdbh/wGFvbBJuI2ZT9dbmbq4S'
  + '4w3l5ZTjOA1wOHuNxkrhNsIYLyXiOqX8MADBYFD3Gj9Kuh4AUeDJbUfcd4W/FhtbbEmfrT9+'
  + 'lJ0eBSJRl05JSsTNphop8WCrbwiHzw8O92j34EQtiZU1D7XZSpYtF51dHXa7XUrGGeNfUy8c'
  + 'x6XkV57xiaRUZawyFPFMTt4no9HHm2X1hvkFvZIuXyp4v/YfvuEoAAAAAElFTkSuQmCC';

const DISABLE_ICON = 'data:image/png;base64,'
  + 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMA/wAAAIBJekM9AAAB'
  + 'i0lEQVR4nH2SwUoCURSG/7lzZwJxYWqtRItQwm3LbCkStol8gLAW9QzB4AgW9QIJWc8QgVBI'
  + '7RQ3bsOmQGdsY466aCZ1RGwxksNo/rt7uN+55ztcJpk89vsD+CeKIt/e+awV6vcHBOGMYZjZ'
  + '2+PxOJ3OZK+9ACqVyk3OB4ACYBgmGo3OAoVCAcDJaRNA9noLueYEMBOLxXieZ1mWEDIYDPL5'
  + '/Nwhp8BoNBoOh71er9/vA4hEIqIoAqyYYgGgqYopVlHkKaBpmsPhMAxDEIQFSlOgXC6bjRcr'
  + 'URM1DwBEUVysRBVFTqczlkasVUnXdU3TTKsJ8P5R3T+Ih4KbcqPm9aw83D9alSilTqeTEDIF'
  + '4nu7Ltey3KhRyqntlk1p/lqLxaJtG39KtjoAZoyUtXqU/Fz8tejFOS9JkmEYpVKpVj+0Kant'
  + 'ltezqra/1tc2qtXX55cnNpFIcBwXDoeDwWDO9xbZ2Q6FQmqnRSmn6d+EEP1H4yjX7qhul5tf'
  + '4mi3263X65IkmS9cXtmVbPkFaGbHAxyF/18AAAAASUVORK5CYII=';

var acmanager = [];

const prefkeys = ['ftp','gopher','http','ssl'];
var prevSetting = null;
var _isEnable = false;
var exec = (function(){
  const Cc = Components.classes;
  const Ci = Components.interfaces;
  var getFile = function(){
    if (arguments.length <= 0) return null;
    var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsILocalFile);
    if (!file) return null;

    file.initWithPath(arguments[0]);
    for (var i=1; i<arguments.length; i++) file.append(arguments[i]);
    if (file.exists() && file.isFile) return file;
    return null;
  };
  var getPathSplitChar = function(){
    var os = Cc["@mozilla.org/xre/app-info;1"].createInstance(Ci.nsIXULRuntime).OS;
    if (os == "WINNT") return ";";
    return ":";
  };
  var run = function(file, arg, async){
    arg = arg || [];
    var process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
    process.init(file);
    process.run(false, arg, arg.length);
    return process.exitValue;
  };
  const spchar = getPathSplitChar();
  return function(cmd, arg, async){
    var file;
    if ( (cmd.indexOf('/') >= 0 || cmd.indexOf('\\') >= 0) && (file=getFile(cmd)) ) return run(file, arg, async);

    var env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
    var exitValue = null;
    env.get('PATH').split(spchar).some(
      function(path){
        if (file=getFile( path, cmd)){
          exitValue = run(file, arg, async);
          return true;
        }
        return false;
      }
    );
    return exitValue;
  };
})();

var ProxyChanger = function() this.initialize.apply(this, arguments);
ProxyChanger.prototype = {
  initialize: function() {
    this.panel = this.createPanel();
  },
  createPanel: function() {
    var self = this;
    var panel = document.getElementById('proxychanger-status');
    if (panel) {
      let parent = panel.parentNode;
      parent.removeChild(panel);
    }
    panel = document.createElement('statusbarpanel');
    panel.setAttribute('id', 'proxychanger-status');
    panel.setAttribute('class', 'statusbarpanel-iconic');
    panel.setAttribute('src', self.isEnable ? ENABLE_ICON : DISABLE_ICON);
    panel.addEventListener('click', function(e) { self.isEnable = !self.isEnable; }, false);
    document.getElementById('status-bar').insertBefore(
      panel, document.getElementById('security-button').nextSibling);
    return panel;
  },
  get isEnable() _isEnable,
  set isEnable(val) {
    this.panel.setAttribute('src', val ? ENABLE_ICON : DISABLE_ICON);
    _isEnable = val;
  },
  autoApplyProxy : checkApplyProxy
};
var manager = new ProxyChanger();

function init() {
  // initialize manager
  proxy_settings.forEach(function(s) {
    if (s.url instanceof RegExp && s.name)
      acmanager.push( {url: s.url, name: s.name, run: s.run || '', args: s.args || [] } );
  });

  proxy_settings.splice(0, 0, {name: 'default', usage: 'default setting', proxy: restore() });

  if (acmanager.length > 0) {
    autocommands.add("LocationChange", '.*', 'js liberator.plugins.AutoProxyChanger.autoApplyProxy()');
    window.addEventListener("unload", function() {
      if (prevSetting != null) applyProxy(prevSetting)
    }, false);
  }

  manager.isEnable = eval(gVar.autochanger_proxy_enabled) || false;
}
function restore() {
  var opt = new Object();
  opt['type'] = options.getPref('network.proxy.type', 0);
  prefkeys.forEach(function(key) {
    opt[key] = options.getPref('network.proxy.' + key, '');
    opt[key+'_port'] = options.getPref('network.proxy.' + key + '_port', 0);
  });
  return opt;
}
function dump(obj) {
  var m = '';
  for (let key in obj) m+=key+':'+obj[key]+'\n';
  return m;
}
function checkApplyProxy() {
  if (prevSetting != null) {
    applyProxy(prevSetting);
    prevSetting = null;
  }
  if (!_isEnable) return;
  acmanager.some( function( manager ) {
    if (manager.url.test(content.location.href)) {
      prevSetting = restore();
      try {
        if (manager.run) {
          if (exec(manager.run, manager.args, false) == null) throw "run process failed...";
          manager.run = null; manager.args = null;
        }
        applyProxyByName(manager.name);
        return true;
      } catch(e) {
        liberator.echoerr(e);
        return true;
      }
    }
    return false;
  });
}

function applyProxyByName( name ) {
  if (!name) {
    liberator.echo( dump(restore())+'usage:proxy [setting name]' );
    return;
  }
  proxy_settings.some( function(setting) {
    if (setting.name.toLowerCase() != name.toLowerCase()) return false;
    // delete setting
    prefkeys.forEach( function(key) {
      options.setPref('network.proxy.'+key, '');
      options.setPref('network.proxy.'+key+'_port', 0);
    });

    // apply proxy
    applyProxy(setting.proxy);
    return true;
  });
}

function applyProxy(proxy) {
  for (let key in proxy) {
    if (typeof proxy[key] != 'undefined')
      options.setPref('network.proxy.'+key, proxy[key]);
  }
}

commands.addUserCommand(['proxy'], 'Proxy settings',
  function(args, bang) {
    if (bang) applyProxyByName('default');
    else applyProxyByName(args.string);
  }, {
    bang: true,
    completer: function(context, arg, special) {
      context.title = ['Name', 'Usage'];
      var list = context.filter ?
        proxy_settings.filter( function(el) this.test(el.name), new RegExp('^'+context.filter))
        : proxy_settings;
      context.completions = list.map( function(v) [v.name, v.usage] );
    }
});

commands.addUserCommand(['toggleautoproxy','aprxy'], 'Toggle auto proxy changer on/off',
  function() {
    manager.isEnable = !manager.isEnable
    liberator.echo('autoproxy:'+ manager.isEnable ? 'ON' : 'OFF');
  }, {}
);

init();
return manager;
})();