twitter-text
Advanced tools
Comparing version 1.4.11 to 1.4.12
{ | ||
"name": "twitter-text" | ||
, "description": "official twitter text linkification" | ||
, "version": "1.4.11" | ||
, "version": "1.4.12" | ||
, "main": "./twitter-text.js" | ||
@@ -6,0 +6,0 @@ , "homepage": "https://github.com/twitter/twitter-text-js" |
@@ -43,2 +43,7 @@ | ||
## Changelog | ||
* v1.4.8 - 2011-11-02 [ Git tag v1.4.8 ] | ||
* [FIX] Extract URLs without protocol in CJK text | ||
* [FIX] Do not extract URL in hashtag | ||
* [FIX] Extract hashtag after bracket | ||
* [FIX] Extract URL with '?' in fragment | ||
@@ -45,0 +50,0 @@ * v1.4.7 - 2011-10-04 [ Git tag v1.4.7 ] |
@@ -88,3 +88,3 @@ if (!window.twttr) { | ||
fromCode(0xFEFF), // BOM | ||
fromCode(0xFFFF), // Special | ||
fromCode(0xFFFF) // Special | ||
]; | ||
@@ -98,6 +98,6 @@ addCharsToCharClass(INVALID_CHARS, 0x202A, 0x202E); // Directional change | ||
twttr.txt.regexen.atSigns = /[@@]/; | ||
twttr.txt.regexen.extractMentions = regexSupplant(/(^|[^a-zA-Z0-9_])(#{atSigns})([a-zA-Z0-9_]{1,20})(?=(.|$))/g); | ||
twttr.txt.regexen.extractMentions = regexSupplant(/(^|[^a-zA-Z0-9_])(#{atSigns})([a-zA-Z0-9_]{1,20})/g); | ||
twttr.txt.regexen.extractReply = regexSupplant(/^(?:#{spaces})*#{atSigns}([a-zA-Z0-9_]{1,20})/); | ||
twttr.txt.regexen.listName = /[a-zA-Z][a-zA-Z0-9_\-\u0080-\u00ff]{0,24}/; | ||
twttr.txt.regexen.extractMentionsOrLists = regexSupplant(/(^|[^a-zA-Z0-9_])(#{atSigns})([a-zA-Z0-9_]{1,20})(\/[a-zA-Z][a-zA-Z0-9_\-]{0,24})?(?=(.|$))/g); | ||
twttr.txt.regexen.extractMentionsOrLists = regexSupplant(/(^|[^a-zA-Z0-9_])(#{atSigns})([a-zA-Z0-9_]{1,20})(\/[a-zA-Z][a-zA-Z0-9_\-]{0,24})?/g); | ||
@@ -144,5 +144,6 @@ var nonLatinHashtagChars = []; | ||
// A hashtag must contain characters, numbers and underscores, but not all numbers. | ||
twttr.txt.regexen.hashtagBoundary = regexSupplant(/(?:^|$|#{spaces}|[「」。、.,!!??:;"'])/); | ||
twttr.txt.regexen.hashtagAlpha = regexSupplant(/[a-z_#{latinAccentChars}#{nonLatinHashtagChars}]/i); | ||
twttr.txt.regexen.hashtagAlphaNumeric = regexSupplant(/[a-z0-9_#{latinAccentChars}#{nonLatinHashtagChars}]/i); | ||
twttr.txt.regexen.endHashtagMatch = /^(?:[##]|:\/\/)/; | ||
twttr.txt.regexen.hashtagBoundary = regexSupplant(/(?:^|$|[^&\/a-z0-9_#{latinAccentChars}#{nonLatinHashtagChars}])/); | ||
twttr.txt.regexen.autoLinkHashtags = regexSupplant(/(#{hashtagBoundary})(#|#)(#{hashtagAlphaNumeric}*#{hashtagAlpha}#{hashtagAlphaNumeric}*)/gi); | ||
@@ -153,3 +154,3 @@ twttr.txt.regexen.autoLinkUsernamesOrLists = /(^|[^a-zA-Z0-9_]|RT:?)([@@]+)([a-zA-Z0-9_]{1,20})(\/[a-zA-Z][a-zA-Z0-9_\-]{0,24})?/g; | ||
// URL related hash regex collection | ||
twttr.txt.regexen.validPrecedingChars = regexSupplant(/(?:[^-\/"'!=A-Za-z0-9_@@\.#{invalid_chars_group}]|^)/); | ||
twttr.txt.regexen.validPrecedingChars = regexSupplant(/(?:[^-\/"'!=A-Za-z0-9_@@##\.#{invalid_chars_group}]|^)/); | ||
@@ -164,4 +165,4 @@ twttr.txt.regexen.invalidDomainChars = stringSupplant("#{punct}#{spaces_group}#{invalid_chars_group}", twttr.txt.regexen); | ||
twttr.txt.regexen.validDomain = regexSupplant(/(?:#{validSubdomain}*#{validDomainName}(?:#{validGTLD}|#{validCCTLD}|#{validPunycode}))/); | ||
twttr.txt.regexen.validAsciiDomain = regexSupplant(/(?:(?:[a-z0-9#{latinAccentChars}]+)\.)+(?:#{validGTLD}|#{validCCTLD}|#{validPunycode})/i); | ||
twttr.txt.regexen.validShortDomain = regexSupplant(/^#{validDomainName}#{validCCTLD}$/); | ||
twttr.txt.regexen.validAsciiDomain = regexSupplant(/(?:(?:[a-z0-9#{latinAccentChars}]+)\.)+(?:#{validGTLD}|#{validCCTLD}|#{validPunycode})/gi); | ||
twttr.txt.regexen.invalidShortDomain = regexSupplant(/^#{validDomainName}#{validCCTLD}$/); | ||
@@ -187,3 +188,3 @@ twttr.txt.regexen.validPortNumber = regexSupplant(/[0-9]+/); | ||
twttr.txt.regexen.validUrlQueryChars = /[a-z0-9!\*'\(\);:&=\+\$\/%#\[\]\-_\.,~|]/i; | ||
twttr.txt.regexen.validUrlQueryChars = /[a-z0-9!?\*'\(\);:&=\+\$\/%#\[\]\-_\.,~|]/i; | ||
twttr.txt.regexen.validUrlQueryEndingChars = /[a-z0-9_&=#\/]/i; | ||
@@ -400,3 +401,7 @@ twttr.txt.regexen.extractUrl = regexSupplant( | ||
return text.replace(twttr.txt.regexen.autoLinkHashtags, function(match, before, hash, text) { | ||
return text.replace(twttr.txt.regexen.autoLinkHashtags, function(match, before, hash, text, offset, chunk) { | ||
var after = chunk.slice(offset + match.length); | ||
if (after.match(twttr.txt.regexen.endHashtagMatch)) | ||
return match; | ||
var d = { | ||
@@ -495,3 +500,4 @@ before: before, | ||
text.replace(twttr.txt.regexen.extractMentions, function(match, before, atSign, screenName, after) { | ||
text.replace(twttr.txt.regexen.extractMentions, function(match, before, atSign, screenName, offset, chunk) { | ||
var after = chunk.slice(offset + match.length); | ||
if (!after.match(twttr.txt.regexen.endScreenNameMatch)) { | ||
@@ -522,3 +528,4 @@ var startPosition = text.indexOf(atSign + screenName, position); | ||
text.replace(twttr.txt.regexen.extractMentionsOrLists, function(match, before, atSign, screenName, slashListname, after) { | ||
text.replace(twttr.txt.regexen.extractMentionsOrLists, function(match, before, atSign, screenName, slashListname, offset, chunk) { | ||
var after = chunk.slice(offset + match.length); | ||
if (!after.match(twttr.txt.regexen.endScreenNameMatch)) { | ||
@@ -546,3 +553,4 @@ slashListname = slashListname || ''; | ||
var possibleScreenName = text.match(twttr.txt.regexen.extractReply); | ||
if (!possibleScreenName) { | ||
if (!possibleScreenName || | ||
RegExp.rightContext.match(twttr.txt.regexen.endScreenNameMatch)) { | ||
return null; | ||
@@ -574,24 +582,41 @@ } | ||
text.replace(twttr.txt.regexen.extractUrl, function(match, all, before, url, protocol, domain, port, path, query) { | ||
// If protocol is missing, check against validAsciiDomain | ||
var startPosition = text.indexOf(url, position), | ||
endPosition = startPosition + url.length; | ||
// if protocol is missing and domain contains non-ASCII characters, | ||
// extract ASCII-only domains. | ||
if (!protocol) { | ||
ascii_domain = domain.match(twttr.txt.regexen.validAsciiDomain); | ||
if (!ascii_domain) { | ||
return; | ||
var lastUrl, | ||
lastUrlInvalidMatch = false, | ||
asciiEndPosition = 0; | ||
domain.replace(twttr.txt.regexen.validAsciiDomain, function(asciiDomain) { | ||
var asciiStartPosition = domain.indexOf(asciiDomain, asciiEndPosition); | ||
asciiEndPosition = asciiStartPosition + asciiDomain.length | ||
lastUrl = { | ||
url: asciiDomain, | ||
indices: [startPosition + asciiStartPosition, startPosition + asciiEndPosition] | ||
} | ||
url = url.replace(domain, ascii_domain[0]); | ||
domain = ascii_domain[0]; | ||
} | ||
// Regex in JavaScript doesn't support lookbehind, so we need to manually filter out | ||
// the short URLs without protocol and slash, i.e., [domain].[ccTLD] | ||
if (!protocol && !path && domain.match(twttr.txt.regexen.validShortDomain)) { | ||
return; | ||
} | ||
lastUrlInvalidMatch = asciiDomain.match(twttr.txt.regexen.invalidShortDomain); | ||
if (!lastUrlInvalidMatch) { | ||
urls.push(lastUrl); | ||
} | ||
}); | ||
var startPosition = text.indexOf(url, position), | ||
position = startPosition + url.length; | ||
if (urls.length == 0) { | ||
return; | ||
} | ||
urls.push({ | ||
url: url, | ||
indices: [startPosition, position] | ||
}); | ||
if (path) { | ||
if (lastUrlInvalidMatch) { | ||
urls.push(lastUrl); | ||
} | ||
lastUrl.url = url.replace(domain, lastUrl.url); | ||
lastUrl.indices[1] = endPosition; | ||
} | ||
} else { | ||
urls.push({ | ||
url: url, | ||
indices: [startPosition, endPosition] | ||
}); | ||
} | ||
}); | ||
@@ -621,3 +646,6 @@ | ||
text.replace(twttr.txt.regexen.autoLinkHashtags, function(match, before, hash, hashText) { | ||
text.replace(twttr.txt.regexen.autoLinkHashtags, function(match, before, hash, hashText, offset, chunk) { | ||
var after = chunk.slice(offset + match.length); | ||
if (after.match(twttr.txt.regexen.endHashtagMatch)) | ||
return; | ||
var startPosition = text.indexOf(hash + hashText, position); | ||
@@ -624,0 +652,0 @@ position = startPosition + hashText.length + 1; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Non-existent author
Supply chain riskThe package was published by an npm account that no longer exists.
Found 1 instance in 1 package
966654
43
20979
0
1