From 23cfa3d8240291d3d854392f0c50db7877818d63 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Tue, 7 Jun 2016 22:12:38 -0700 Subject: [PATCH 1/3] Add IP addresses to linkify Fixes #91 --- addons/linkify/linkify.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/addons/linkify/linkify.js b/addons/linkify/linkify.js index 152404d4..8b222564 100644 --- a/addons/linkify/linkify.js +++ b/addons/linkify/linkify.js @@ -30,8 +30,10 @@ negatedDomainCharacterSet = '[^\\da-z\\.-]+', domainBodyClause = '(' + domainCharacterSet + ')', tldClause = '([a-z\\.]{2,6})', - hostClause = domainBodyClause + '\\.' + tldClause, - pathClause = '([\\/\\w\\.-]*)*\\/?', + ipClause = '((\\d{1,3}\\.){3}\\d{1,3})', + portClause = '(:\\d{1,5})', + hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|(' + ipClause + portClause + '?))', + pathClause = '(\\/[\\/\\w\\.-]*)*', negatedPathCharacterSet = '[^\\/\\w\\.-]+', bodyClause = hostClause + pathClause, start = '(?:^|' + negatedDomainCharacterSet + ')(', @@ -41,7 +43,6 @@ lenientUrlRegex = new RegExp(lenientUrlClause), strictUrlRegex = new RegExp(strictUrlClause); - /** * Converts all valid URLs found in the given terminal line into * hyperlinks. The terminal line can be either the HTML element itself From 9c3b1105e28e829d82f70690fb1170eb89a467d1 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 10 Jun 2016 13:15:59 -0700 Subject: [PATCH 2/3] Check optional port clause after domain too --- addons/linkify/linkify.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/linkify/linkify.js b/addons/linkify/linkify.js index 8b222564..344bc711 100644 --- a/addons/linkify/linkify.js +++ b/addons/linkify/linkify.js @@ -32,7 +32,7 @@ tldClause = '([a-z\\.]{2,6})', ipClause = '((\\d{1,3}\\.){3}\\d{1,3})', portClause = '(:\\d{1,5})', - hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|(' + ipClause + portClause + '?))', + hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + ')' + portClause + '?', pathClause = '(\\/[\\/\\w\\.-]*)*', negatedPathCharacterSet = '[^\\/\\w\\.-]+', bodyClause = hostClause + pathClause, From f2f0f460c4ecf5dd61097937bf4292cf77d516c7 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 10 Jun 2016 18:53:32 -0700 Subject: [PATCH 3/3] Add a bunch of tests --- addons/linkify/linkify.js | 29 ++++++++++++---------- package.json | 2 +- test/addons/linkify-test.js | 48 +++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 test/addons/linkify-test.js diff --git a/addons/linkify/linkify.js b/addons/linkify/linkify.js index 344bc711..f02c2023 100644 --- a/addons/linkify/linkify.js +++ b/addons/linkify/linkify.js @@ -91,22 +91,13 @@ continue; } + var url = exports.findLinkMatch(node.data, lenient); - if (lenient) { - match = node.data.match(lenientUrlRegex); - } else { - match = node.data.match(strictUrlRegex); - } - - /** - * If no URL was found in the current text, return. - */ - if (!match) { + if (!url) { continue; } - var url = match[1], - startsWithProtocol = new RegExp('^' + protocolClause), + var startsWithProtocol = new RegExp('^' + protocolClause), urlHasProtocol = url.match(startsWithProtocol), href = (urlHasProtocol) ? url : 'http://' + url, link = '' + url + '', @@ -125,6 +116,20 @@ terminal.emit('linkify:line', line); }; + /** + * Finds a link within a block of text. + * + * @param {string} text - The text to search . + * @param {boolean} lenient - Whether to use the lenient search. + * @return {string} A URL. + */ + exports.findLinkMatch = function (text, lenient) { + var match = text.match(lenient ? lenientUrlRegex : strictUrlRegex); + if (!match || match.length === 0) { + return null; + } + return match[1]; + } /** * Converts all valid URLs found in the terminal view into hyperlinks. diff --git a/package.json b/package.json index 73fde3c7..f1d3e577 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,6 @@ }, "scripts": { "start": "bash bin/server", - "test": "bash bin/test" + "test": "bash bin/test --recursive" } } diff --git a/test/addons/linkify-test.js b/test/addons/linkify-test.js new file mode 100644 index 00000000..7cb23186 --- /dev/null +++ b/test/addons/linkify-test.js @@ -0,0 +1,48 @@ +var assert = require('chai').assert; +var Terminal = require('../../src/xterm'); +var linkify = require('../../addons/linkify/linkify'); + +describe('linkify addon', function () { + var xterm; + + describe('API', function () { + it('should define Terminal.prototype.linkify', function () { + assert.isDefined(Terminal.prototype.linkify); + }); + it('should define Terminal.prototype.linkifyTerminalLine', function () { + assert.isDefined(Terminal.prototype.linkifyTerminalLine); + }); + }); + + describe('findUrlMatchOnLine', function () { + describe('strict regex', function () { + it('should match when the entire text is a match', function () { + assert.equal(linkify.findLinkMatch('http://github.com', false), 'http://github.com'); + assert.equal(linkify.findLinkMatch('http://127.0.0.1', false), 'http://127.0.0.1'); + }); + it('should match simple domains', function () { + assert.equal(linkify.findLinkMatch('foo http://github.com bar', false), 'http://github.com'); + assert.equal(linkify.findLinkMatch('foo http://www.github.com bar', false), 'http://www.github.com'); + assert.equal(linkify.findLinkMatch('foo https://github.com bar', false), 'https://github.com'); + assert.equal(linkify.findLinkMatch('foo https://www.github.com bar', false), 'https://www.github.com'); + }); + it('should match web addresses with alpha paths', function () { + assert.equal(linkify.findLinkMatch('foo http://github.com/a/b/c bar', false), 'http://github.com/a/b/c'); + assert.equal(linkify.findLinkMatch('foo http://www.github.com/a/b/c bar', false), 'http://www.github.com/a/b/c'); + }); + it('should not include whitespace surrounding a match', function () { + assert.equal(linkify.findLinkMatch(' http://github.com', false), 'http://github.com'); + assert.equal(linkify.findLinkMatch('http://github.com ', false), 'http://github.com'); + assert.equal(linkify.findLinkMatch(' http://github.com ', false), 'http://github.com'); + }); + it('should match IP addresses', function () { + assert.equal(linkify.findLinkMatch('foo http://127.0.0.1 bar', false), 'http://127.0.0.1'); + assert.equal(linkify.findLinkMatch('foo https://127.0.0.1 bar', false), 'https://127.0.0.1'); + }); + it('should match ports on both domains and IP addresses', function () { + assert.equal(linkify.findLinkMatch('foo http://127.0.0.1:8080 bar', false), 'http://127.0.0.1:8080'); + assert.equal(linkify.findLinkMatch('foo http://www.github.com:8080 bar', false), 'http://www.github.com:8080'); + }); + }); + }); +});