2021-05-28 16:46:29 +02:00
/ * *
* Finite State Machine generation utilities
* /
/ * *
* Define a basic state machine state . j is the list of character transitions ,
* jr is the list of regex - match transitions , jd is the default state to
* transition to t is the accepting token type , if any . If this is the terminal
* state , then it does not emit a token .
* @ param { string | class } token to emit
* /
function State ( token ) {
this . j = { } ; // IMPLEMENTATION 1
// this.j = []; // IMPLEMENTATION 2
this . jr = [ ] ;
this . jd = null ;
this . t = token ;
}
/ * *
* Take the transition from this state to the next one on the given input .
* If this state does not exist deterministically , will create it .
*
* @ param { string } input character or token to transition on
* @ param { string | class } [ token ] token or multi - token to emit when reaching
* this state
* /
State . prototype = {
/ * *
* @ param { State } state
* /
accepts : function accepts ( ) {
return ! ! this . t ;
} ,
/ * *
* Short for "take transition" , this is a method for building / working with
* state machines .
*
* If a state already exists for the given input , returns it .
*
* If a token is specified , that state will emit that token when reached by
* the linkify engine .
*
* If no state exists , it will be initialized with some default transitions
* that resemble existing default transitions .
*
* If a state is given for the second argument , that state will be
* transitioned to on the given input regardless of what that input
* previously did .
*
* @ param { string } input character or token to transition on
* @ param { Token | State } tokenOrState transition to a matching state
* @ returns State taken after the given input
* /
tt : function tt ( input , tokenOrState ) {
if ( tokenOrState && tokenOrState . j ) {
// State, default a basic transition
this . j [ input ] = tokenOrState ;
return tokenOrState ;
} // See if there's a direct state transition (not regex or default)
var token = tokenOrState ;
var nextState = this . j [ input ] ;
if ( nextState ) {
if ( token ) {
nextState . t = token ;
} // overrwites previous token
return nextState ;
} // Create a new state for this input
nextState = makeState ( ) ; // Take the transition using the usual default mechanisms
var templateState = takeT ( this , input ) ;
if ( templateState ) {
// Some default state transition, make a prime state based on this one
Object . assign ( nextState . j , templateState . j ) ;
nextState . jr . append ( templateState . jr ) ;
nextState . jr = templateState . jd ;
nextState . t = token || templateState . t ;
} else {
nextState . t = token ;
}
this . j [ input ] = nextState ;
return nextState ;
}
} ;
/ * *
* Utility function to create state without using new keyword ( reduced file size
* when minified )
* /
var makeState = function makeState ( ) {
return new State ( ) ;
} ;
/ * *
* Similar to previous except it is an accepting state that emits a token
* @ param { Token } token
* /
var makeAcceptingState = function makeAcceptingState ( token ) {
return new State ( token ) ;
} ;
/ * *
* Create a transition from startState to nextState via the given character
* @ param { State } startState transition from thie starting state
* @ param { Token } input via this input character or other concrete token type
* @ param { State } nextState to this next state
* /
var makeT = function makeT ( startState , input , nextState ) {
// IMPLEMENTATION 1: Add to object (fast)
if ( ! startState . j [ input ] ) {
startState . j [ input ] = nextState ;
} // IMPLEMENTATION 2: Add to array (slower)
// startState.j.push([input, nextState]);
} ;
/ * *
*
* @ param { State } startState stransition from this starting state
* @ param { RegExp } regex Regular expression to match on input
* @ param { State } nextState transition to this next state if there ' s are regex match
* /
var makeRegexT = function makeRegexT ( startState , regex , nextState ) {
startState . jr . push ( [ regex , nextState ] ) ;
} ;
/ * *
* Follow the transition from the given character to the next state
* @ param { State } state
* @ param { Token } input character or other concrete token type to transition
* @ returns { ? State } the next state , if any
* /
var takeT = function takeT ( state , input ) {
// IMPLEMENTATION 1: Object key lookup (faster)
var nextState = state . j [ input ] ;
if ( nextState ) {
return nextState ;
} // IMPLEMENTATION 2: List lookup (slower)
// Loop through all the state transitions and see if there's a match
// for (let i = 0; i < state.j.length; i++) {
// const val = state.j[i][0];
// const nextState = state.j[i][1];
// if (input === val) { return nextState; }
// }
for ( var i = 0 ; i < state . jr . length ; i ++ ) {
var regex = state . jr [ i ] [ 0 ] ;
var _nextState = state . jr [ i ] [ 1 ] ;
if ( regex . test ( input ) ) {
return _nextState ;
}
} // Nowhere left to jump! Return default, if any
return state . jd ;
} ;
/ * *
* Similar to makeT , but takes a list of characters that all transition to the
* same nextState startState
* @ param { State } startState
* @ param { Array } chars
* @ param { State } nextState
* /
var makeMultiT = function makeMultiT ( startState , chars , nextState ) {
for ( var i = 0 ; i < chars . length ; i ++ ) {
makeT ( startState , chars [ i ] , nextState ) ;
}
} ;
/ * *
* Set up a list of multiple transitions at once . transitions is a list of
* tuples , where the first element is the transitions character and the second
* is the state to transition to
* @ param { State } startState
* @ param { Array } transitions
* /
var makeBatchT = function makeBatchT ( startState , transitions ) {
for ( var i = 0 ; i < transitions . length ; i ++ ) {
var input = transitions [ i ] [ 0 ] ;
var nextState = transitions [ i ] [ 1 ] ;
makeT ( startState , input , nextState ) ;
}
} ;
/ * *
* For state machines that transition on characters only ; given a non - empty
* target string , generates states ( if required ) for each consecutive substring
* of characters starting from the beginning of the string . The final state will
* have a special value , as specified in options . All other "in between"
* substrings will have a default end state .
*
* This turns the state machine into a Trie - like data structure ( rather than a
* intelligently - designed DFA ) .
* @ param { State } state
* @ param { string } str
* @ param { Token } endStateFactory
* @ param { Token } defaultStateFactory
* /
var makeChainT = function makeChainT ( state , str , endState , defaultStateFactory ) {
var i = 0 ,
len = str . length ,
nextState ; // Find the next state without a jump to the next character
while ( i < len && ( nextState = state . j [ str [ i ] ] ) ) {
state = nextState ;
i ++ ;
}
if ( i >= len ) {
return [ ] ;
} // no new tokens were added
while ( i < len - 1 ) {
nextState = defaultStateFactory ( ) ;
makeT ( state , str [ i ] , nextState ) ;
state = nextState ;
i ++ ;
}
makeT ( state , str [ len - 1 ] , endState ) ;
} ;
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Text Tokens
Tokens composed of strings
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
// A valid web domain token
var DOMAIN = 'DOMAIN' ;
var LOCALHOST = 'LOCALHOST' ; // special case of domain
// Valid top-level domain (see tlds.js)
2022-01-19 15:03:45 +01:00
var TLD = 'TLD' ; // Any sequence of digits 0-9
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var NUM = 'NUM' ; // A web URL protocol. Supported types include
// - `http:`
// - `https:`
// - `ftp:`
// - `ftps:`
// - user-defined custom protocols
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var PROTOCOL = 'PROTOCOL' ; // Start of the email URI protocol
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var MAILTO = 'MAILTO' ; // mailto:
// Any number of consecutive whitespace characters that are not newline
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var WS = 'WS' ; // New line (unix style)
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var NL = 'NL' ; // \n
// Opening/closing bracket classes
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var OPENBRACE = 'OPENBRACE' ; // {
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var OPENBRACKET = 'OPENBRACKET' ; // [
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var OPENANGLEBRACKET = 'OPENANGLEBRACKET' ; // <
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var OPENPAREN = 'OPENPAREN' ; // (
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var CLOSEBRACE = 'CLOSEBRACE' ; // }
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var CLOSEBRACKET = 'CLOSEBRACKET' ; // ]
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var CLOSEANGLEBRACKET = 'CLOSEANGLEBRACKET' ; // >
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var CLOSEPAREN = 'CLOSEPAREN' ; // )
// Various symbols
var AMPERSAND = 'AMPERSAND' ; // &
var APOSTROPHE = 'APOSTROPHE' ; // '
var ASTERISK = 'ASTERISK' ; // *
var AT = 'AT' ; // @
var BACKSLASH = 'BACKSLASH' ; // \
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var BACKTICK = 'BACKTICK' ; // `
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var CARET = 'CARET' ; // ^
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var COLON = 'COLON' ; // :
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var COMMA = 'COMMA' ; // ,
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var DOLLAR = 'DOLLAR' ; // $
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var DOT = 'DOT' ; // .
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var EQUALS = 'EQUALS' ; // =
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var EXCLAMATION = 'EXCLAMATION' ; // !
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var HYPHEN = 'HYPHEN' ; // -
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var PERCENT = 'PERCENT' ; // %
var PIPE = 'PIPE' ; // |
var PLUS = 'PLUS' ; // +
var POUND = 'POUND' ; // #
var QUERY = 'QUERY' ; // ?
var QUOTE = 'QUOTE' ; // "
var SEMI = 'SEMI' ; // ;
var SLASH = 'SLASH' ; // /
var TILDE = 'TILDE' ; // ~
var UNDERSCORE = 'UNDERSCORE' ; // _
2021-05-28 16:46:29 +02:00
// Default token - anything that is not one of the above
var SYM = 'SYM' ;
var text = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
DOMAIN : DOMAIN ,
LOCALHOST : LOCALHOST ,
TLD : TLD ,
NUM : NUM ,
PROTOCOL : PROTOCOL ,
MAILTO : MAILTO ,
WS : WS ,
2022-01-19 15:03:45 +01:00
NL : NL ,
2021-05-28 16:46:29 +02:00
OPENBRACE : OPENBRACE ,
OPENBRACKET : OPENBRACKET ,
OPENANGLEBRACKET : OPENANGLEBRACKET ,
OPENPAREN : OPENPAREN ,
CLOSEBRACE : CLOSEBRACE ,
CLOSEBRACKET : CLOSEBRACKET ,
CLOSEANGLEBRACKET : CLOSEANGLEBRACKET ,
CLOSEPAREN : CLOSEPAREN ,
AMPERSAND : AMPERSAND ,
2022-01-19 15:03:45 +01:00
APOSTROPHE : APOSTROPHE ,
ASTERISK : ASTERISK ,
AT : AT ,
BACKSLASH : BACKSLASH ,
BACKTICK : BACKTICK ,
CARET : CARET ,
COLON : COLON ,
COMMA : COMMA ,
DOLLAR : DOLLAR ,
DOT : DOT ,
EQUALS : EQUALS ,
EXCLAMATION : EXCLAMATION ,
HYPHEN : HYPHEN ,
PERCENT : PERCENT ,
PIPE : PIPE ,
PLUS : PLUS ,
POUND : POUND ,
QUERY : QUERY ,
QUOTE : QUOTE ,
SEMI : SEMI ,
SLASH : SLASH ,
TILDE : TILDE ,
UNDERSCORE : UNDERSCORE ,
2021-05-28 16:46:29 +02:00
SYM : SYM
} ) ;
// NOTE: punycode versions of IDNs are not included here because these will not
// be as commonly used without the http prefix anyway and linkify will already
// force-encode those.
// To be updated with the values in this list
// http://data.iana.org/TLD/tlds-alpha-by-domain.txt
// Version 2021022800, Last Updated Sun Feb 28 07:07:01 2021 UTC
var tlds = ' aaa \
aarp \
abarth \
abb \
abbott \
abbvie \
abc \
able \
abogado \
abudhabi \
ac \
academy \
accenture \
accountant \
accountants \
aco \
actor \
ad \
adac \
ads \
adult \
ae \
aeg \
aero \
aetna \
af \
afamilycompany \
afl \
africa \
ag \
agakhan \
agency \
ai \
aig \
airbus \
airforce \
airtel \
akdn \
al \
alfaromeo \
alibaba \
alipay \
allfinanz \
allstate \
ally \
alsace \
alstom \
am \
amazon \
americanexpress \
americanfamily \
amex \
amfam \
amica \
amsterdam \
analytics \
android \
anquan \
anz \
ao \
aol \
apartments \
app \
apple \
aq \
aquarelle \
ar \
arab \
aramco \
archi \
army \
arpa \
art \
arte \
as \
asda \
asia \
associates \
at \
athleta \
attorney \
au \
auction \
audi \
audible \
audio \
auspost \
author \
auto \
autos \
avianca \
aw \
aws \
ax \
axa \
az \
azure \
ba \
baby \
baidu \
banamex \
bananarepublic \
band \
bank \
bar \
barcelona \
barclaycard \
barclays \
barefoot \
bargains \
baseball \
basketball \
bauhaus \
bayern \
bb \
bbc \
bbt \
bbva \
bcg \
bcn \
bd \
be \
beats \
beauty \
beer \
bentley \
berlin \
best \
bestbuy \
bet \
bf \
bg \
bh \
bharti \
bi \
bible \
bid \
bike \
bing \
bingo \
bio \
biz \
bj \
black \
blackfriday \
blockbuster \
blog \
bloomberg \
blue \
bm \
bms \
bmw \
bn \
bnpparibas \
bo \
boats \
boehringer \
bofa \
bom \
bond \
boo \
book \
booking \
bosch \
bostik \
boston \
bot \
boutique \
box \
br \
bradesco \
bridgestone \
broadway \
broker \
brother \
brussels \
bs \
bt \
budapest \
bugatti \
build \
builders \
business \
buy \
buzz \
bv \
bw \
by \
bz \
bzh \
ca \
cab \
cafe \
cal \
call \
calvinklein \
cam \
camera \
camp \
cancerresearch \
canon \
capetown \
capital \
capitalone \
car \
caravan \
cards \
care \
career \
careers \
cars \
casa \
case \
cash \
casino \
cat \
catering \
catholic \
cba \
cbn \
cbre \
cbs \
cc \
cd \
center \
ceo \
cern \
cf \
cfa \
cfd \
cg \
ch \
chanel \
channel \
charity \
chase \
chat \
cheap \
chintai \
christmas \
chrome \
church \
ci \
cipriani \
circle \
cisco \
citadel \
citi \
citic \
city \
cityeats \
ck \
cl \
claims \
cleaning \
click \
clinic \
clinique \
clothing \
cloud \
club \
clubmed \
cm \
cn \
co \
coach \
codes \
coffee \
college \
cologne \
com \
comcast \
commbank \
community \
company \
compare \
computer \
comsec \
condos \
construction \
consulting \
contact \
contractors \
cooking \
cookingchannel \
cool \
coop \
corsica \
country \
coupon \
coupons \
courses \
cpa \
cr \
credit \
creditcard \
creditunion \
cricket \
crown \
crs \
cruise \
cruises \
csc \
cu \
cuisinella \
cv \
cw \
cx \
cy \
cymru \
cyou \
cz \
dabur \
dad \
dance \
data \
date \
dating \
datsun \
day \
dclk \
dds \
de \
deal \
dealer \
deals \
degree \
delivery \
dell \
deloitte \
delta \
democrat \
dental \
dentist \
desi \
design \
dev \
dhl \
diamonds \
diet \
digital \
direct \
directory \
discount \
discover \
dish \
diy \
dj \
dk \
dm \
dnp \
do \
docs \
doctor \
dog \
domains \
dot \
download \
drive \
dtv \
dubai \
duck \
dunlop \
dupont \
durban \
dvag \
dvr \
dz \
earth \
eat \
ec \
eco \
edeka \
edu \
education \
ee \
eg \
email \
emerck \
energy \
engineer \
engineering \
enterprises \
epson \
equipment \
er \
ericsson \
erni \
es \
esq \
estate \
et \
etisalat \
eu \
eurovision \
eus \
events \
exchange \
expert \
exposed \
express \
extraspace \
fage \
fail \
fairwinds \
faith \
family \
fan \
fans \
farm \
farmers \
fashion \
fast \
fedex \
feedback \
ferrari \
ferrero \
fi \
fiat \
fidelity \
fido \
film \
final \
finance \
financial \
fire \
firestone \
firmdale \
fish \
fishing \
fit \
fitness \
fj \
fk \
flickr \
flights \
flir \
florist \
flowers \
fly \
fm \
fo \
foo \
food \
foodnetwork \
football \
ford \
forex \
forsale \
forum \
foundation \
fox \
fr \
free \
fresenius \
frl \
frogans \
frontdoor \
frontier \
ftr \
fujitsu \
fujixerox \
fun \
fund \
furniture \
futbol \
fyi \
ga \
gal \
gallery \
gallo \
gallup \
game \
games \
gap \
garden \
gay \
gb \
gbiz \
gd \
gdn \
ge \
gea \
gent \
genting \
george \
gf \
gg \
ggee \
gh \
gi \
gift \
gifts \
gives \
giving \
gl \
glade \
glass \
gle \
global \
globo \
gm \
gmail \
gmbh \
gmo \
gmx \
gn \
godaddy \
gold \
goldpoint \
golf \
goo \
goodyear \
goog \
google \
gop \
got \
gov \
gp \
gq \
gr \
grainger \
graphics \
gratis \
green \
gripe \
grocery \
group \
gs \
gt \
gu \
guardian \
gucci \
guge \
guide \
guitars \
guru \
gw \
gy \
hair \
hamburg \
hangout \
haus \
hbo \
hdfc \
hdfcbank \
health \
healthcare \
help \
helsinki \
here \
hermes \
hgtv \
hiphop \
hisamitsu \
hitachi \
hiv \
hk \
hkt \
hm \
hn \
hockey \
holdings \
holiday \
homedepot \
homegoods \
homes \
homesense \
honda \
horse \
hospital \
host \
hosting \
hot \
hoteles \
hotels \
hotmail \
house \
how \
hr \
hsbc \
ht \
hu \
hughes \
hyatt \
hyundai \
ibm \
icbc \
ice \
icu \
id \
ie \
ieee \
ifm \
ikano \
il \
im \
imamat \
imdb \
immo \
immobilien \
in \
inc \
industries \
infiniti \
info \
ing \
ink \
institute \
insurance \
insure \
int \
international \
intuit \
investments \
io \
ipiranga \
iq \
ir \
irish \
is \
ismaili \
ist \
istanbul \
it \
itau \
itv \
iveco \
jaguar \
java \
jcb \
je \
jeep \
jetzt \
jewelry \
jio \
jll \
jm \
jmp \
jnj \
jo \
jobs \
joburg \
jot \
joy \
jp \
jpmorgan \
jprs \
juegos \
juniper \
kaufen \
kddi \
ke \
kerryhotels \
kerrylogistics \
kerryproperties \
kfh \
kg \
kh \
ki \
kia \
kim \
kinder \
kindle \
kitchen \
kiwi \
km \
kn \
koeln \
komatsu \
kosher \
kp \
kpmg \
kpn \
kr \
krd \
kred \
kuokgroup \
kw \
ky \
kyoto \
kz \
la \
lacaixa \
lamborghini \
lamer \
lancaster \
lancia \
land \
landrover \
lanxess \
lasalle \
lat \
latino \
latrobe \
law \
lawyer \
lb \
lc \
lds \
lease \
leclerc \
lefrak \
legal \
lego \
lexus \
lgbt \
li \
lidl \
life \
lifeinsurance \
lifestyle \
lighting \
like \
lilly \
limited \
limo \
lincoln \
linde \
link \
lipsy \
live \
living \
lixil \
lk \
llc \
llp \
loan \
loans \
locker \
locus \
loft \
lol \
london \
lotte \
lotto \
love \
lpl \
lplfinancial \
lr \
ls \
lt \
ltd \
ltda \
lu \
lundbeck \
luxe \
luxury \
lv \
ly \
ma \
macys \
madrid \
maif \
maison \
makeup \
man \
management \
mango \
map \
market \
marketing \
markets \
marriott \
marshalls \
maserati \
mattel \
mba \
mc \
mckinsey \
md \
me \
med \
media \
meet \
melbourne \
meme \
memorial \
men \
menu \
merckmsd \
mg \
mh \
miami \
microsoft \
mil \
mini \
mint \
mit \
mitsubishi \
mk \
ml \
mlb \
mls \
mm \
mma \
mn \
mo \
mobi \
mobile \
moda \
moe \
moi \
mom \
monash \
money \
monster \
mormon \
mortgage \
moscow \
moto \
motorcycles \
mov \
movie \
mp \
mq \
mr \
ms \
msd \
mt \
mtn \
mtr \
mu \
museum \
mutual \
mv \
mw \
mx \
my \
mz \
na \
nab \
nagoya \
name \
nationwide \
natura \
navy \
nba \
nc \
ne \
nec \
net \
netbank \
netflix \
network \
neustar \
new \
news \
next \
nextdirect \
nexus \
nf \
nfl \
ng \
ngo \
nhk \
ni \
nico \
nike \
nikon \
ninja \
nissan \
nissay \
nl \
no \
nokia \
northwesternmutual \
norton \
now \
nowruz \
nowtv \
np \
nr \
nra \
nrw \
ntt \
nu \
nyc \
nz \
obi \
observer \
off \
office \
okinawa \
olayan \
olayangroup \
oldnavy \
ollo \
om \
omega \
one \
ong \
onl \
online \
onyourside \
ooo \
open \
oracle \
orange \
org \
organic \
origins \
osaka \
otsuka \
ott \
ovh \
pa \
page \
panasonic \
paris \
pars \
partners \
parts \
party \
passagens \
pay \
pccw \
pe \
pet \
pf \
pfizer \
pg \
ph \
pharmacy \
phd \
philips \
phone \
photo \
photography \
photos \
physio \
pics \
pictet \
pictures \
pid \
pin \
ping \
pink \
pioneer \
pizza \
pk \
pl \
place \
play \
playstation \
plumbing \
plus \
pm \
pn \
pnc \
pohl \
poker \
politie \
porn \
post \
pr \
pramerica \
praxi \
press \
prime \
pro \
prod \
productions \
prof \
progressive \
promo \
properties \
property \
protection \
pru \
prudential \
ps \
pt \
pub \
pw \
pwc \
py \
qa \
qpon \
quebec \
quest \
qvc \
racing \
radio \
raid \
re \
read \
realestate \
realtor \
realty \
recipes \
red \
redstone \
redumbrella \
rehab \
reise \
reisen \
reit \
reliance \
ren \
rent \
rentals \
repair \
report \
republican \
rest \
restaurant \
review \
reviews \
rexroth \
rich \
richardli \
ricoh \
ril \
rio \
rip \
rmit \
ro \
rocher \
rocks \
rodeo \
rogers \
room \
rs \
rsvp \
ru \
rugby \
ruhr \
run \
rw \
rwe \
ryukyu \
sa \
saarland \
safe \
safety \
sakura \
sale \
salon \
samsclub \
samsung \
sandvik \
sandvikcoromant \
sanofi \
sap \
sarl \
sas \
save \
saxo \
sb \
sbi \
sbs \
sc \
sca \
scb \
schaeffler \
schmidt \
scholarships \
school \
schule \
schwarz \
science \
scjohnson \
scot \
sd \
se \
search \
seat \
secure \
security \
seek \
select \
sener \
services \
ses \
seven \
sew \
sex \
sexy \
sfr \
sg \
sh \
shangrila \
sharp \
shaw \
shell \
shia \
shiksha \
shoes \
shop \
shopping \
shouji \
show \
showtime \
si \
silk \
sina \
singles \
site \
sj \
sk \
ski \
skin \
sky \
skype \
sl \
sling \
sm \
smart \
smile \
sn \
sncf \
so \
soccer \
social \
softbank \
software \
sohu \
solar \
solutions \
song \
sony \
soy \
spa \
space \
sport \
spot \
spreadbetting \
sr \
srl \
ss \
st \
stada \
staples \
star \
statebank \
statefarm \
stc \
stcgroup \
stockholm \
storage \
store \
stream \
studio \
study \
style \
su \
sucks \
supplies \
supply \
support \
surf \
surgery \
suzuki \
sv \
swatch \
swiftcover \
swiss \
sx \
sy \
sydney \
systems \
sz \
tab \
taipei \
talk \
taobao \
target \
tatamotors \
tatar \
tattoo \
tax \
taxi \
tc \
tci \
td \
tdk \
team \
tech \
technology \
tel \
temasek \
tennis \
teva \
tf \
tg \
th \
thd \
theater \
theatre \
tiaa \
tickets \
tienda \
tiffany \
tips \
tires \
tirol \
tj \
tjmaxx \
tjx \
tk \
tkmaxx \
tl \
tm \
tmall \
tn \
to \
today \
tokyo \
tools \
top \
toray \
toshiba \
total \
tours \
town \
toyota \
toys \
tr \
trade \
trading \
training \
travel \
travelchannel \
travelers \
travelersinsurance \
trust \
trv \
tt \
tube \
tui \
tunes \
tushu \
tv \
tvs \
tw \
tz \
ua \
ubank \
ubs \
ug \
uk \
unicom \
university \
uno \
uol \
ups \
us \
uy \
uz \
va \
vacations \
vana \
vanguard \
vc \
ve \
vegas \
ventures \
verisign \
versicherung \
vet \
vg \
vi \
viajes \
video \
vig \
viking \
villas \
vin \
vip \
virgin \
visa \
vision \
viva \
vivo \
vlaanderen \
vn \
vodka \
volkswagen \
volvo \
vote \
voting \
voto \
voyage \
vu \
vuelos \
wales \
walmart \
walter \
wang \
wanggou \
watch \
watches \
weather \
weatherchannel \
webcam \
weber \
website \
wed \
wedding \
weibo \
weir \
wf \
whoswho \
wien \
wiki \
williamhill \
win \
windows \
wine \
winners \
wme \
wolterskluwer \
woodside \
work \
works \
world \
wow \
ws \
wtc \
wtf \
xbox \
xerox \
xfinity \
xihuan \
xin \
xxx \
xyz \
yachts \
yahoo \
yamaxun \
yandex \
ye \
yodobashi \
yoga \
yokohama \
you \
youtube \
yt \
yun \
za \
zappos \
zara \
zero \
zip \
zm \
zone \
zuerich \
zw \
vermögensberater - ctb \
vermögensberatung - pwb \
ελ \
ευ \
б г \
бел \
дети \
ею \
католик \
ком \
қаз \
мкд \
мон \
москва \
онлайн \
о р г \
р у с \
рф \
сайт \
с р б \
укр \
გე \
հայ \
ישראל \
קום \
ابوظبي \
اتصالات \
ارامكو \
الاردن \
البحرين \
الجزائر \
السعودية \
العليان \
المغرب \
امارات \
ایران \
بارت \
بازار \
بھارت \
بيتك \
پاکستان \
ڀارت \
تونس \
سودان \
سورية \
شبكة \
عراق \
عرب \
عمان \
فلسطين \
قطر \
كاثوليك \
كوم \
مصر \
مليسيا \
موريتانيا \
موقع \
همراه \
क ॉ म \
न े ट \
भ ा रत \
भ ा रतम ् \
भ ा र ो त \
स ं गठन \
ব া ং ল া \
ভ া রত \
ভ া ৰত \
ਭ ਾ ਰਤ \
ભ ા રત \
ଭ ା ରତ \
இந ் த ி ய ா \
இலங ் க ை \
ச ி ங ் கப ் ப ூ ர ் \
భ ా రత ్ \
ಭ ಾ ರತ \
ഭ ാ രത ം \
ල ං ක ා \
คอม \
ไทย \
ລາວ \
닷넷 \
닷컴 \
삼성 \
한국 \
アマゾン \
グーグル \
クラウド \
コム \
ストア \
セール \
ファッション \
ポイント \
みんな \
世界 \
中信 \
中国 \
中國 \
中文网 \
亚马逊 \
企业 \
佛山 \
信息 \
健康 \
八卦 \
公司 \
公益 \
台湾 \
台灣 \
商城 \
商店 \
商标 \
嘉里 \
嘉里大酒店 \
在线 \
大众汽车 \
大拿 \
天主教 \
娱乐 \
家電 \
广东 \
微博 \
慈善 \
我爱你 \
手机 \
招聘 \
政务 \
政府 \
新加坡 \
新闻 \
时尚 \
書籍 \
机构 \
淡马锡 \
游戏 \
澳門 \
点看 \
移动 \
组织机构 \
网址 \
网店 \
网站 \
网络 \
联通 \
诺基亚 \
谷歌 \
购物 \
通販 \
集团 \
電訊盈科 \
飞利浦 \
食品 \
餐厅 \
香格里拉 \
香港 '.split(' ' ) ;
/ * *
The scanner provides an interface that takes a string of text as input , and
outputs an array of tokens instances that can be used for easy URL parsing .
@ module linkify
@ submodule scanner
@ main scanner
* /
2022-01-19 15:03:45 +01:00
var LETTER = / ( ? : [ A - Z a - z \ x A A \ x B 5 \ x B A \ x C 0 - \ x D 6 \ x D 8 - \ x F 6 \ x F 8 - \ u 0 2 C 1 \ u 0 2 C 6 - \ u 0 2 D 1 \ u 0 2 E 0 - \ u 0 2 E 4 \ u 0 2 E C \ u 0 2 E E \ u 0 3 7 0 - \ u 0 3 7 4 \ u 0 3 7 6 \ u 0 3 7 7 \ u 0 3 7 A - \ u 0 3 7 D \ u 0 3 7 F \ u 0 3 8 6 \ u 0 3 8 8 - \ u 0 3 8 A \ u 0 3 8 C \ u 0 3 8 E - \ u 0 3 A 1 \ u 0 3 A 3 - \ u 0 3 F 5 \ u 0 3 F 7 - \ u 0 4 8 1 \ u 0 4 8 A - \ u 0 5 2 F \ u 0 5 3 1 - \ u 0 5 5 6 \ u 0 5 5 9 \ u 0 5 6 0 - \ u 0 5 8 8 \ u 0 5 D 0 - \ u 0 5 E A \ u 0 5 E F - \ u 0 5 F 2 \ u 0 6 2 0 - \ u 0 6 4 A \ u 0 6 6 E \ u 0 6 6 F \ u 0 6 7 1 - \ u 0 6 D 3 \ u 0 6 D 5 \ u 0 6 E 5 \ u 0 6 E 6 \ u 0 6 E E \ u 0 6 E F \ u 0 6 F A - \ u 0 6 F C \ u 0 6 F F \ u 0 7 1 0 \ u 0 7 1 2 - \ u 0 7 2 F \ u 0 7 4 D - \ u 0 7 A 5 \ u 0 7 B 1 \ u 0 7 C A - \ u 0 7 E A \ u 0 7 F 4 \ u 0 7 F 5 \ u 0 7 F A \ u 0 8 0 0 - \ u 0 8 1 5 \ u 0 8 1 A \ u 0 8 2 4 \ u 0 8 2 8 \ u 0 8 4 0 - \ u 0 8 5 8 \ u 0 8 6 0 - \ u 0 8 6 A \ u 0 8 7 0 - \ u 0 8 8 7 \ u 0 8 8 9 - \ u 0 8 8 E \ u 0 8 A 0 - \ u 0 8 C 9 \ u 0 9 0 4 - \ u 0 9 3 9 \ u 0 9 3 D \ u 0 9 5 0 \ u 0 9 5 8 - \ u 0 9 6 1 \ u 0 9 7 1 - \ u 0 9 8 0 \ u 0 9 8 5 - \ u 0 9 8 C \ u 0 9 8 F \ u 0 9 9 0 \ u 0 9 9 3 - \ u 0 9 A 8 \ u 0 9 A A - \ u 0 9 B 0 \ u 0 9 B 2 \ u 0 9 B 6 - \ u 0 9 B 9 \ u 0 9 B D \ u 0 9 C E \ u 0 9 D C \ u 0 9 D D \ u 0 9 D F - \ u 0 9 E 1 \ u 0 9 F 0 \ u 0 9 F 1 \ u 0 9 F C \ u 0 A 0 5 - \ u 0 A 0 A \ u 0 A 0 F \ u 0 A 1 0 \ u 0 A 1 3 - \ u 0 A 2 8 \ u 0 A 2 A - \ u 0 A 3 0 \ u 0 A 3 2 \ u 0 A 3 3 \ u 0 A 3 5 \ u 0 A 3 6 \ u 0 A 3 8 \ u 0 A 3 9 \ u 0 A 5 9 - \ u 0 A 5 C \ u 0 A 5 E \ u 0 A 7 2 - \ u 0 A 7 4 \ u 0 A 8 5 - \ u 0 A 8 D \ u 0 A 8 F - \ u 0 A 9 1 \ u 0 A 9 3 - \ u 0 A A 8 \ u 0 A A A - \ u 0 A B 0 \ u 0 A B 2 \ u 0 A B 3 \ u 0 A B 5 - \ u 0 A B 9 \ u 0 A B D \ u 0 A D 0 \ u 0 A E 0 \ u 0 A E 1 \ u 0 A F 9 \ u 0 B 0 5 - \ u 0 B 0 C \ u 0 B 0 F \ u 0 B 1 0 \ u 0 B 1 3 - \ u 0 B 2 8 \ u 0 B 2 A - \ u 0 B 3 0 \ u 0 B 3 2 \ u 0 B 3 3 \ u 0 B 3 5 - \ u 0 B 3 9 \ u 0 B 3 D \ u 0 B 5 C \ u 0 B 5 D \ u 0 B 5 F - \ u 0 B 6 1 \ u 0 B 7 1 \ u 0 B 8 3 \ u 0 B 8 5 - \ u 0 B 8 A \ u 0 B 8 E - \ u 0 B 9 0 \ u 0 B 9 2 - \ u 0 B 9 5 \ u 0 B 9 9 \ u 0 B 9 A \ u 0 B 9 C \ u 0 B 9 E \ u 0 B 9 F \ u 0 B A 3 \ u 0 B A 4 \ u 0 B A 8 - \ u 0 B A A \ u 0 B A E - \ u 0 B B 9 \ u 0 B D 0 \ u 0 C 0 5 - \ u 0 C 0 C \ u 0 C 0 E - \ u 0 C 1 0 \ u 0 C 1 2 - \ u 0 C 2 8 \ u 0 C 2 A - \ u 0 C 3 9 \ u 0 C 3 D \ u 0 C 5 8 - \ u 0 C 5 A \ u 0 C 5 D \ u 0 C 6 0 \ u 0 C 6 1 \ u 0 C 8 0 \ u 0 C 8 5 - \ u 0 C 8 C \ u 0 C 8 E - \ u 0 C 9 0 \ u 0 C 9 2 - \ u 0 C A 8 \ u 0 C A A - \ u 0 C B 3 \ u 0 C B 5 - \ u 0 C B 9 \ u 0 C B D \ u 0 C D D \ u 0 C D E \ u 0 C E 0 \ u 0 C E 1 \ u 0 C F 1 \ u 0 C F 2 \ u 0 D 0 4 - \ u 0 D 0 C \ u 0 D 0 E - \ u 0 D 1 0 \ u 0 D 1 2 - \ u 0 D 3 A \ u 0 D 3 D \ u 0 D 4 E \ u 0 D 5 4 - \ u 0 D 5 6 \ u 0 D 5 F - \ u 0 D 6 1 \ u 0 D 7 A - \ u 0 D 7 F \ u 0 D 8 5 - \ u 0 D 9 6 \ u 0 D 9 A - \ u 0 D B 1 \ u 0 D B 3 - \ u 0 D B B \ u 0 D B D \ u 0 D C 0 - \ u 0 D C 6 \ u 0 E 0 1 - \ u 0 E 3 0 \ u 0 E 3 2 \ u 0 E 3 3 \ u 0 E 4 0 - \ u 0 E 4 6 \ u 0 E 8 1 \ u 0 E 8 2 \ u 0 E 8 4 \ u 0 E 8 6 - \ u 0 E 8 A \ u 0 E 8 C - \ u 0 E A 3 \ u 0 E A 5 \ u 0 E A 7 - \ u 0 E B 0 \ u 0 E B 2 \ u 0 E B 3 \ u 0 E B D \ u 0 E C 0 - \ u 0 E C 4 \ u 0 E C 6 \ u 0 E D C - \ u 0 E D F \ u 0 F 0 0 \ u 0 F 4 0 - \ u 0 F 4 7 \ u 0 F 4 9 - \ u 0 F 6 C \ u 0 F 8 8 - \ u 0 F 8 C \ u 1 0 0 0 - \ u 1 0 2 A \ u 1 0 3 F \ u 1 0 5 0 - \ u 1 0 5 5 \ u 1 0 5 A - \ u 1 0 5 D \ u 1 0 6 1 \ u 1 0 6 5 \ u 1 0 6 6 \ u 1 0 6 E - \ u 1 0 7 0 \ u 1 0 7 5 - \ u 1 0 8 1 \ u 1 0 8 E \ u 1 0 A 0 - \ u 1 0 C 5 \ u 1 0 C 7 \ u 1 0 C D \ u 1 0 D 0 - \ u 1 0 F A \ u 1 0 F C - \ u 1 2 4 8 \ u 1 2 4 A - \ u 1 2 4 D \ u 1 2 5 0 - \ u 1 2 5 6 \ u 1 2 5 8 \ u 1 2 5 A - \ u 1 2 5 D \ u 1 2 6 0 - \ u 1 2 8 8 \ u 1 2 8 A - \ u 1 2 8 D \ u 1 2 9 0 - \ u 1 2 B 0 \ u 1 2 B 2 - \ u 1 2 B 5 \ u 1 2 B 8 - \ u 1 2 B E \ u 1 2 C 0 \ u 1 2 C 2 - \ u 1 2 C 5 \ u 1 2 C 8 - \ u 1 2 D 6 \ u 1 2 D 8 - \ u 1 3 1 0 \ u 1 3 1 2 - \ u 1 3 1 5 \ u 1 3 1 8 - \ u 1 3 5 A \ u 1 3 8 0 - \ u 1 3 8 F \ u 1 3 A 0 - \ u 1 3 F 5 \ u 1 3 F 8 - \ u 1 3 F D \ u 1 4 0 1 - \ u 1 6 6 C \ u 1 6 6 F - \ u 1 6 7 F \ u 1 6 8 1 - \ u 1 6 9 A \ u 1 6 A 0 - \ u 1 6 E A \ u 1 6 F 1 - \ u 1 6 F 8 \ u 1 7 0 0 - \ u 1 7 1 1 \ u 1 7 1 F - \ u 1 7 3 1 \ u 1 7 4 0 - \ u 1 7 5 1 \ u 1 7 6 0 - \ u 1 7 6 C \ u 1 7 6 E - \ u 1 7 7 0 \ u 1 7 8 0 - \ u 1 7 B 3 \ u 1 7 D 7 \ u 1 7 D C \ u 1 8 2 0 - \ u 1 8 7 8 \ u 1 8 8 0 - \ u 1 8 8 4 \ u 1 8 8 7 - \ u 1 8 A 8 \ u 1 8 A A \ u 1 8 B 0 - \ u 1 8 F 5 \ u 1 9 0 0 - \ u 1 9 1 E \ u 1 9 5 0 - \ u 1 9 6 D \ u 1 9 7 0 - \ u 1 9 7 4 \ u 1 9 8 0 - \ u 1 9 A B \ u 1 9 B 0 - \ u 1 9 C 9 \ u 1 A 0 0 - \ u 1 A 1 6 \ u 1 A 2 0 - \ u 1 A 5 4 \ u 1 A A 7 \ u 1 B 0 5 - \ u 1 B 3 3 \ u 1 B 4 5 - \ u 1 B 4 C \ u 1 B 8 3 - \ u 1 B A 0 \ u 1 B A E \ u 1 B A F \ u 1 B B A - \ u 1 B E 5 \ u 1 C 0 0 - \ u 1 C 2 3 \ u 1 C 4 D - \ u 1 C 4 F \ u 1 C 5 A - \ u 1 C 7 D \ u 1 C 8 0 - \ u 1 C 8 8 \ u 1 C 9 0 - \ u 1 C B A \ u 1 C B D - \ u 1 C B F \ u 1 C E 9 - \ u 1 C E C \ u 1 C E E - \ u 1 C F 3 \ u 1 C F 5 \ u 1 C F 6 \ u 1 C F A \ u 1 D 0 0 - \ u 1 D B F \ u 1 E 0 0 - \ u 1 F 1 5 \ u 1 F 1 8 - \ u 1 F 1 D \ u 1 F 2 0 - \ u 1 F 4 5 \ u 1 F 4 8 - \ u 1 F 4 D \ u 1 F 5 0 - \ u 1 F 5 7 \ u 1 F 5 9 \ u 1 F 5 B \ u 1 F 5 D \ u 1 F 5 F - \ u 1 F 7 D \ u 1 F 8 0 - \ u 1 F B 4 \ u 1 F B 6 - \ u 1 F B C \ u 1 F B E \ u 1 F C 2 - \ u 1 F C 4 \ u 1 F C 6 - \ u 1 F C C \ u 1 F D 0 - \ u 1 F D 3 \ u 1 F D 6 - \ u 1 F D B \ u 1 F E 0 - \ u 1 F E C \ u 1 F F 2 - \ u 1 F F 4 \ u 1 F F 6 - \ u 1 F F C \ u 2 0 7 1 \ u 2 0 7 F \ u 2 0 9 0 - \ u 2 0 9 C \ u 2 1 0 2 \ u 2 1 0 7 \ u 2 1 0 A - \ u 2 1 1 3 \ u 2 1 1 5 \ u 2 1 1 9 - \ u 2 1 1 D \ u 2 1 2 4 \ u 2 1 2 6 \ u 2 1 2 8 \ u 2 1 2 A - \ u 2 1 2 D \ u 2 1 2 F - \ u 2 1 3 9 \ u 2 1 3 C - \ u 2 1 3 F \ u 2 1 4 5 - \ u 2 1 4 9 \ u 2 1 4 E \ u 2 1 8 3 \ u 2 1 8 4 \ u 2 C 0 0 - \ u 2 C E 4 \ u 2 C E B - \ u 2 C E E \ u 2 C F 2 \ u 2 C F 3 \ u 2 D 0 0 - \ u 2 D 2 5 \ u 2 D 2 7 \ u 2 D 2 D \ u 2 D 3 0 - \ u 2 D 6 7 \ u 2 D 6 F \ u 2 D 8 0 - \ u 2 D 9 6 \ u 2 D A 0 - \ u 2 D A 6 \ u 2 D A 8 - \ u 2 D A E \ u 2 D B 0 - \ u 2 D B 6 \ u 2 D B 8 - \ u 2 D B E \ u 2 D C 0 - \ u 2 D C 6 \ u 2 D C 8 - \ u 2 D C E \ u 2 D D 0 - \ u 2 D D 6 \ u 2 D D 8 - \ u 2 D D E \ u 2 E 2 F \ u 3 0 0 5 \ u 3 0 0 6 \ u 3 0 3 1 - \ u 3 0 3 5 \ u 3 0 3 B \ u 3 0 3 C \ u 3 0 4 1 - \ u 3 0 9 6 \ u 3 0 9 D - \ u 3 0 9 F \ u 3 0 A 1 - \ u 3 0 F A \ u 3 0 F C - \ u 3 0 F F \ u 3 1 0 5 - \ u 3 1 2 F \ u 3 1 3 1 - \ u 3 1 8 E \ u 3 1 A 0 - \ u 3 1 B F \ u 3 1 F 0 - \ u 3 1 F F \ u 3 4 0 0 - \ u 4 D B F \ u 4 E 0 0 - \ u A 4 8 C \ u A 4 D 0 - \ u A 4 F D \ u A 5 0 0 - \ u A 6 0 C \ u A 6 1 0 - \ u A 6 1 F \ u A 6 2 A \ u A 6 2 B \ u A 6 4 0 - \ u A 6 6 E \ u A 6 7 F - \ u A 6 9 D \ u A 6 A 0 - \ u A 6 E 5 \ u A 7 1 7 - \ u A 7 1 F \ u A 7 2 2 - \ u A 7 8 8 \ u A 7 8 B - \ u A 7 C A \ u A 7 D 0 \ u A 7 D 1 \ u A 7 D 3 \ u A 7 D 5 - \ u A 7 D 9 \ u A 7 F 2 - \ u A 8 0 1 \ u A 8 0 3 - \ u A 8 0 5 \ u A 8 0 7 - \ u A 8 0 A \ u A 8 0 C - \ u A 8 2 2 \ u A 8 4 0 - \ u A 8 7 3 \ u A 8 8 2 - \ u A 8 B 3 \ u A 8 F 2 - \ u A 8 F 7 \ u A 8 F B \ u A 8 F D \ u A 8 F E \ u A 9 0 A - \ u A 9 2 5 \ u A 9 3 0 - \ u A 9 4 6 \ u A 9 6 0 - \ u A 9 7 C \ u A 9 8 4 - \ u A 9 B 2 \ u A 9 C F \ u A 9 E 0 - \ u A 9 E 4 \ u A 9 E 6 - \ u A 9 E F \ u A 9 F A - \ u A 9 F E \ u A A 0 0 - \ u A A 2 8 \ u A A 4 0 - \ u A A 4 2 \ u A A 4 4 - \ u A A 4 B \ u A A 6 0 - \ u A A 7 6 \ u A A 7 A \ u A A 7 E - \ u A A A F \ u A A B 1 \ u A A B 5 \ u A A B 6 \ u A A B 9 - \ u A A B D \ u A A C 0 \ u A A C 2 \ u A A D B - \ u A A D D \ u A A E 0 - \ u A A E A \ u A A F 2 - \ u A A F 4 \ u A B 0 1 - \ u A B 0 6 \ u A B 0 9 - \ u A B 0 E \ u A B 1 1 - \ u A B 1 6 \ u A B 2 0 - \ u A B 2 6 \ u A B 2 8 - \ u A B 2 E \ u A B 3 0 - \ u A B 5 A \ u A B 5 C - \ u A B 6 9 \ u A B 7 0 - \ u A B E 2 \ u A C 0 0 - \ u D 7 A 3 \ u D 7 B 0 - \ u D 7 C 6 \ u D 7 C B - \ u D 7 F B \ u F 9 0 0 - \ u F A 6 D \ u F A 7 0 - \ u F A D 9 \ u F B 0 0 - \ u F B 0 6 \ u F B 1 3 - \ u F B 1 7 \ u F B 1 D \ u F B 1 F - \ u F B 2 8 \ u F B 2 A - \ u F B 3 6 \ u F B 3 8 - \ u F B 3
2021-05-28 16:46:29 +02:00
2022-01-19 15:03:45 +01:00
var EMOJI = /(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEDD-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDDFF\uDE70-\uDE74\uDE78-\uDE7C\uDE80-\uDE86\uDE90-\uDEAC\uDEB0-\uDEBA\uDEC0-\uDEC5\uDED0-\uDED9\uDEE0-\uDEE7\uDEF0-\uDEF6])/ ; // Any Unicode emoji character
var EMOJI _VARIATION = /\uFE0F/ ; // Variation selector, follows heart and others
2021-05-28 16:46:29 +02:00
var DIGIT = /\d/ ;
var SPACE = /\s/ ;
/ * *
* Initialize the scanner character - based state machine for the given start state
* @ return { State } scanner starting state
* /
function init$2 ( ) {
var customProtocols = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : [ ] ;
// Frequently used states
var S _START = makeState ( ) ;
var S _NUM = makeAcceptingState ( NUM ) ;
var S _DOMAIN = makeAcceptingState ( DOMAIN ) ;
var S _DOMAIN _HYPHEN = makeState ( ) ; // domain followed by 1 or more hyphen characters
var S _WS = makeAcceptingState ( WS ) ;
2022-01-19 15:03:45 +01:00
var DOMAIN _REGEX _TRANSITIONS = [ [ DIGIT , S _DOMAIN ] , [ LETTER , S _DOMAIN ] , [ EMOJI , S _DOMAIN ] , [ EMOJI _VARIATION , S _DOMAIN ] ] ; // Create a state which emits a domain token
2021-05-28 16:46:29 +02:00
var makeDomainState = function makeDomainState ( ) {
var state = makeAcceptingState ( DOMAIN ) ;
state . j = {
'-' : S _DOMAIN _HYPHEN
} ;
state . jr = [ ] . concat ( DOMAIN _REGEX _TRANSITIONS ) ;
return state ;
} ; // Create a state which does not emit a domain state but the usual alphanumeric
// transitions are domains
var makeNearDomainState = function makeNearDomainState ( token ) {
var state = makeDomainState ( ) ;
state . t = token ;
return state ;
} ; // States for special URL symbols that accept immediately after start
2022-01-19 15:03:45 +01:00
makeBatchT ( S _START , [ [ "'" , makeAcceptingState ( APOSTROPHE ) ] , [ '{' , makeAcceptingState ( OPENBRACE ) ] , [ '[' , makeAcceptingState ( OPENBRACKET ) ] , [ '<' , makeAcceptingState ( OPENANGLEBRACKET ) ] , [ '(' , makeAcceptingState ( OPENPAREN ) ] , [ '}' , makeAcceptingState ( CLOSEBRACE ) ] , [ ']' , makeAcceptingState ( CLOSEBRACKET ) ] , [ '>' , makeAcceptingState ( CLOSEANGLEBRACKET ) ] , [ ')' , makeAcceptingState ( CLOSEPAREN ) ] , [ '&' , makeAcceptingState ( AMPERSAND ) ] , [ '*' , makeAcceptingState ( ASTERISK ) ] , [ '@' , makeAcceptingState ( AT ) ] , [ '`' , makeAcceptingState ( BACKTICK ) ] , [ '^' , makeAcceptingState ( CARET ) ] , [ ':' , makeAcceptingState ( COLON ) ] , [ ',' , makeAcceptingState ( COMMA ) ] , [ '$' , makeAcceptingState ( DOLLAR ) ] , [ '.' , makeAcceptingState ( DOT ) ] , [ '=' , makeAcceptingState ( EQUALS ) ] , [ '!' , makeAcceptingState ( EXCLAMATION ) ] , [ '-' , makeAcceptingState ( HYPHEN ) ] , [ '%' , makeAcceptingState ( PERCENT ) ] , [ '|' , makeAcceptingState ( PIPE ) ] , [ '+' , makeAcceptingState ( PLUS ) ] , [ '#' , makeAcceptingState ( POUND ) ] , [ '?' , makeAcceptingState ( QUERY ) ] , [ '"' , makeAcceptingState ( QUOTE ) ] , [ '/' , makeAcceptingState ( SLASH ) ] , [ ';' , makeAcceptingState ( SEMI ) ] , [ '~' , makeAcceptingState ( TILDE ) ] , [ '_' , makeAcceptingState ( UNDERSCORE ) ] , [ '\\' , makeAcceptingState ( BACKSLASH ) ] ] ) ; // Whitespace jumps
2021-05-28 16:46:29 +02:00
// Tokens of only non-newline whitespace are arbitrarily long
makeT ( S _START , '\n' , makeAcceptingState ( NL ) ) ;
makeRegexT ( S _START , SPACE , S _WS ) ; // If any whitespace except newline, more whitespace!
makeT ( S _WS , '\n' , makeState ( ) ) ; // non-accepting state
makeRegexT ( S _WS , SPACE , S _WS ) ; // Generates states for top-level domains
// Note that this is most accurate when tlds are in alphabetical order
for ( var i = 0 ; i < tlds . length ; i ++ ) {
makeChainT ( S _START , tlds [ i ] , makeNearDomainState ( TLD ) , makeDomainState ) ;
} // Collect the states generated by different protocls
var S _PROTOCOL _FILE = makeDomainState ( ) ;
var S _PROTOCOL _FTP = makeDomainState ( ) ;
var S _PROTOCOL _HTTP = makeDomainState ( ) ;
var S _MAILTO = makeDomainState ( ) ;
makeChainT ( S _START , 'file' , S _PROTOCOL _FILE , makeDomainState ) ;
makeChainT ( S _START , 'ftp' , S _PROTOCOL _FTP , makeDomainState ) ;
makeChainT ( S _START , 'http' , S _PROTOCOL _HTTP , makeDomainState ) ;
makeChainT ( S _START , 'mailto' , S _MAILTO , makeDomainState ) ; // Protocol states
var S _PROTOCOL _SECURE = makeDomainState ( ) ;
var S _FULL _PROTOCOL = makeAcceptingState ( PROTOCOL ) ; // Full protocol ends with COLON
var S _FULL _MAILTO = makeAcceptingState ( MAILTO ) ; // Mailto ends with COLON
// Secure protocols (end with 's')
makeT ( S _PROTOCOL _FTP , 's' , S _PROTOCOL _SECURE ) ;
makeT ( S _PROTOCOL _FTP , ':' , S _FULL _PROTOCOL ) ;
makeT ( S _PROTOCOL _HTTP , 's' , S _PROTOCOL _SECURE ) ;
makeT ( S _PROTOCOL _HTTP , ':' , S _FULL _PROTOCOL ) ; // Become protocol tokens after a COLON
makeT ( S _PROTOCOL _FILE , ':' , S _FULL _PROTOCOL ) ;
makeT ( S _PROTOCOL _SECURE , ':' , S _FULL _PROTOCOL ) ;
makeT ( S _MAILTO , ':' , S _FULL _MAILTO ) ; // Register custom protocols
var S _CUSTOM _PROTOCOL = makeDomainState ( ) ;
for ( var _i = 0 ; _i < customProtocols . length ; _i ++ ) {
makeChainT ( S _START , customProtocols [ _i ] , S _CUSTOM _PROTOCOL , makeDomainState ) ;
}
makeT ( S _CUSTOM _PROTOCOL , ':' , S _FULL _PROTOCOL ) ; // Localhost
makeChainT ( S _START , 'localhost' , makeNearDomainState ( LOCALHOST ) , makeDomainState ) ; // Everything else
// DOMAINs make more DOMAINs
// Number and character transitions
makeRegexT ( S _START , DIGIT , S _NUM ) ;
makeRegexT ( S _START , LETTER , S _DOMAIN ) ;
makeRegexT ( S _START , EMOJI , S _DOMAIN ) ;
2022-01-19 15:03:45 +01:00
makeRegexT ( S _START , EMOJI _VARIATION , S _DOMAIN ) ;
2021-05-28 16:46:29 +02:00
makeRegexT ( S _NUM , DIGIT , S _NUM ) ;
makeRegexT ( S _NUM , LETTER , S _DOMAIN ) ; // number becomes DOMAIN
makeRegexT ( S _NUM , EMOJI , S _DOMAIN ) ; // number becomes DOMAIN
2022-01-19 15:03:45 +01:00
makeRegexT ( S _NUM , EMOJI _VARIATION , S _DOMAIN ) ; // number becomes DOMAIN
2021-05-28 16:46:29 +02:00
makeT ( S _NUM , '-' , S _DOMAIN _HYPHEN ) ; // Default domain transitions
makeT ( S _DOMAIN , '-' , S _DOMAIN _HYPHEN ) ;
makeT ( S _DOMAIN _HYPHEN , '-' , S _DOMAIN _HYPHEN ) ;
makeRegexT ( S _DOMAIN , DIGIT , S _DOMAIN ) ;
makeRegexT ( S _DOMAIN , LETTER , S _DOMAIN ) ;
makeRegexT ( S _DOMAIN , EMOJI , S _DOMAIN ) ;
2022-01-19 15:03:45 +01:00
makeRegexT ( S _DOMAIN , EMOJI _VARIATION , S _DOMAIN ) ;
2021-05-28 16:46:29 +02:00
makeRegexT ( S _DOMAIN _HYPHEN , DIGIT , S _DOMAIN ) ;
makeRegexT ( S _DOMAIN _HYPHEN , LETTER , S _DOMAIN ) ;
2022-01-19 15:03:45 +01:00
makeRegexT ( S _DOMAIN _HYPHEN , EMOJI , S _DOMAIN ) ;
makeRegexT ( S _DOMAIN _HYPHEN , EMOJI _VARIATION , S _DOMAIN ) ; // Set default transition for start state (some symbol)
2021-05-28 16:46:29 +02:00
S _START . jd = makeAcceptingState ( SYM ) ;
return S _START ;
}
/ * *
Given a string , returns an array of TOKEN instances representing the
composition of that string .
@ method run
@ param { State } start scanner starting state
@ param { string } str input string to scan
2022-01-19 15:03:45 +01:00
@ return { { t : string , v : string , s : number , l : number } [ ] } list of tokens , each with a type and value
2021-05-28 16:46:29 +02:00
* /
function run$1 ( start , str ) {
// State machine is not case sensitive, so input is tokenized in lowercased
// form (still returns the regular case though) Uses selective `toLowerCase`
// is used because lowercasing the entire string causes the length and
// character position to vary in some non-English strings with V8-based
// runtimes.
2022-01-19 15:03:45 +01:00
var iterable = stringToArray ( str . replace ( /[A-Z]/g , function ( c ) {
2021-05-28 16:46:29 +02:00
return c . toLowerCase ( ) ;
} ) ) ;
var charCount = iterable . length ; // <= len if there are emojis, etc
var tokens = [ ] ; // return value
// cursor through the string itself, accounting for characters that have
// width with length 2 such as emojis
var cursor = 0 ; // Cursor through the array-representation of the string
var charCursor = 0 ; // Tokenize the string
while ( charCursor < charCount ) {
var state = start ;
var nextState = null ;
var tokenLength = 0 ;
var latestAccepting = null ;
var sinceAccepts = - 1 ;
var charsSinceAccepts = - 1 ;
while ( charCursor < charCount && ( nextState = takeT ( state , iterable [ charCursor ] ) ) ) {
state = nextState ; // Keep track of the latest accepting state
if ( state . accepts ( ) ) {
sinceAccepts = 0 ;
charsSinceAccepts = 0 ;
latestAccepting = state ;
} else if ( sinceAccepts >= 0 ) {
sinceAccepts += iterable [ charCursor ] . length ;
charsSinceAccepts ++ ;
}
tokenLength += iterable [ charCursor ] . length ;
cursor += iterable [ charCursor ] . length ;
charCursor ++ ;
2022-01-19 15:03:45 +01:00
} // Roll back to the latest accepting state
2021-05-28 16:46:29 +02:00
cursor -= sinceAccepts ;
charCursor -= charsSinceAccepts ;
tokenLength -= sinceAccepts ; // No more jumps, just make a new token from the last accepting one
// TODO: If possible, don't output v, instead output range where values ocur
tokens . push ( {
t : latestAccepting . t ,
// token type/name
v : str . substr ( cursor - tokenLength , tokenLength ) ,
// string value
s : cursor - tokenLength ,
// start index
e : cursor // end index (excluding)
} ) ;
}
return tokens ;
}
2022-01-19 15:03:45 +01:00
/ * *
* Convert a String to an Array of characters , taking into account that some
* characters like emojis take up two string indexes .
*
* Adapted from core - js ( MIT license )
* https : //github.com/zloirock/core-js/blob/2d69cf5f99ab3ea3463c395df81e5a15b68f49d9/packages/core-js/internals/string-multibyte.js
*
* @ function stringToArray
* @ param { string } str
* @ returns { string [ ] }
* /
function stringToArray ( str ) {
var result = [ ] ;
var len = str . length ;
var index = 0 ;
while ( index < len ) {
var first = str . charCodeAt ( index ) ;
var second = void 0 ;
var char = first < 0xd800 || first > 0xdbff || index + 1 === len || ( second = str . charCodeAt ( index + 1 ) ) < 0xdc00 || second > 0xdfff ? str [ index ] // single character
: str . slice ( index , index + 2 ) ; // two-index characters
result . push ( char ) ;
index += char . length ;
}
return result ;
}
2021-05-28 16:46:29 +02:00
function _typeof ( obj ) {
"@babel/helpers - typeof" ;
if ( typeof Symbol === "function" && typeof Symbol . iterator === "symbol" ) {
_typeof = function ( obj ) {
return typeof obj ;
} ;
} else {
_typeof = function ( obj ) {
return obj && typeof Symbol === "function" && obj . constructor === Symbol && obj !== Symbol . prototype ? "symbol" : typeof obj ;
} ;
}
return _typeof ( obj ) ;
}
2022-01-19 15:03:45 +01:00
/ * *
* @ property { string } defaultProtocol
* @ property { { [ string ] : ( event ) => void } ] } [ events ]
* /
2021-05-28 16:46:29 +02:00
var defaults = {
defaultProtocol : 'http' ,
events : null ,
format : noop ,
formatHref : noop ,
nl2br : false ,
tagName : 'a' ,
target : null ,
rel : null ,
validate : true ,
truncate : 0 ,
className : null ,
attributes : null ,
ignoreTags : [ ]
} ;
2022-01-19 15:03:45 +01:00
/ * *
* @ class Options
* @ param { Object } [ opts ] Set option properties besides the defaults
* /
2021-05-28 16:46:29 +02:00
function Options ( opts ) {
opts = opts || { } ;
this . defaultProtocol = 'defaultProtocol' in opts ? opts . defaultProtocol : defaults . defaultProtocol ;
this . events = 'events' in opts ? opts . events : defaults . events ;
this . format = 'format' in opts ? opts . format : defaults . format ;
this . formatHref = 'formatHref' in opts ? opts . formatHref : defaults . formatHref ;
this . nl2br = 'nl2br' in opts ? opts . nl2br : defaults . nl2br ;
this . tagName = 'tagName' in opts ? opts . tagName : defaults . tagName ;
this . target = 'target' in opts ? opts . target : defaults . target ;
this . rel = 'rel' in opts ? opts . rel : defaults . rel ;
this . validate = 'validate' in opts ? opts . validate : defaults . validate ;
this . truncate = 'truncate' in opts ? opts . truncate : defaults . truncate ;
this . className = 'className' in opts ? opts . className : defaults . className ;
this . attributes = opts . attributes || defaults . attributes ;
this . ignoreTags = [ ] ; // Make all tags names upper case
var ignoredTags = 'ignoreTags' in opts ? opts . ignoreTags : defaults . ignoreTags ;
for ( var i = 0 ; i < ignoredTags . length ; i ++ ) {
this . ignoreTags . push ( ignoredTags [ i ] . toUpperCase ( ) ) ;
}
}
Options . prototype = {
/ * *
* Given the token , return all options for how it should be displayed
* /
resolve : function resolve ( token ) {
var href = token . toHref ( this . defaultProtocol ) ;
return {
formatted : this . get ( 'format' , token . toString ( ) , token ) ,
formattedHref : this . get ( 'formatHref' , href , token ) ,
tagName : this . get ( 'tagName' , href , token ) ,
className : this . get ( 'className' , href , token ) ,
target : this . get ( 'target' , href , token ) ,
rel : this . get ( 'rel' , href , token ) ,
events : this . getObject ( 'events' , href , token ) ,
attributes : this . getObject ( 'attributes' , href , token ) ,
truncate : this . get ( 'truncate' , href , token )
} ;
} ,
/ * *
* Returns true or false based on whether a token should be displayed as a
* link based on the user options . By default ,
* /
check : function check ( token ) {
return this . get ( 'validate' , token . toString ( ) , token ) ;
} ,
// Private methods
/ * *
* Resolve an option ' s value based on the value of the option and the given
* params .
* @ param { string } key Name of option to use
* @ param operator will be passed to the target option if it ' s method
* @ param { MultiToken } token The token from linkify . tokenize
* /
get : function get ( key , operator , token ) {
var option = this [ key ] ;
if ( ! option ) {
return option ;
}
var optionValue ;
switch ( _typeof ( option ) ) {
case 'function' :
return option ( operator , token . t ) ;
case 'object' :
optionValue = token . t in option ? option [ token . t ] : defaults [ key ] ;
return typeof optionValue === 'function' ? optionValue ( operator , token . t ) : optionValue ;
}
return option ;
} ,
getObject : function getObject ( key , operator , token ) {
var option = this [ key ] ;
return typeof option === 'function' ? option ( operator , token . t ) : option ;
}
} ;
function noop ( val ) {
return val ;
}
var options = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
defaults : defaults ,
Options : Options
} ) ;
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Multi - Tokens
Tokens composed of arrays of TextTokens
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
function inherits ( parent , child ) {
var props = arguments . length > 2 && arguments [ 2 ] !== undefined ? arguments [ 2 ] : { } ;
var extended = Object . create ( parent . prototype ) ;
for ( var p in props ) {
extended [ p ] = props [ p ] ;
}
extended . constructor = child ;
child . prototype = extended ;
return child ;
}
/ * *
Abstract class used for manufacturing tokens of text tokens . That is rather
than the value for a token being a small string of text , it ' s value an array
of text tokens .
Used for grouping together URLs , emails , hashtags , and other potential
creations .
@ class MultiToken
@ param { string } value
2022-01-19 15:03:45 +01:00
@ param { { t : string , v : string , s : number , e : number } [ ] } tokens
2021-05-28 16:46:29 +02:00
@ abstract
* /
2022-01-19 15:03:45 +01:00
function MultiToken ( ) { }
2021-05-28 16:46:29 +02:00
MultiToken . prototype = {
/ * *
String representing the type for this token
@ property t
@ default 'token'
* /
t : 'token' ,
/ * *
Is this multitoken a link ?
@ property isLink
@ default false
* /
isLink : false ,
/ * *
Return the string this token represents .
@ method toString
@ return { string }
* /
toString : function toString ( ) {
return this . v ;
} ,
/ * *
What should the value for this token be in the ` href ` HTML attribute ?
Returns the ` .toString ` value by default .
@ method toHref
@ return { string }
* /
toHref : function toHref ( ) {
return this . toString ( ) ;
} ,
/ * *
* The start index of this token in the original input string
* @ returns { number }
* /
startIndex : function startIndex ( ) {
return this . tk [ 0 ] . s ;
} ,
/ * *
* The end index of this token in the original input string ( up to this
* index but not including it )
* @ returns { number }
* /
endIndex : function endIndex ( ) {
return this . tk [ this . tk . length - 1 ] . e ;
} ,
/ * *
Returns a hash of relevant values for this token , which includes keys
* type - Kind of token ( 'url' , 'email' , etc . )
* value - Original text
* href - The value that should be added to the anchor tag ' s href
attribute
@ method toObject
@ param { string } [ protocol ] ` 'http' ` by default
* /
toObject : function toObject ( ) {
var protocol = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : defaults . defaultProtocol ;
return {
type : this . t ,
value : this . v ,
isLink : this . isLink ,
href : this . toHref ( protocol ) ,
start : this . startIndex ( ) ,
end : this . endIndex ( )
} ;
}
} ; // Base token
/ * *
* Create a new token that can be emitted by the parser state machine
* @ param { string } type readable type of the token
* @ param { object } props properties to assign or override , including isLink = true or false
* @ returns { ( value : string , tokens : { t : string , v : string , s : number , e : number } ) => MultiToken } new token class
* /
function createTokenClass ( type , props ) {
function Token ( value , tokens ) {
this . t = type ;
this . v = value ;
this . tk = tokens ;
}
inherits ( MultiToken , Token , props ) ;
return Token ;
}
/ * *
Represents an arbitrarily mailto email address with the prefix included
@ class MailtoEmail
@ extends MultiToken
* /
var MailtoEmail = createTokenClass ( 'email' , {
isLink : true
} ) ;
/ * *
Represents a list of tokens making up a valid email address
@ class Email
@ extends MultiToken
* /
var Email = createTokenClass ( 'email' , {
isLink : true ,
toHref : function toHref ( ) {
return 'mailto:' + this . toString ( ) ;
}
} ) ;
/ * *
Represents some plain text
@ class Text
@ extends MultiToken
* /
var Text = createTokenClass ( 'text' ) ;
/ * *
Multi - linebreak token - represents a line break
@ class Nl
@ extends MultiToken
* /
var Nl = createTokenClass ( 'nl' ) ;
/ * *
Represents a list of text tokens making up a valid URL
@ class Url
@ extends MultiToken
* /
var Url = createTokenClass ( 'url' , {
isLink : true ,
/ * *
Lowercases relevant parts of the domain and adds the protocol if
required . Note that this will not escape unsafe HTML characters in the
URL .
@ method href
@ param { string } protocol
@ return { string }
* /
toHref : function toHref ( ) {
var protocol = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : defaults . defaultProtocol ;
var tokens = this . tk ;
var hasProtocol = false ;
var hasSlashSlash = false ;
var result = [ ] ;
var i = 0 ; // Make the first part of the domain lowercase
// Lowercase protocol
while ( tokens [ i ] . t === PROTOCOL ) {
hasProtocol = true ;
result . push ( tokens [ i ] . v ) ;
i ++ ;
} // Skip slash-slash
while ( tokens [ i ] . t === SLASH ) {
hasSlashSlash = true ;
result . push ( tokens [ i ] . v ) ;
i ++ ;
} // Continue pushing characters
for ( ; i < tokens . length ; i ++ ) {
result . push ( tokens [ i ] . v ) ;
}
result = result . join ( '' ) ;
if ( ! ( hasProtocol || hasSlashSlash ) ) {
result = "" . concat ( protocol , "://" ) . concat ( result ) ;
}
return result ;
} ,
hasProtocol : function hasProtocol ( ) {
return this . tk [ 0 ] . t === PROTOCOL ;
}
} ) ;
var multi = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
MultiToken : MultiToken ,
Base : MultiToken ,
createTokenClass : createTokenClass ,
MailtoEmail : MailtoEmail ,
Email : Email ,
Text : Text ,
Nl : Nl ,
Url : Url
} ) ;
/ * *
Not exactly parser , more like the second - stage scanner ( although we can
theoretically hotswap the code here with a real parser in the future ... but
for a little URL - finding utility abstract syntax trees may be a little
overkill ) .
URL format : http : //en.wikipedia.org/wiki/URI_scheme
Email format : http : //en.wikipedia.org/wiki/Email_address (links to RFC in
reference )
@ module linkify
@ submodule parser
@ main run
* /
/ * *
* Generate the parser multi token - based state machine
* @ returns { State } the starting state
* /
function init$1 ( ) {
// The universal starting state.
var S _START = makeState ( ) ; // Intermediate states for URLs. Note that domains that begin with a protocol
// are treated slighly differently from those that don't.
var S _PROTOCOL = makeState ( ) ; // e.g., 'http:'
var S _MAILTO = makeState ( ) ; // 'mailto:'
var S _PROTOCOL _SLASH = makeState ( ) ; // e.g., 'http:/''
var S _PROTOCOL _SLASH _SLASH = makeState ( ) ; // e.g.,'http://'
var S _DOMAIN = makeState ( ) ; // parsed string ends with a potential domain name (A)
var S _DOMAIN _DOT = makeState ( ) ; // (A) domain followed by DOT
var S _TLD = makeAcceptingState ( Url ) ; // (A) Simplest possible URL with no query string
var S _TLD _COLON = makeState ( ) ; // (A) URL followed by colon (potential port number here)
var S _TLD _PORT = makeAcceptingState ( Url ) ; // TLD followed by a port number
var S _URL = makeAcceptingState ( Url ) ; // Long URL with optional port and maybe query string
var S _URL _NON _ACCEPTING = makeState ( ) ; // URL followed by some symbols (will not be part of the final URL)
var S _URL _OPENBRACE = makeState ( ) ; // URL followed by {
var S _URL _OPENBRACKET = makeState ( ) ; // URL followed by [
var S _URL _OPENANGLEBRACKET = makeState ( ) ; // URL followed by <
var S _URL _OPENPAREN = makeState ( ) ; // URL followed by (
var S _URL _OPENBRACE _Q = makeAcceptingState ( Url ) ; // URL followed by { and some symbols that the URL can end it
var S _URL _OPENBRACKET _Q = makeAcceptingState ( Url ) ; // URL followed by [ and some symbols that the URL can end it
var S _URL _OPENANGLEBRACKET _Q = makeAcceptingState ( Url ) ; // URL followed by < and some symbols that the URL can end it
var S _URL _OPENPAREN _Q = makeAcceptingState ( Url ) ; // URL followed by ( and some symbols that the URL can end it
var S _URL _OPENBRACE _SYMS = makeState ( ) ; // S_URL_OPENBRACE_Q followed by some symbols it cannot end it
var S _URL _OPENBRACKET _SYMS = makeState ( ) ; // S_URL_OPENBRACKET_Q followed by some symbols it cannot end it
var S _URL _OPENANGLEBRACKET _SYMS = makeState ( ) ; // S_URL_OPENANGLEBRACKET_Q followed by some symbols it cannot end it
var S _URL _OPENPAREN _SYMS = makeState ( ) ; // S_URL_OPENPAREN_Q followed by some symbols it cannot end it
var S _EMAIL _DOMAIN = makeState ( ) ; // parsed string starts with local email info + @ with a potential domain name (C)
var S _EMAIL _DOMAIN _DOT = makeState ( ) ; // (C) domain followed by DOT
var S _EMAIL = makeAcceptingState ( Email ) ; // (C) Possible email address (could have more tlds)
var S _EMAIL _COLON = makeState ( ) ; // (C) URL followed by colon (potential port number here)
var S _EMAIL _PORT = makeAcceptingState ( Email ) ; // (C) Email address with a port
var S _MAILTO _EMAIL = makeAcceptingState ( MailtoEmail ) ; // Email that begins with the mailto prefix (D)
var S _MAILTO _EMAIL _NON _ACCEPTING = makeState ( ) ; // (D) Followed by some non-query string chars
var S _LOCALPART = makeState ( ) ; // Local part of the email address
var S _LOCALPART _AT = makeState ( ) ; // Local part of the email address plus @
var S _LOCALPART _DOT = makeState ( ) ; // Local part of the email address plus '.' (localpart cannot end in .)
var S _NL = makeAcceptingState ( Nl ) ; // single new line
// Make path from start to protocol (with '//')
makeT ( S _START , NL , S _NL ) ;
makeT ( S _START , PROTOCOL , S _PROTOCOL ) ;
makeT ( S _START , MAILTO , S _MAILTO ) ;
makeT ( S _PROTOCOL , SLASH , S _PROTOCOL _SLASH ) ;
makeT ( S _PROTOCOL _SLASH , SLASH , S _PROTOCOL _SLASH _SLASH ) ; // The very first potential domain name
makeT ( S _START , TLD , S _DOMAIN ) ;
makeT ( S _START , DOMAIN , S _DOMAIN ) ;
makeT ( S _START , LOCALHOST , S _TLD ) ;
makeT ( S _START , NUM , S _DOMAIN ) ; // Force URL for protocol followed by anything sane
makeT ( S _PROTOCOL _SLASH _SLASH , TLD , S _URL ) ;
makeT ( S _PROTOCOL _SLASH _SLASH , DOMAIN , S _URL ) ;
makeT ( S _PROTOCOL _SLASH _SLASH , NUM , S _URL ) ;
makeT ( S _PROTOCOL _SLASH _SLASH , LOCALHOST , S _URL ) ; // Account for dots and hyphens
// hyphens are usually parts of domain names
makeT ( S _DOMAIN , DOT , S _DOMAIN _DOT ) ;
makeT ( S _EMAIL _DOMAIN , DOT , S _EMAIL _DOMAIN _DOT ) ; // Hyphen can jump back to a domain name
// After the first domain and a dot, we can find either a URL or another domain
makeT ( S _DOMAIN _DOT , TLD , S _TLD ) ;
makeT ( S _DOMAIN _DOT , DOMAIN , S _DOMAIN ) ;
makeT ( S _DOMAIN _DOT , NUM , S _DOMAIN ) ;
makeT ( S _DOMAIN _DOT , LOCALHOST , S _DOMAIN ) ;
makeT ( S _EMAIL _DOMAIN _DOT , TLD , S _EMAIL ) ;
makeT ( S _EMAIL _DOMAIN _DOT , DOMAIN , S _EMAIL _DOMAIN ) ;
makeT ( S _EMAIL _DOMAIN _DOT , NUM , S _EMAIL _DOMAIN ) ;
makeT ( S _EMAIL _DOMAIN _DOT , LOCALHOST , S _EMAIL _DOMAIN ) ; // S_TLD accepts! But the URL could be longer, try to find a match greedily
// The `run` function should be able to "rollback" to the accepting state
makeT ( S _TLD , DOT , S _DOMAIN _DOT ) ;
makeT ( S _EMAIL , DOT , S _EMAIL _DOMAIN _DOT ) ; // Become real URLs after `SLASH` or `COLON NUM SLASH`
// Here PSS and non-PSS converge
makeT ( S _TLD , COLON , S _TLD _COLON ) ;
makeT ( S _TLD , SLASH , S _URL ) ;
makeT ( S _TLD _COLON , NUM , S _TLD _PORT ) ;
makeT ( S _TLD _PORT , SLASH , S _URL ) ;
makeT ( S _EMAIL , COLON , S _EMAIL _COLON ) ;
makeT ( S _EMAIL _COLON , NUM , S _EMAIL _PORT ) ; // Types of characters the URL can definitely end in
2022-01-19 15:03:45 +01:00
var qsAccepting = [ AMPERSAND , ASTERISK , AT , BACKSLASH , BACKTICK , CARET , DOLLAR , DOMAIN , EQUALS , HYPHEN , LOCALHOST , NUM , PERCENT , PIPE , PLUS , POUND , PROTOCOL , SLASH , SYM , TILDE , TLD , UNDERSCORE ] ; // Types of tokens that can follow a URL and be part of the query string
2021-05-28 16:46:29 +02:00
// but cannot be the very last characters
// Characters that cannot appear in the URL at all should be excluded
2022-01-19 15:03:45 +01:00
var qsNonAccepting = [ APOSTROPHE , CLOSEANGLEBRACKET , CLOSEBRACE , CLOSEBRACKET , CLOSEPAREN , COLON , COMMA , DOT , EXCLAMATION , OPENANGLEBRACKET , OPENBRACE , OPENBRACKET , OPENPAREN , QUERY , QUOTE , SEMI ] ; // These states are responsible primarily for determining whether or not to
2021-05-28 16:46:29 +02:00
// include the final round bracket.
// URL, followed by an opening bracket
makeT ( S _URL , OPENBRACE , S _URL _OPENBRACE ) ;
makeT ( S _URL , OPENBRACKET , S _URL _OPENBRACKET ) ;
makeT ( S _URL , OPENANGLEBRACKET , S _URL _OPENANGLEBRACKET ) ;
makeT ( S _URL , OPENPAREN , S _URL _OPENPAREN ) ; // URL with extra symbols at the end, followed by an opening bracket
makeT ( S _URL _NON _ACCEPTING , OPENBRACE , S _URL _OPENBRACE ) ;
makeT ( S _URL _NON _ACCEPTING , OPENBRACKET , S _URL _OPENBRACKET ) ;
makeT ( S _URL _NON _ACCEPTING , OPENANGLEBRACKET , S _URL _OPENANGLEBRACKET ) ;
makeT ( S _URL _NON _ACCEPTING , OPENPAREN , S _URL _OPENPAREN ) ; // Closing bracket component. This character WILL be included in the URL
makeT ( S _URL _OPENBRACE , CLOSEBRACE , S _URL ) ;
makeT ( S _URL _OPENBRACKET , CLOSEBRACKET , S _URL ) ;
makeT ( S _URL _OPENANGLEBRACKET , CLOSEANGLEBRACKET , S _URL ) ;
makeT ( S _URL _OPENPAREN , CLOSEPAREN , S _URL ) ;
makeT ( S _URL _OPENBRACE _Q , CLOSEBRACE , S _URL ) ;
makeT ( S _URL _OPENBRACKET _Q , CLOSEBRACKET , S _URL ) ;
makeT ( S _URL _OPENANGLEBRACKET _Q , CLOSEANGLEBRACKET , S _URL ) ;
makeT ( S _URL _OPENPAREN _Q , CLOSEPAREN , S _URL ) ;
makeT ( S _URL _OPENBRACE _SYMS , CLOSEBRACE , S _URL ) ;
makeT ( S _URL _OPENBRACKET _SYMS , CLOSEBRACKET , S _URL ) ;
makeT ( S _URL _OPENANGLEBRACKET _SYMS , CLOSEANGLEBRACKET , S _URL ) ;
makeT ( S _URL _OPENPAREN _SYMS , CLOSEPAREN , S _URL ) ; // URL that beings with an opening bracket, followed by a symbols.
// Note that the final state can still be `S_URL_OPENBRACE_Q` (if the URL only
// has a single opening bracket for some reason).
makeMultiT ( S _URL _OPENBRACE , qsAccepting , S _URL _OPENBRACE _Q ) ;
makeMultiT ( S _URL _OPENBRACKET , qsAccepting , S _URL _OPENBRACKET _Q ) ;
makeMultiT ( S _URL _OPENANGLEBRACKET , qsAccepting , S _URL _OPENANGLEBRACKET _Q ) ;
makeMultiT ( S _URL _OPENPAREN , qsAccepting , S _URL _OPENPAREN _Q ) ;
makeMultiT ( S _URL _OPENBRACE , qsNonAccepting , S _URL _OPENBRACE _SYMS ) ;
makeMultiT ( S _URL _OPENBRACKET , qsNonAccepting , S _URL _OPENBRACKET _SYMS ) ;
makeMultiT ( S _URL _OPENANGLEBRACKET , qsNonAccepting , S _URL _OPENANGLEBRACKET _SYMS ) ;
makeMultiT ( S _URL _OPENPAREN , qsNonAccepting , S _URL _OPENPAREN _SYMS ) ; // URL that begins with an opening bracket, followed by some symbols
makeMultiT ( S _URL _OPENBRACE _Q , qsAccepting , S _URL _OPENBRACE _Q ) ;
makeMultiT ( S _URL _OPENBRACKET _Q , qsAccepting , S _URL _OPENBRACKET _Q ) ;
makeMultiT ( S _URL _OPENANGLEBRACKET _Q , qsAccepting , S _URL _OPENANGLEBRACKET _Q ) ;
makeMultiT ( S _URL _OPENPAREN _Q , qsAccepting , S _URL _OPENPAREN _Q ) ;
makeMultiT ( S _URL _OPENBRACE _Q , qsNonAccepting , S _URL _OPENBRACE _Q ) ;
makeMultiT ( S _URL _OPENBRACKET _Q , qsNonAccepting , S _URL _OPENBRACKET _Q ) ;
makeMultiT ( S _URL _OPENANGLEBRACKET _Q , qsNonAccepting , S _URL _OPENANGLEBRACKET _Q ) ;
makeMultiT ( S _URL _OPENPAREN _Q , qsNonAccepting , S _URL _OPENPAREN _Q ) ;
makeMultiT ( S _URL _OPENBRACE _SYMS , qsAccepting , S _URL _OPENBRACE _Q ) ;
makeMultiT ( S _URL _OPENBRACKET _SYMS , qsAccepting , S _URL _OPENBRACKET _Q ) ;
makeMultiT ( S _URL _OPENANGLEBRACKET _SYMS , qsAccepting , S _URL _OPENANGLEBRACKET _Q ) ;
makeMultiT ( S _URL _OPENPAREN _SYMS , qsAccepting , S _URL _OPENPAREN _Q ) ;
makeMultiT ( S _URL _OPENBRACE _SYMS , qsNonAccepting , S _URL _OPENBRACE _SYMS ) ;
makeMultiT ( S _URL _OPENBRACKET _SYMS , qsNonAccepting , S _URL _OPENBRACKET _SYMS ) ;
makeMultiT ( S _URL _OPENANGLEBRACKET _SYMS , qsNonAccepting , S _URL _OPENANGLEBRACKET _SYMS ) ;
makeMultiT ( S _URL _OPENPAREN _SYMS , qsNonAccepting , S _URL _OPENPAREN _SYMS ) ; // Account for the query string
makeMultiT ( S _URL , qsAccepting , S _URL ) ;
makeMultiT ( S _URL _NON _ACCEPTING , qsAccepting , S _URL ) ;
makeMultiT ( S _URL , qsNonAccepting , S _URL _NON _ACCEPTING ) ;
makeMultiT ( S _URL _NON _ACCEPTING , qsNonAccepting , S _URL _NON _ACCEPTING ) ; // Email address-specific state definitions
// Note: We are not allowing '/' in email addresses since this would interfere
// with real URLs
// For addresses with the mailto prefix
// 'mailto:' followed by anything sane is a valid email
makeT ( S _MAILTO , TLD , S _MAILTO _EMAIL ) ;
makeT ( S _MAILTO , DOMAIN , S _MAILTO _EMAIL ) ;
makeT ( S _MAILTO , NUM , S _MAILTO _EMAIL ) ;
makeT ( S _MAILTO , LOCALHOST , S _MAILTO _EMAIL ) ; // Greedily get more potential valid email values
makeMultiT ( S _MAILTO _EMAIL , qsAccepting , S _MAILTO _EMAIL ) ;
makeMultiT ( S _MAILTO _EMAIL , qsNonAccepting , S _MAILTO _EMAIL _NON _ACCEPTING ) ;
makeMultiT ( S _MAILTO _EMAIL _NON _ACCEPTING , qsAccepting , S _MAILTO _EMAIL ) ;
makeMultiT ( S _MAILTO _EMAIL _NON _ACCEPTING , qsNonAccepting , S _MAILTO _EMAIL _NON _ACCEPTING ) ; // For addresses without the mailto prefix
// Tokens allowed in the localpart of the email
2022-01-19 15:03:45 +01:00
var localpartAccepting = [ AMPERSAND , APOSTROPHE , ASTERISK , BACKSLASH , BACKTICK , CARET , CLOSEBRACE , DOLLAR , DOMAIN , EQUALS , HYPHEN , NUM , OPENBRACE , PERCENT , PIPE , PLUS , POUND , QUERY , SLASH , SYM , TILDE , TLD , UNDERSCORE ] ; // Some of the tokens in `localpartAccepting` are already accounted for here and
2021-05-28 16:46:29 +02:00
// will not be overwritten (don't worry)
makeMultiT ( S _DOMAIN , localpartAccepting , S _LOCALPART ) ;
makeT ( S _DOMAIN , AT , S _LOCALPART _AT ) ;
makeMultiT ( S _TLD , localpartAccepting , S _LOCALPART ) ;
makeT ( S _TLD , AT , S _LOCALPART _AT ) ;
makeMultiT ( S _DOMAIN _DOT , localpartAccepting , S _LOCALPART ) ; // Now in localpart of address
// TODO: IP addresses and what if the email starts with numbers?
makeMultiT ( S _LOCALPART , localpartAccepting , S _LOCALPART ) ;
makeT ( S _LOCALPART , AT , S _LOCALPART _AT ) ; // close to an email address now
makeT ( S _LOCALPART , DOT , S _LOCALPART _DOT ) ;
makeMultiT ( S _LOCALPART _DOT , localpartAccepting , S _LOCALPART ) ;
makeT ( S _LOCALPART _AT , TLD , S _EMAIL _DOMAIN ) ;
makeT ( S _LOCALPART _AT , DOMAIN , S _EMAIL _DOMAIN ) ;
makeT ( S _LOCALPART _AT , NUM , S _EMAIL _DOMAIN ) ;
makeT ( S _LOCALPART _AT , LOCALHOST , S _EMAIL ) ; // States following `@` defined above
return S _START ;
}
/ * *
* Run the parser state machine on a list of scanned string - based tokens to
* create a list of multi tokens , each of which represents a URL , email address ,
* plain text , etc .
*
* @ param { State } start parser start state
* @ param { string } input the original input used to generate the given tokens
2022-01-19 15:03:45 +01:00
* @ param { { t : string , v : string , s : number , e : number } [ ] } tokens list of scanned tokens
* @ returns { MultiToken [ ] }
2021-05-28 16:46:29 +02:00
* /
function run ( start , input , tokens ) {
var len = tokens . length ;
var cursor = 0 ;
var multis = [ ] ;
var textTokens = [ ] ;
while ( cursor < len ) {
var state = start ;
var secondState = null ;
var nextState = null ;
var multiLength = 0 ;
var latestAccepting = null ;
var sinceAccepts = - 1 ;
while ( cursor < len && ! ( secondState = takeT ( state , tokens [ cursor ] . t ) ) ) {
// Starting tokens with nowhere to jump to.
// Consider these to be just plain text
textTokens . push ( tokens [ cursor ++ ] ) ;
}
while ( cursor < len && ( nextState = secondState || takeT ( state , tokens [ cursor ] . t ) ) ) {
// Get the next state
secondState = null ;
state = nextState ; // Keep track of the latest accepting state
if ( state . accepts ( ) ) {
sinceAccepts = 0 ;
latestAccepting = state ;
} else if ( sinceAccepts >= 0 ) {
sinceAccepts ++ ;
}
cursor ++ ;
multiLength ++ ;
}
if ( sinceAccepts < 0 ) {
// No accepting state was found, part of a regular text token
// Add all the tokens we looked at to the text tokens array
for ( var i = cursor - multiLength ; i < cursor ; i ++ ) {
textTokens . push ( tokens [ i ] ) ;
}
} else {
// Accepting state!
// First close off the textTokens (if available)
if ( textTokens . length > 0 ) {
multis . push ( parserCreateMultiToken ( Text , input , textTokens ) ) ;
textTokens = [ ] ;
} // Roll back to the latest accepting state
cursor -= sinceAccepts ;
multiLength -= sinceAccepts ; // Create a new multitoken
var Multi = latestAccepting . t ;
var subtokens = tokens . slice ( cursor - multiLength , cursor ) ;
multis . push ( parserCreateMultiToken ( Multi , input , subtokens ) ) ;
}
} // Finally close off the textTokens (if available)
if ( textTokens . length > 0 ) {
multis . push ( parserCreateMultiToken ( Text , input , textTokens ) ) ;
}
return multis ;
}
/ * *
* Utility function for instantiating a new multitoken with all the relevant
* fields during parsing .
* @ param { Class < MultiToken > } Multi class to instantiate
* @ param { string } input original input string
2022-01-19 15:03:45 +01:00
* @ param { { t : string , v : string , s : number , e : number } [ ] } tokens consecutive tokens scanned from input string
2021-05-28 16:46:29 +02:00
* @ returns { MultiToken }
* /
function parserCreateMultiToken ( Multi , input , tokens ) {
var startIdx = tokens [ 0 ] . s ;
var endIdx = tokens [ tokens . length - 1 ] . e ;
var value = input . substr ( startIdx , endIdx - startIdx ) ;
return new Multi ( value , tokens ) ;
}
var warn = typeof console !== 'undefined' && console && console . warn || function ( ) { } ; // Side-effect initialization state
var INIT = {
scanner : null ,
parser : null ,
pluginQueue : [ ] ,
customProtocols : [ ] ,
initialized : false
} ;
/ * *
* De - register all plugins and reset the internal state - machine . Used for
* testing ; not required in practice .
* @ private
* /
function reset ( ) {
INIT . scanner = null ;
INIT . parser = null ;
INIT . pluginQueue = [ ] ;
INIT . customProtocols = [ ] ;
INIT . initialized = false ;
}
/ * *
* Register a linkify extension plugin
* @ param { string } name of plugin to register
* @ param { Function } plugin function that accepts mutable linkify state
* /
function registerPlugin ( name , plugin ) {
for ( var i = 0 ; i < INIT . pluginQueue . length ; i ++ ) {
if ( name === INIT . pluginQueue [ i ] [ 0 ] ) {
warn ( "linkifyjs: plugin \"" . concat ( name , "\" already registered - will be overwritten" ) ) ;
INIT . pluginQueue [ i ] = [ name , plugin ] ;
return ;
}
}
INIT . pluginQueue . push ( [ name , plugin ] ) ;
if ( INIT . initialized ) {
warn ( "linkifyjs: already initialized - will not register plugin \"" . concat ( name , "\" until you manually call linkify.init(). To avoid this warning, please register all plugins before invoking linkify the first time." ) ) ;
}
}
/ * *
* Detect URLs with the following additional protocol . Anything following
* "protocol:" will be considered a link .
* @ param { string } protocol
* /
function registerCustomProtocol ( protocol ) {
if ( INIT . initialized ) {
warn ( "linkifyjs: already initialized - will not register custom protocol \"" . concat ( protocol , "\" until you manually call linkify.init(). To avoid this warning, please register all custom protocols before invoking linkify the first time." ) ) ;
}
2022-01-19 15:03:45 +01:00
if ( ! /^[a-z-]+$/ . test ( protocol ) ) {
throw Error ( 'linkifyjs: protocols containing characters other than a-z or - (hyphen) are not supported' ) ;
2021-05-28 16:46:29 +02:00
}
INIT . customProtocols . push ( protocol ) ;
}
/ * *
* Initialize the linkify state machine . Called automatically the first time
* linkify is called on a string , but may be called manually as well .
* /
function init ( ) {
// Initialize state machines
INIT . scanner = {
start : init$2 ( INIT . customProtocols ) ,
tokens : text
} ;
INIT . parser = {
start : init$1 ( ) ,
tokens : multi
} ;
var utils = {
createTokenClass : createTokenClass
} ; // Initialize plugins
for ( var i = 0 ; i < INIT . pluginQueue . length ; i ++ ) {
INIT . pluginQueue [ i ] [ 1 ] ( {
scanner : INIT . scanner ,
parser : INIT . parser ,
utils : utils
} ) ;
}
INIT . initialized = true ;
}
/ * *
2022-01-19 15:03:45 +01:00
Parse a string into tokens that represent linkable and non - linkable sub - components
2021-05-28 16:46:29 +02:00
@ param { string } str
2022-01-19 15:03:45 +01:00
@ return { MultiToken [ ] } tokens
2021-05-28 16:46:29 +02:00
* /
function tokenize ( str ) {
if ( ! INIT . initialized ) {
init ( ) ;
}
return run ( INIT . parser . start , str , run$1 ( INIT . scanner . start , str ) ) ;
}
/ * *
2022-01-19 15:03:45 +01:00
Find a list of linkable items in the given string .
2021-05-28 16:46:29 +02:00
@ param { string } str string to find links in
2022-01-19 15:03:45 +01:00
@ param { string } [ type ] ( optional ) only find links of a specific type , e . g . ,
2021-05-28 16:46:29 +02:00
'url' or 'email'
* /
function find ( str ) {
var type = arguments . length > 1 && arguments [ 1 ] !== undefined ? arguments [ 1 ] : null ;
var tokens = tokenize ( str ) ;
var filtered = [ ] ;
for ( var i = 0 ; i < tokens . length ; i ++ ) {
var token = tokens [ i ] ;
if ( token . isLink && ( ! type || token . t === type ) ) {
filtered . push ( token . toObject ( ) ) ;
}
}
return filtered ;
}
/ * *
* Is the given string valid linkable text of some sort . Note that this does not
* trim the text for you .
*
* Optionally pass in a second ` type ` param , which is the type of link to test
* for .
*
* For example ,
*
* linkify . test ( str , 'email' ) ;
*
* Returns ` true ` if str is a valid email .
* @ param { string } str string to test for links
* @ param { string } [ type ] optional specific link type to look for
* @ returns boolean true / false
* /
function test ( str ) {
var type = arguments . length > 1 && arguments [ 1 ] !== undefined ? arguments [ 1 ] : null ;
var tokens = tokenize ( str ) ;
return tokens . length === 1 && tokens [ 0 ] . isLink && ( ! type || tokens [ 0 ] . t === type ) ;
}
2022-01-19 15:17:38 +01:00
export { Options , find , init , options , registerCustomProtocol , registerPlugin , reset , test , tokenize } ;