aboutsummaryrefslogtreecommitdiffstats
path: root/appendAnchor.js
blob: e9f0f0bddc0079e116053877a111c00a2b7fdc9d (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
/**
 * == VimperatorPlugin==
 * @name          appendAnchor
 * @description   append anchors to texts look like url.
 * @author        SAKAI, Kazuaki
 * @version       0.03
 * @minVersion    2.0pre
 * @maxVersion    2.0pre
 * == /VimperatorPlugin==
 */

(function(){

  // settings ---
  // "ACEILMPRSTXY" is result of below code.
  //   Array.prototype.uniq = function() this.reduceRight( function (a, b) (a[0] === b || a.unshift(b), a), []);
  //   [ 'TITLE', 'STYLE', 'SCRIPT', 'TEXTAREA', 'XMP', 'A', ].join('').split('').sort().uniq().join('');
  const xpathQueryPlainText = '/descendant::*[not(contains(" TITLE STYLE SCRIPT TEXTAREA XMP A ", concat(" ", translate(local-name(), "aceilmprstxy", "ACEILMPRSTXY"), " ")))]/child::text()';
  const regexpLikeURL = new RegExp("h?(ttps?):/+([a-zA-Z0-9][-_.!~*'()a-zA-Z0-9;/?:@&=+$,%#]+[-_~*(a-zA-Z0-9;/?@&=+$%#])");

  // process global variable
  if (stringToBoolean(liberator.globalVariables.auto_append_anchor, 'false')) {
    let originalHintsShow = liberator.modules.hints.show;
    hints.show = function () {
      liberator.execute('anc');
      originalHintsShow.apply(this, arguments);
    };
  }

  // register command
  liberator.modules.commands.addUserCommand(['anc'], 'append anchors to texts look like url',
    function(arg, special) {
      const doc = window.content.document;
      const range = doc.createRange();

      let nodes = liberator.modules.buffer.evaluateXPath(xpathQueryPlainText);
      for (let node in nodes) {
        while (node) {
          range.selectNode(node)

          // search string like URL
          let start = range.toString().search(regexpLikeURL);
          // go to next node when there is nothing look like URL in current node
          if (!(start > -1)) break;

          // build URL
          let href = 'h' + RegExp.$1 + '://' + RegExp.$2;

          // reset range
          range.setStart(node, start);
          range.setEnd(node, start + RegExp.lastMatch.length);

          // build anchor element
          let anchor = doc.createElement('a');
          anchor.setAttribute('href', href);
          range.surroundContents(anchor);

          // insert
          range.insertNode(anchor);

          // iterate
          node = node.nextSibling.nextSibling;
        }
      }
      range.detach();
    },{}
  );

  // stuff function
  function stringToBoolean(str, defaultValue) {
    return !str                          ? (defaultValue ? true : false)
         : str.toLowerCase() === 'false' ? false
         : /^\d+$/.test(str)             ? (parseInt(str) ? true : false)
         :                                 true;
  }

})();
/span> STORAGE_NAME = 'plugin-garbage-finder'; const IGNORES = (let (gv = liberator.globalVariables.garbage_finder_ignore) gv === undefined ? 'DownloadUtils PluralForm' : gv).split(/\s+/); function Somali (n) let(V,[l,s,j,t]=liberator.eval('[loadPref,savePref,json,Object]',storage.newObject)) ({load:function(d)let(v=l(n,true,t))(V=v?v.value:d), save:function(v)s({store:true,name:n,serial:j.encode({value:v===undefined?V:v})})}); function vars () { let result = []; for (let name in window) result.push(name); return result.sort(); } function has (ary, v) ary.some(function (it) v == it); function diff (oldList, newList) { function sub (n, o) n.filter(function (it) !has(o, it)); return { appended: ignore(sub(newList, oldList)), removed: ignore(sub(oldList, newList)) }; } function id (value) value; function ignore (ary) ary.filter(function (it) !has(IGNORES, it)); let store = new Somali(STORAGE_NAME); let prevVars = store.load(vars()); function save () store.save(vars()); autocommands.add( 'VimperatorEnter', /.*/, function () setTimeout(save, 2000) ); commands.addUserCommand( ['garbages'], 'Displays garbages', function (args) { function makeLI (list) { if (list.length) { let result = <></>; list.forEach(function (it) (result += <li>{it}</li>)); return <ol>{result}</ol>; } // XXX 駄目くさいけどめんどくさいので… return <ol>Nothing</ol>; } if (args.bang) { save(); liberator.echo('Current variables was saved.'); } else { let gs = diff(prevVars, vars()); let as = makeLI(gs.appended), rs = makeLI(gs.removed); liberator.echo(<div><h1>Appended</h1><div>{as}</div><h1>Removed</h1><div>{rs}</div></div>); } }, { bang: true }, true ); })(); // vim:sw=2 ts=2 et si fdm=marker: