Linkify as an extension. Finally fix #97

This commit is contained in:
Florian Mounier
2016-09-28 17:42:23 +02:00
parent 9bcc989149
commit 2887f6e25a
6 changed files with 134 additions and 42 deletions

View File

@@ -1,5 +1,5 @@
(function() {
var Popup, Selection, _set_theme_href, _theme, alt, cancel, clean_ansi, copy, ctrl, first, nextLeaf, popup, previousLeaf, selection, setAlarm, virtualInput,
var Popup, Selection, _set_theme_href, _theme, alt, cancel, clean_ansi, copy, ctrl, first, linkify, nextLeaf, popup, previousLeaf, selection, setAlarm, virtualInput, walk,
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
clean_ansi = function(data) {
@@ -156,6 +156,47 @@
}
});
walk = function(node, callback) {
var child, j, len1, ref, results;
ref = node.childNodes;
results = [];
for (j = 0, len1 = ref.length; j < len1; j++) {
child = ref[j];
callback.call(child);
results.push(walk(child, callback));
}
return results;
};
linkify = function(text) {
var emailAddressPattern, pseudoUrlPattern, urlPattern;
urlPattern = /\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|]/gim;
pseudoUrlPattern = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
emailAddressPattern = /[\w.]+@[a-zA-Z_-]+?(?:\.[a-zA-Z]{2,6})+/gim;
return text.replace(urlPattern, '<a href="$&">$&</a>').replace(pseudoUrlPattern, '$1<a href="http://$2">$2</a>').replace(emailAddressPattern, '<a href="mailto:$&">$&</a>');
};
Terminal.on('change', function(lines) {
var j, len1, line, results;
results = [];
for (j = 0, len1 = lines.length; j < len1; j++) {
line = lines[j];
results.push(walk(line, function() {
var linkified, newNode;
if (this.nodeType === 3) {
linkified = linkify(this.nodeValue);
if (linkified !== this.nodeValue) {
newNode = document.createElement('span');
newNode.innerHTML = linkified;
this.parentElement.replaceChild(newNode, this);
return true;
}
}
}));
}
return results;
});
document.addEventListener('keydown', function(e) {
if (!(e.altKey && e.keyCode === 79)) {
return true;

File diff suppressed because one or more lines are too long

View File

@@ -145,6 +145,22 @@
};
Terminal = (function() {
Terminal.hooks = {};
Terminal.on = function(hook, fun) {
if (Terminal.hooks[hook] == null) {
Terminal.hooks[hook] = [];
}
return Terminal.hooks[hook].push(fun);
};
Terminal.off = function(hook, fun) {
if (Terminal.hooks[hook] == null) {
Terminal.hooks[hook] = [];
}
return Terminal.hooks[hook].pop(fun);
};
function Terminal(parent, out1, ctl1) {
var div, px;
this.parent = parent;
@@ -201,8 +217,24 @@
return _this.resize();
};
})(this));
this.emit('load');
}
Terminal.prototype.emit = function() {
var args, fun, hook, k, len, ref, results;
hook = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
if (Terminal.hooks[hook] == null) {
Terminal.hooks[hook] = [];
}
ref = Terminal.hooks[hook];
results = [];
for (k = 0, len = ref.length; k < len; k++) {
fun = ref[k];
results.push(fun.apply(this, args));
}
return results;
};
Terminal.prototype.cloneAttr = function(a, char) {
if (char == null) {
char = null;
@@ -502,25 +534,8 @@
})(this));
};
Terminal.prototype.linkify = function(t) {
var emailAddressPattern, part, pseudoUrlPattern, urlPattern;
urlPattern = /\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|]/gim;
pseudoUrlPattern = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
emailAddressPattern = /[\w.]+@[a-zA-Z_-]+?(?:\.[a-zA-Z]{2,6})+/gim;
return ((function() {
var k, len, ref, results;
ref = t.split('&nbsp;');
results = [];
for (k = 0, len = ref.length; k < len; k++) {
part = ref[k];
results.push(part.replace(urlPattern, '<a href="$&">$&</a>').replace(pseudoUrlPattern, '$1<a href="http://$2">$2</a>').replace(emailAddressPattern, '<a href="mailto:$&">$&</a>'));
}
return results;
})()).join('&nbsp;');
};
Terminal.prototype.refresh = function(force) {
var active, attr, ch, classes, cursor, data, fg, group, i, j, k, len, len1, len2, len3, len4, line, lines, m, newOut, o, out, q, ref, ref1, ref2, ref3, ref4, ref5, skipnext, styles, u, v, x;
var active, attr, ch, classes, cursor, data, fg, group, i, j, k, len, len1, len2, len3, len4, line, lines, m, modified, newOut, o, out, q, ref, ref1, ref2, ref3, ref4, ref5, skipnext, styles, u, v, x;
if (force == null) {
force = false;
}
@@ -535,6 +550,7 @@
active.classList.remove('active');
}
newOut = '';
modified = [];
ref2 = this.screen;
for (j = o = 0, len2 = ref2.length; o < len2; j = ++o) {
line = ref2[j];
@@ -659,14 +675,12 @@
if (!this.equalAttr(attr, this.defAttr)) {
out += "</span>";
}
if (!(j === this.y + this.shift || data.html)) {
out = this.linkify(out);
}
if (line.wrap) {
out += '\u23CE';
}
if (this.children[j]) {
this.children[j].innerHTML = out;
modified.push(this.children[j]);
if (x !== -Infinity) {
this.children[j].classList.add('active');
}
@@ -679,6 +693,7 @@
group = this.document.createElement('div');
group.className = 'group';
group.innerHTML = newOut;
modified.push(group);
this.body.appendChild(group);
this.screen = this.screen.slice(-this.rows);
this.shift = 0;
@@ -698,7 +713,8 @@
}
this.children = Array.prototype.slice.call(lines, -this.rows);
}
return this.nativeScrollTo();
this.nativeScrollTo();
return this.emit('change', modified);
};
Terminal.prototype._cursorBlink = function() {

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,26 @@
walk = (node, callback) ->
for child in node.childNodes
callback.call(child)
walk child, callback
linkify = (text) ->
# http://stackoverflow.com/questions/37684/how-to-replace-plain-urls-with-links
urlPattern = (
/\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|]/gim)
pseudoUrlPattern = /(^|[^\/])(www\.[\S]+(\b|$))/gim
emailAddressPattern = /[\w.]+@[a-zA-Z_-]+?(?:\.[a-zA-Z]{2,6})+/gim
text
.replace(urlPattern, '<a href="$&">$&</a>')
.replace(pseudoUrlPattern, '$1<a href="http://$2">$2</a>')
.replace(emailAddressPattern, '<a href="mailto:$&">$&</a>')
Terminal.on 'change', (lines) ->
for line in lines
walk line, ->
if @nodeType is 3
linkified = linkify @nodeValue
if linkified isnt @nodeValue
newNode = document.createElement('span')
newNode.innerHTML = linkified
@parentElement.replaceChild newNode, @
true

View File

@@ -28,7 +28,6 @@
# http://bellard.org/jslinux/
cancel = (ev) ->
ev.preventDefault() if ev.preventDefault
ev.stopPropagation() if ev.stopPropagation
@@ -45,7 +44,20 @@ State =
dcs: s++
ignore: s++
class Terminal
@hooks: {}
# Mini implementation of event
@on: (hook, fun) ->
unless Terminal.hooks[hook]?
Terminal.hooks[hook] = []
Terminal.hooks[hook].push(fun)
@off: (hook, fun) ->
unless Terminal.hooks[hook]?
Terminal.hooks[hook] = []
Terminal.hooks[hook].pop(fun)
constructor: (@parent, @out, @ctl=->) ->
# Global elements
@document = @parent.ownerDocument
@@ -102,6 +114,13 @@ class Terminal
@initmouse()
addEventListener 'load', => @resize()
@emit 'load'
emit: (hook, args...) ->
unless Terminal.hooks[hook]?
Terminal.hooks[hook] = []
for fun in Terminal.hooks[hook]
fun.apply(@, args)
cloneAttr: (a, char=null) ->
bg: a.bg
@@ -396,18 +415,6 @@ class Terminal
sendButton ev
cancel ev
linkify: (t) ->
# http://stackoverflow.com/questions/37684/how-to-replace-plain-urls-with-links
urlPattern = (
/\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|]/gim)
pseudoUrlPattern = /(^|[^\/])(www\.[\S]+(\b|$))/gim
emailAddressPattern = /[\w.]+@[a-zA-Z_-]+?(?:\.[a-zA-Z]{2,6})+/gim
(part
.replace(urlPattern, '<a href="$&">$&</a>')
.replace(pseudoUrlPattern, '$1<a href="http://$2">$2</a>')
.replace(emailAddressPattern, '<a href="mailto:$&">$&</a>'
) for part in t.split('&nbsp;')).join('&nbsp;')
refresh: (force=false) ->
for cursor in @body.querySelectorAll(".cursor")
cursor.parentNode.replaceChild(
@@ -416,7 +423,7 @@ class Terminal
active.classList.remove('active')
newOut = ''
modified = []
for line, j in @screen
continue unless line.dirty or force
out = ""
@@ -518,10 +525,10 @@ class Terminal
out += "</span>" if i is x
attr = data
out += "</span>" unless @equalAttr attr, @defAttr
out = @linkify(out) unless j is @y + @shift or data.html
out += '\u23CE' if line.wrap
if @children[j]
@children[j].innerHTML = out
modified.push @children[j]
if x isnt -Infinity
@children[j].classList.add 'active'
else
@@ -533,6 +540,7 @@ class Terminal
group = @document.createElement('div')
group.className = 'group'
group.innerHTML = newOut
modified.push group
@body.appendChild group
@screen = @screen.slice(-@rows)
@shift = 0
@@ -549,6 +557,7 @@ class Terminal
lines, -@rows)
@nativeScrollTo()
@emit 'change', modified
_cursorBlink: ->
@cursorState ^= 1