aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--appendAnchor.js66
1 files changed, 46 insertions, 20 deletions
diff --git a/appendAnchor.js b/appendAnchor.js
index a6af591..e9f0f0b 100644
--- a/appendAnchor.js
+++ b/appendAnchor.js
@@ -3,7 +3,7 @@
* @name appendAnchor
* @description append anchors to texts look like url.
* @author SAKAI, Kazuaki
- * @version 0.02
+ * @version 0.03
* @minVersion 2.0pre
* @maxVersion 2.0pre
* == /VimperatorPlugin==
@@ -11,7 +11,15 @@
(function(){
- if (window.eval(liberator.globalVariables.auto_append_anchor || 'false')) {
+ // 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');
@@ -19,33 +27,51 @@
};
}
+ // register command
liberator.modules.commands.addUserCommand(['anc'], 'append anchors to texts look like url',
function(arg, special) {
- var doc = window.content.document;
- var nodes = liberator.modules.buffer.evaluateXPath(
- '/descendant::*[not(contains(" TITLE STYLE SCRIPT TEXTAREA XMP A ", concat(" ", translate(local-name(), "aceilmprstxy", "ACEILMPRSTXY"), " ")))]/child::text()'
- );
- var regex = new RegExp("h?(ttps?):/+([a-zA-Z0-9][-_.!~*'()a-zA-Z0-9;/?:@&=+$,%#]+[-_~*(a-zA-Z0-9;/?@&=+$%#])");
-
- var range = doc.createRange();
- var last;
- var href;
- for (let i = 0, l = nodes.snapshotLength; i < l; i++) {
- let node = nodes.snapshotItem(i);
- range.selectNode(node);
- while (node && (last = range.toString().search(regex)) > -1) {
- range.setStart(node, last);
- range.setEnd(node, last + RegExp.lastMatch.length);
- href = 'h' + RegExp.$1 + '://' + RegExp.$2;
+ 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');
- range.insertNode(anchor);
anchor.setAttribute('href', href);
range.surroundContents(anchor);
+
+ // insert
+ range.insertNode(anchor);
+
+ // iterate
node = node.nextSibling.nextSibling;
- range.selectNode(node);
}
}
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;
+ }
+
})();