]> git.proxmox.com Git - mirror_xterm.js.git/blame - addons/linkify/linkify.js
Add a bunch of tests
[mirror_xterm.js.git] / addons / linkify / linkify.js
CommitLineData
b60903a2 1(function (linkify) {
fff56eea
PK
2 if (typeof exports === 'object' && typeof module === 'object') {
3 /*
4 * CommonJS environment
5 */
dc67c945 6 module.exports = linkify(require('../../src/xterm'));
fff56eea
PK
7 } else if (typeof define == 'function') {
8 /*
9 * Require.js is available
10 */
11 define(['../../src/xterm'], linkify);
12 } else {
13 /*
dc67c945
PK
14 * Plain browser environment
15 */
fff56eea
PK
16 linkify(this.Xterm);
17 }
b60903a2 18})(function (Xterm) {
fff56eea
PK
19 'use strict';
20
21 /**
22 * This module provides methods for convertings valid URL substrings
23 * into HTML anchor elements (links), inside a terminal view.
24 *
25 * @module xterm/addons/linkify/linkify
26 */
27 var exports = {},
28 protocolClause = '(https?:\\/\\/)',
29 domainCharacterSet = '[\\da-z\\.-]+',
30 negatedDomainCharacterSet = '[^\\da-z\\.-]+',
31 domainBodyClause = '(' + domainCharacterSet + ')',
32 tldClause = '([a-z\\.]{2,6})',
23cfa3d8
DI
33 ipClause = '((\\d{1,3}\\.){3}\\d{1,3})',
34 portClause = '(:\\d{1,5})',
9c3b1105 35 hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + ')' + portClause + '?',
23cfa3d8 36 pathClause = '(\\/[\\/\\w\\.-]*)*',
fff56eea
PK
37 negatedPathCharacterSet = '[^\\/\\w\\.-]+',
38 bodyClause = hostClause + pathClause,
39 start = '(?:^|' + negatedDomainCharacterSet + ')(',
40 end = ')($|' + negatedPathCharacterSet + ')',
41 lenientUrlClause = start + protocolClause + '?' + bodyClause + end,
42 strictUrlClause = start + protocolClause + bodyClause + end,
43 lenientUrlRegex = new RegExp(lenientUrlClause),
44 strictUrlRegex = new RegExp(strictUrlClause);
45
fff56eea
PK
46 /**
47 * Converts all valid URLs found in the given terminal line into
48 * hyperlinks. The terminal line can be either the HTML element itself
49 * or the index of the termina line in the children of the terminal
50 * rows container.
51 *
52 * @param {Xterm} terminal - The terminal that owns the given line.
53 * @param {number|HTMLDivElement} line - The terminal line that should get
54 * "linkified".
55 * @param {boolean} lenient - The regex type that will be used to identify links. If lenient is
56 * false, the regex requires a protocol clause. Defaults to true.
57 * @emits linkify
58 * @emits linkify:line
59 */
60 exports.linkifyTerminalLine = function (terminal, line, lenient) {
61 if (typeof line == 'number') {
62 line = terminal.rowContainer.children[line];
63 } else if (! (line instanceof HTMLDivElement)) {
64 var message = 'The "line" argument should be either a number';
65 message += ' or an HTMLDivElement';
66
67 throw new TypeError(message);
68 }
b1058b9f 69
fff56eea
PK
70 var buffer = document.createElement('span'),
71 nodes = line.childNodes;
72
73 for (var j=0; j<nodes.length; j++) {
74 var node = nodes[j],
75 match;
76
77 /**
78 * Since we cannot access the TextNode's HTML representation
79 * from the instance itself, we assign its data as textContent
80 * to a dummy buffer span, in order to retrieve the TextNode's
81 * HTML representation from the buffer's innerHTML.
82 */
83 buffer.textContent = node.data;
84
85 var nodeHTML = buffer.innerHTML;
86
87 /**
88 * Apply function only on TextNodes
89 */
90 if (node.nodeType != node.TEXT_NODE) {
91 continue;
92 }
93
f2f0f460 94 var url = exports.findLinkMatch(node.data, lenient);
fff56eea 95
f2f0f460 96 if (!url) {
fff56eea
PK
97 continue;
98 }
99
f2f0f460 100 var startsWithProtocol = new RegExp('^' + protocolClause),
fff56eea
PK
101 urlHasProtocol = url.match(startsWithProtocol),
102 href = (urlHasProtocol) ? url : 'http://' + url,
103 link = '<a href="' + href + '" >' + url + '</a>',
104 newHTML = nodeHTML.replace(url, link);
105
106 line.innerHTML = line.innerHTML.replace(nodeHTML, newHTML);
107 }
c8a497eb
PK
108
109 /**
fff56eea
PK
110 * This event gets emitted when conversion of all URL susbtrings
111 * to HTML anchor elements (links) has finished, for a specific
112 * line of the current Xterm instance.
c8a497eb 113 *
fff56eea 114 * @event linkify:line
c8a497eb 115 */
fff56eea
PK
116 terminal.emit('linkify:line', line);
117 };
118
f2f0f460
DI
119 /**
120 * Finds a link within a block of text.
121 *
122 * @param {string} text - The text to search .
123 * @param {boolean} lenient - Whether to use the lenient search.
124 * @return {string} A URL.
125 */
126 exports.findLinkMatch = function (text, lenient) {
127 var match = text.match(lenient ? lenientUrlRegex : strictUrlRegex);
128 if (!match || match.length === 0) {
129 return null;
130 }
131 return match[1];
132 }
fff56eea
PK
133
134 /**
135 * Converts all valid URLs found in the terminal view into hyperlinks.
136 *
137 * @param {Xterm} terminal - The terminal that should get "linkified".
138 * @param {boolean} lenient - The regex type that will be used to identify links. If lenient is
139 * false, the regex requires a protocol clause. Defaults to true.
140 * @emits linkify
141 * @emits linkify:line
142 */
143 exports.linkify = function (terminal, lenient) {
144 var rows = terminal.rowContainer.children;
145
146 lenient = (typeof lenient == "boolean") ? lenient : true;
147 for (var i=0; i<rows.length; i++) {
148 var line = rows[i];
149
150 exports.linkifyTerminalLine(terminal, line, lenient);
151 }
c8a497eb
PK
152
153 /**
fff56eea
PK
154 * This event gets emitted when conversion of all URL substrings to
155 * HTML anchor elements (links) has finished for the current Xterm
156 * instance's view.
c8a497eb 157 *
fff56eea 158 * @event linkify
c8a497eb 159 */
fff56eea
PK
160 terminal.emit('linkify');
161 };
162
163 /**
164 * Extend Xterm prototype.
165 */
166
167 /**
dc67c945
PK
168 * Converts all valid URLs found in the current terminal linte into
169 * hyperlinks.
fff56eea 170 *
dc67c945
PK
171 * @memberof Xterm
172 * @param {number|HTMLDivElement} line - The terminal line that should get
173 * "linkified".
174 * @param {boolean} lenient - The regex type that will be used to identify links. If lenient is
175 * false, the regex requires a protocol clause. Defaults to true.
fff56eea 176 */
dc67c945
PK
177 Xterm.prototype.linkifyTerminalLine = function (line, lenient) {
178 return exports.linkifyTerminalLine(this, line, lenient);
fff56eea
PK
179 };
180
181 /**
dc67c945
PK
182 * Converts all valid URLs found in the current terminal into hyperlinks.
183 *
184 * @memberof Xterm
185 * @param {boolean} lenient - The regex type that will be used to identify links. If lenient is
186 * false, the regex requires a protocol clause. Defaults to true.
fff56eea 187 */
dc67c945
PK
188 Xterm.prototype.linkify = function (lenient) {
189 return exports.linkify(this, lenient);
190 };
c8a497eb 191
fff56eea 192 return exports;
b1058b9f 193});