]> git.proxmox.com Git - mirror_xterm.js.git/blob - addons/linkify/linkify.js
[addon linkify] Improve URL to link conversion algorithm
[mirror_xterm.js.git] / addons / linkify / linkify.js
1 (function (linkify) {
2 if (typeof define == 'function') {
3 /*
4 * Require.js is available
5 */
6 define(['../../src/xterm'], linkify);
7 } else {
8 /*
9 * Plain browser environment
10 */
11 linkify(this.Xterm);
12 }
13 })(function (Xterm) {
14 'use strict';
15
16 /**
17 * This module provides methods for convertings valid URL substrings
18 * into HTML anchor elements (links), inside a terminal view.
19 *
20 * @module xterm/addons/linkify/linkify
21 */
22 var exports = {},
23 protocolClause = '(https?:\\/\\/)',
24 domainBodyClause = '([\\da-z\\.-]+)',
25 tldClause = '([a-z\\.]{2,6})',
26 hostClause = domainBodyClause + '\\.' + tldClause,
27 pathClause = '([\\/\\w\\.-]*)*\\/?',
28 bodyClause = hostClause + pathClause,
29 start = '(?:^|\\s+)(',
30 end = ')($|\\s+)',
31 urlClause = start + protocolClause + '?' + bodyClause + end,
32 urlRegex = new RegExp(urlClause);
33
34 /**
35 * Converts all valid URLs found in the given terminal line into
36 * hyperlinks. The terminal line can be either the HTML element itself
37 * or the index of the termina line in the children of the terminal
38 * rows container.
39 *
40 * @param {Xterm} terminal - The terminal that owns the given line.
41 * @param {number|HTMLDivElement} line - The terminal line that should get
42 * "linkified".
43 * @emits linkify
44 * @emits linkify:line
45 */
46 exports.linkifyTerminalLine = function (terminal, line) {
47 if (typeof line == 'number') {
48 line = terminal.rowContainer.children[line];
49 } else if (! (line instanceof HTMLDivElement)) {
50 var message = 'The "line" argument should be either a number';
51 message += ' or an HTMLDivElement';
52
53 throw new TypeError(message);
54 }
55
56 var buffer = document.createElement('span'),
57 nodes = line.childNodes;
58
59 console.log(nodes.length, 'number of nodes');
60 for (var j=0; j<nodes.length; j++) {
61 var node = nodes[j];
62
63 /*
64 * Since we cannot access the TextNode's HTML representation
65 * from the instance itself, we assign its data as textContent
66 * to a dummy buffer span, in order to retrieve the TextNode's
67 * HTML representation from the buffer's innerHTML.
68 */
69 buffer.textContent = node.data;
70
71 var nodeHTML = buffer.innerHTML;
72
73 /*
74 * Apply function only on TextNodes
75 */
76 if (node.nodeType != node.TEXT_NODE) {
77 continue;
78 }
79
80
81 var match = node.data.match(urlRegex);
82
83 /*
84 * If no URL was found in the current text, return.
85 */
86 if (!match) {
87 continue;
88 }
89
90 var url = match[1],
91 startsWithProtocol = new RegExp('^' + protocolClause),
92 urlHasProtocol = url.match(startsWithProtocol),
93 href = (urlHasProtocol) ? url : 'http://' + url,
94 link = '<a href="' + href + '" >' + url + '</a>',
95 newHTML = nodeHTML.replace(url, link);
96
97 line.innerHTML = line.innerHTML.replace(nodeHTML, newHTML);
98 }
99
100 /**
101 * This event gets emitted when conversion of all URL susbtrings
102 * to HTML anchor elements (links) has finished, for a specific
103 * line of the current Xterm instance.
104 *
105 * @event linkify:line
106 */
107 terminal.emit('linkify:line', line);
108 };
109
110
111 /**
112 * Converts all valid URLs found in the terminal view into hyperlinks.
113 *
114 * @param {Xterm} terminal - The terminal that should get "linkified".
115 * @emits linkify
116 * @emits linkify:line
117 */
118 exports.linkify = function (terminal) {
119 var rows = terminal.rowContainer.children;
120
121 for (var i=0; i<rows.length; i++) {
122 var line = rows[i];
123
124 exports.linkifyTerminalLine(terminal, line);
125 }
126
127 /**
128 * This event gets emitted when conversion of all URL substrings to
129 * HTML anchor elements (links) has finished for the current Xterm
130 * instance's view.
131 *
132 * @event linkify
133 */
134 terminal.emit('linkify');
135 };
136
137 /*
138 * Extend Xterm prototype.
139 */
140
141 /**
142 * Converts all valid URLs found in the current terminal linte into
143 * hyperlinks.
144 *
145 * @memberof Xterm
146 * @param {number|HTMLDivElement} line - The terminal line that should get
147 * "linkified".
148 */
149 Xterm.prototype.linkifyTerminalLine = function (line) {
150 return exports.linkifyTerminalLine(this, line);
151 };
152
153 /**
154 * Converts all valid URLs found in the current terminal into hyperlinks.
155 *
156 * @memberof Xterm
157 */
158 Xterm.prototype.linkify = function () {
159 return exports.linkify(this);
160 };
161
162 return exports;
163 });