Skip to content

Commit cbffc3d

Browse files
author
Nick Frasser
committed
Merge pull request #74 from SoapBox/2.0.0-beta.4
2.0.0 beta.4
2 parents 68057ad + e118379 commit cbffc3d

File tree

7 files changed

+67
-34
lines changed

7 files changed

+67
-34
lines changed

run-tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
if [[ `echo $TRAVIS_BRANCH` = "master" ]]; then
1+
if [[ `echo $TRAVIS_BRANCH` = "master" && `echo $SAUCE_USERNAME` != "" ]]; then
22
# Run basic and SauceLabs tests
33
echo "Running complete test suite..."
44
npm test || exit 1

src/linkify-element.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const HTML_NODE = 1, TXT_NODE = 3;
88

99
/**
1010
Given a parent element and child node that the parent contains, replaces
11-
that child with the given aary of new children
11+
that child with the given array of new children
1212
*/
1313
function replaceChildWithChildren(parent, oldChild, newChildren) {
1414
let lastNewChild = newChildren[newChildren.length - 1];
@@ -22,9 +22,10 @@ function replaceChildWithChildren(parent, oldChild, newChildren) {
2222
/**
2323
Given an array of MultiTokens, return an array of Nodes that are either
2424
(a) Plain Text nodes (node type 3)
25-
(b) Anchor tag nodes (usually, unless tag name is overriden in the options)
25+
(b) Anchor tag nodes (usually, unless tag name is overridden in the options)
2626
27-
Takes the same options as linkifyElement and an optional doc element (this should be passed in by linkifyElement)
27+
Takes the same options as linkifyElement and an optional doc element
28+
(this should be passed in by linkifyElement)
2829
*/
2930
function tokensToNodes(tokens, opts, doc) {
3031
let result = [];
@@ -96,8 +97,7 @@ function linkifyElementHelper(element, opts, doc) {
9697
return element;
9798
}
9899

99-
let
100-
childElement = element.firstChild;
100+
let childElement = element.firstChild;
101101

102102
while (childElement) {
103103

@@ -145,8 +145,7 @@ function linkifyElement(element, opts, doc=null) {
145145
return linkifyElementHelper(element, opts, doc);
146146
}
147147

148-
// Maintain reference to the recursive helper to save some option-normalization
149-
// cycles
148+
// Maintain reference to the recursive helper to cache option-normalization
150149
linkifyElement.helper = linkifyElementHelper;
151150
linkifyElement.normalize = options.normalize;
152151

src/linkify/core/parser.js

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ TT_DOMAIN = TEXT_TOKENS.DOMAIN,
2323
TT_AT = TEXT_TOKENS.AT,
2424
TT_COLON = TEXT_TOKENS.COLON,
2525
TT_DOT = TEXT_TOKENS.DOT,
26+
TT_PUNCTUATION = TEXT_TOKENS.PUNCTUATION,
2627
TT_LOCALHOST = TEXT_TOKENS.LOCALHOST,
2728
TT_NL = TEXT_TOKENS.NL,
2829
TT_NUM = TEXT_TOKENS.NUM,
@@ -86,9 +87,10 @@ S_PROTOCOL_SLASH.on(TT_SLASH, S_PROTOCOL_SLASH_SLASH);
8687
S_START.on(TT_TLD, S_DOMAIN);
8788
S_START.on(TT_DOMAIN, S_DOMAIN);
8889
S_START.on(TT_LOCALHOST, S_TLD);
89-
S_START.on(TT_NUM, S_LOCALPART);
90+
S_START.on(TT_NUM, S_DOMAIN);
9091
S_PROTOCOL_SLASH_SLASH.on(TT_TLD, S_PSS_DOMAIN);
9192
S_PROTOCOL_SLASH_SLASH.on(TT_DOMAIN, S_PSS_DOMAIN);
93+
S_PROTOCOL_SLASH_SLASH.on(TT_NUM, S_PSS_DOMAIN);
9294
S_PROTOCOL_SLASH_SLASH.on(TT_LOCALHOST, S_PSS_TLD);
9395

9496
// Account for dots and hyphens
@@ -102,12 +104,15 @@ S_EMAIL_DOMAIN.on(TT_DOT, S_EMAIL_DOMAIN_DOT);
102104
// After the first domain and a dot, we can find either a URL or another domain
103105
S_DOMAIN_DOT.on(TT_TLD, S_TLD);
104106
S_DOMAIN_DOT.on(TT_DOMAIN, S_DOMAIN);
107+
S_DOMAIN_DOT.on(TT_NUM, S_DOMAIN);
105108
S_DOMAIN_DOT.on(TT_LOCALHOST, S_DOMAIN);
106109
S_PSS_DOMAIN_DOT.on(TT_TLD, S_PSS_TLD);
107110
S_PSS_DOMAIN_DOT.on(TT_DOMAIN, S_PSS_DOMAIN);
111+
S_PSS_DOMAIN_DOT.on(TT_NUM, S_PSS_DOMAIN);
108112
S_PSS_DOMAIN_DOT.on(TT_LOCALHOST, S_PSS_DOMAIN);
109113
S_EMAIL_DOMAIN_DOT.on(TT_TLD, S_EMAIL);
110114
S_EMAIL_DOMAIN_DOT.on(TT_DOMAIN, S_EMAIL_DOMAIN);
115+
S_EMAIL_DOMAIN_DOT.on(TT_NUM, S_EMAIL_DOMAIN);
111116
S_EMAIL_DOMAIN_DOT.on(TT_LOCALHOST, S_EMAIL_DOMAIN);
112117

113118
// S_TLD accepts! But the URL could be longer, try to find a match greedily
@@ -133,14 +138,14 @@ S_EMAIL_COLON.on(TT_NUM, S_EMAIL_PORT);
133138
let qsAccepting = [
134139
TT_DOMAIN,
135140
TT_AT,
136-
137141
TT_LOCALHOST,
138142
TT_NUM,
139143
TT_PLUS,
140144
TT_POUND,
141145
TT_PROTOCOL,
142146
TT_SLASH,
143-
TT_TLD
147+
TT_TLD,
148+
TT_SYM
144149
];
145150

146151
// Types of tokens that can follow a URL and be part of the query string
@@ -150,7 +155,7 @@ let qsNonAccepting = [
150155
TT_COLON,
151156
TT_DOT,
152157
TT_QUERY,
153-
TT_SYM
158+
TT_PUNCTUATION
154159
];
155160

156161
// Account for the query string
@@ -167,7 +172,6 @@ S_URL_SYMS.on(qsNonAccepting, S_URL_SYMS);
167172
// Tokens allowed in the localpart of the email
168173
let localpartAccepting = [
169174
TT_DOMAIN,
170-
TT_COLON,
171175
TT_NUM,
172176
TT_PLUS,
173177
TT_POUND,
@@ -183,12 +187,6 @@ S_DOMAIN.on(TT_AT, S_LOCALPART_AT);
183187
S_DOMAIN_DOT.on(localpartAccepting, S_LOCALPART);
184188
S_TLD.on(localpartAccepting, S_LOCALPART);
185189
S_TLD.on(TT_AT, S_LOCALPART_AT);
186-
S_TLD_COLON.on(localpartAccepting, S_LOCALPART);
187-
S_TLD_COLON.on(TT_DOT, S_LOCALPART);
188-
S_TLD_COLON.on(TT_AT, S_LOCALPART_AT);
189-
S_TLD_PORT.on(localpartAccepting, S_LOCALPART);
190-
S_TLD_PORT.on(TT_DOT, S_LOCALPART_DOT);
191-
S_TLD_PORT.on(TT_AT, S_LOCALPART_AT);
192190

193191
// Okay we're on a localpart. Now what?
194192
// TODO: IP addresses and what if the email starts with numbers?

src/linkify/core/scanner.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ S_START.on('#', makeState(TOKENS.POUND));
4444
S_START.on('?', makeState(TOKENS.QUERY));
4545
S_START.on('/', makeState(TOKENS.SLASH));
4646
S_START.on(COLON, makeState(TOKENS.COLON));
47+
S_START.on(/[,;!]/, makeState(TOKENS.PUNCTUATION));
4748

4849
// Whitespace jumps
4950
// Tokens of only non-newline whitespace are arbitrarily long

src/linkify/core/tokens.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,15 @@ class DOT extends TextToken {
6363
constructor() { super('.'); }
6464
}
6565

66+
/**
67+
A character class that can surround the URL, but which the URL cannot begin
68+
or end with. Does not include certain English punctuation like parentheses.
69+
70+
@class PUNCTUATION
71+
@extends TextToken
72+
*/
73+
class PUNCTUATION extends TextToken {}
74+
6675
/**
6776
The word localhost (by itself)
6877
@class LOCALHOST
@@ -158,6 +167,7 @@ let text = {
158167
AT,
159168
COLON,
160169
DOT,
170+
PUNCTUATION,
161171
LOCALHOST,
162172
NL: TNL,
163173
NUM,

test/spec/linkify/core/parser-test.js

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ EMAIL = MULTI_TOKENS.EMAIL;
1515
[2] - The values of the tokens the text should result in
1616
*/
1717
var tests = [
18-
// BEGIN: Original linkify tests
1918
[
2019
'google.com',
2120
[URL],
@@ -33,12 +32,12 @@ var tests = [
3332
['there are two tests, ', 'brennan.com', ' and ', 'nick.ca', ' -- do they work?']
3433
], [
3534
'there are two tests!brennan.com. and nick.ca? -- do they work?',
36-
[TEXT, URL, TEXT],
37-
['there are two tests!brennan.com. and ', 'nick.ca', '? -- do they work?']
35+
[TEXT, URL, TEXT, URL, TEXT],
36+
['there are two tests!', 'brennan.com', '. and ', 'nick.ca', '? -- do they work?']
3837
], [
3938
'This [i.imgur.com/ckSj2Ba.jpg)] should also work',
4039
[TEXT, URL, TEXT],
41-
['This [', 'i.imgur.com/ckSj2Ba.jpg', ')] should also work']
40+
['This [', 'i.imgur.com/ckSj2Ba.jpg)]', ' should also work']
4241
], [
4342
'A link is http://nick.is.awesome/?q=nick+amazing&nick=yo%29%30hellp another is http://nick.con/?q=look',
4443
[TEXT, URL, TEXT],
@@ -63,13 +62,10 @@ var tests = [
6362
'This port is too short someport.com: this port is too long http://googgle.com:789023/myQuery this port is just right https://github.com:8080/SoapBox/jQuery-linkify/',
6463
[TEXT, URL, TEXT, URL, TEXT, URL],
6564
['This port is too short ', 'someport.com', ': this port is too long ', 'http://googgle.com:789023/myQuery', ' this port is just right ', 'https://github.com:8080/SoapBox/jQuery-linkify/']
66-
],
67-
// END: Original linkifiy tests
68-
// BEGIN: New linkify tests
69-
[
70-
'The best URL http://google.com/?love=true and t.co',
65+
], [
66+
'The best URL http://google.com/?love=true, and t.co',
7167
[TEXT, URL, TEXT, URL],
72-
['The best URL ', 'http://google.com/?love=true', ' and ', 't.co']
68+
['The best URL ', 'http://google.com/?love=true', ', and ', 't.co']
7369
], [
7470
'Please email me at [email protected]',
7571
[TEXT, EMAIL],
@@ -83,15 +79,42 @@ var tests = [
8379
[URL, TEXT],
8480
['http://500-px.com', ' is a real domain?']
8581
], [
86-
'IP loops like email? [email protected] works!!',
82+
'IP loops like email? [email protected]! works!!',
8783
[TEXT, EMAIL, TEXT],
88-
['IP loops like email? ', '[email protected]', ' works!!']
84+
['IP loops like email? ', '[email protected]', '! works!!']
8985
], [
90-
'Url like bro-215.co with a hyphen?',
86+
'Url like bro-215.co; with a hyphen?',
9187
[TEXT, URL, TEXT],
92-
['Url like ', 'bro-215.co', ' with a hyphen?']
88+
['Url like ', 'bro-215.co', '; with a hyphen?']
89+
], [
90+
'This URL http://23456789098.sydney is a number',
91+
[TEXT, URL, TEXT],
92+
['This URL ', 'http://23456789098.sydney', ' is a number']
93+
], [
94+
'This URL http://23456789098.sydney is a number',
95+
[TEXT, URL, TEXT],
96+
['This URL ', 'http://23456789098.sydney', ' is a number']
97+
], [
98+
'A URL with only numbers is 123.456.ca another is //7.8.com/?wat=1 is valid',
99+
[TEXT, URL, TEXT, URL, TEXT],
100+
['A URL with only numbers is ', '123.456.ca', ' another is ', '//7.8.com/?wat=1', ' is valid']
101+
], [
102+
'URL Numbers 6.wat.78.where.eu and u.0.e.9.kp',
103+
[TEXT, URL, TEXT, URL],
104+
['URL Numbers ', '6.wat.78.where.eu', ' and ', 'u.0.e.9.kp']
105+
], [
106+
'Emails like nick:[email protected] do not have colons in them',
107+
[TEXT, EMAIL, TEXT],
108+
['Emails like nick:', '[email protected]', ' do not have colons in them']
109+
], [
110+
'Emails cannot have two dots, e.g.: [email protected]',
111+
[TEXT, EMAIL],
112+
['Emails cannot have two dots, e.g.: nick..', '[email protected]']
113+
], [
114+
'The `mailto:` part should not be included in mailto:[email protected]',
115+
[TEXT, EMAIL],
116+
['The `mailto:` part should not be included in mailto:', '[email protected]']
93117
]
94-
// END: New linkify tests
95118
];
96119

97120
describe('linkify/core/parser#run()', function () {

test/spec/linkify/core/scanner-test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ DOMAIN = TEXT_TOKENS.DOMAIN,
77
AT = TEXT_TOKENS.AT,
88
COLON = TEXT_TOKENS.COLON,
99
DOT = TEXT_TOKENS.DOT,
10+
PUNCTUATION = TEXT_TOKENS.PUNCTUATION,
1011
LOCALHOST = TEXT_TOKENS.LOCALHOST,
1112
NL = TEXT_TOKENS.NL,
1213
NUM = TEXT_TOKENS.NUM,
@@ -35,6 +36,7 @@ var tests = [
3536
['/', [SLASH], ['/']],
3637
['&', [SYM], ['&']],
3738
['&?<>(', [SYM, QUERY, SYM, SYM, SYM], ['&', '?', '<', '>', '(']],
39+
['!,;', [PUNCTUATION, PUNCTUATION, PUNCTUATION], ['!', ',', ';']],
3840
['hello', [DOMAIN], ['hello']],
3941
['Hello123', [DOMAIN], ['Hello123']],
4042
['hello123world', [DOMAIN], ['hello123world']],

0 commit comments

Comments
 (0)