Tweak/rewrite Linkify.
This commit is contained in:
parent
58531319ca
commit
6d5f422c3f
@ -2,91 +2,73 @@ Linkify =
|
|||||||
init: ->
|
init: ->
|
||||||
return if g.VIEW is 'catalog' or !Conf['Linkify']
|
return if g.VIEW is 'catalog' or !Conf['Linkify']
|
||||||
|
|
||||||
@catchAll = /\b(?:([a-z][\w-]+):(?:\/{1,3}|[a-z0-9%]|(\?(?:dn|xl|xt|as|xs|kt|mt|tr)=))|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\((?:[^\s()<>]+|(?:\([^\s()<>]+\)))*\))+(?:\((?:[^\s()<>]+|(?:\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’])/i
|
# gruber revised + magnet support
|
||||||
|
# http://rodneyrehm.de/t/url-regex.html
|
||||||
@globalCatchAll = ///#{@catchAll.source}///g
|
@catchAll = /\b([a-z][\w-]+:(\/{1,3}|[a-z0-9%]|\?(dn|x[lts]|as|kt|mt|tr)=)|www\d{0,3}\.|[a-z0-9.\-]+\.[a-z]{2,4}\/)([^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’])/g
|
||||||
|
|
||||||
Post::callbacks.push
|
Post::callbacks.push
|
||||||
name: 'Linkify'
|
name: 'Linkify'
|
||||||
cb: @node
|
cb: @node
|
||||||
|
|
||||||
node: ->
|
node: ->
|
||||||
return if @isClone or !links = @info.comment.match Linkify.globalCatchAll
|
return if @isClone or !links = @info.comment.match Linkify.catchAll
|
||||||
walker = d.createTreeWalker @nodes.comment, 4, null, false
|
walker = d.createTreeWalker @nodes.comment, 4
|
||||||
anchor = false
|
for link in links
|
||||||
while (node = walker.nextNode())?
|
boundaries = Linkify.find link, walker
|
||||||
{parentNode} = node
|
# continue unless boundaries
|
||||||
if parentNode.nodeName is 'A'
|
anchor = Linkify.createLink link
|
||||||
# prettyprint has some issues
|
if Linkify.surround anchor, link, boundaries
|
||||||
if parentNode.textContent is links[0]
|
Linkify.cleanLink anchor if Conf['Clean Links']
|
||||||
delete links[0]
|
walker.currentNode = anchor.lastChild
|
||||||
walker.currentNode = parentNode.lastChild
|
else
|
||||||
continue
|
walker.currentNode = boundaries.endNode
|
||||||
continue unless data = node.data
|
|
||||||
while !anchor
|
|
||||||
return unless link = links.shift()
|
|
||||||
[anchor, link] = Linkify.parseLink link
|
|
||||||
if data.length >= link.length and (index = data.indexOf link) >= 0
|
|
||||||
walker.currentNode = Linkify.surround anchor, link, index, index + link.length, node
|
|
||||||
anchor = false
|
|
||||||
continue
|
|
||||||
index = found = 0
|
|
||||||
nextContent = node.nextSibling?.textContent
|
|
||||||
while index isnt data.length
|
|
||||||
start = data[index++..]
|
|
||||||
startLength = start.length
|
|
||||||
threshold = startLength is 2
|
|
||||||
if threshold and nextContent and link[...startLength + nextContent.length] is start + nextContent
|
|
||||||
found = true
|
|
||||||
if threshold or found = link[...startLength] is start
|
|
||||||
index--
|
|
||||||
break
|
|
||||||
continue unless found
|
|
||||||
startNode = node
|
|
||||||
while start.length < link.length
|
|
||||||
start += data = (node = walker.nextNode())?.data
|
|
||||||
if Conf['Clean Links']
|
|
||||||
{parentNode} = node
|
|
||||||
if parentNode.nodeName is 'S' and parentNode.textContent.length < link.length
|
|
||||||
$.replace parentNode, node
|
|
||||||
continue unless start[...link.length] is link
|
|
||||||
endIndex = link[start.length - data.length...].length
|
|
||||||
walker.currentNode = Linkify.surround anchor, link, index, endIndex, startNode, node
|
|
||||||
anchor = false
|
|
||||||
return
|
return
|
||||||
|
|
||||||
parseLink: (link) ->
|
find: (link, walker) ->
|
||||||
unless result = link.match @catchAll
|
# Walk through the nodes until we find the entire link.
|
||||||
return false
|
text = ''
|
||||||
[link, protocol, isMagnet] = result
|
while node = walker.nextNode()
|
||||||
try
|
{data} = node
|
||||||
decodeURIComponent link
|
text += node.data
|
||||||
catch
|
if text.indexOf(link) > -1
|
||||||
return false
|
startNode = endNode = node
|
||||||
target = if isMagnet or /^(irc|ftps?)$/.test protocol
|
break
|
||||||
'_self'
|
|
||||||
else
|
|
||||||
'_blank'
|
|
||||||
href = if protocol
|
|
||||||
link
|
|
||||||
else
|
|
||||||
"http://#{link}"
|
|
||||||
anchor = $.el 'a',
|
|
||||||
target: target
|
|
||||||
href: href
|
|
||||||
rel: 'noreferrer'
|
|
||||||
[anchor, link]
|
|
||||||
|
|
||||||
surround: (anchor, link, startIndex, endIndex, startNode, endNode = startNode) ->
|
# Walk backwards to find the startNode.
|
||||||
parent = startNode.parentNode
|
text = data
|
||||||
if parent?.nodeName is 'S' and parent.textContent.length < link.length
|
until (index = text.indexOf link) > -1
|
||||||
parentClone = parent.cloneNode true
|
startNode = walker.previousNode()
|
||||||
$.replace parent, startNode
|
text = "#{startNode.data}#{text}"
|
||||||
|
|
||||||
|
return {
|
||||||
|
startNode, endNode
|
||||||
|
startOffset: index
|
||||||
|
endOffset: endNode.length - (text.length - index - link.length)
|
||||||
|
}
|
||||||
|
|
||||||
|
createLink: (link) ->
|
||||||
|
unless /^[a-z][\w-]+:/.test link
|
||||||
|
link = "http://#{link}"
|
||||||
|
a = $.el 'a',
|
||||||
|
href: link
|
||||||
|
target: '_blank'
|
||||||
|
a
|
||||||
|
|
||||||
|
surround: (anchor, link, {startOffset, endOffset, startNode, endNode}) ->
|
||||||
|
# parent = startNode.parentNode
|
||||||
|
# if parent?.nodeName is 'S' and parent.textContent.length < link.length
|
||||||
|
# parentClone = parent.cloneNode true
|
||||||
|
# $.replace parent, startNode
|
||||||
range = d.createRange()
|
range = d.createRange()
|
||||||
range.setStart startNode, startIndex
|
range.setStart startNode, startOffset
|
||||||
range.setEnd endNode, endIndex
|
range.setEnd endNode, endOffset
|
||||||
try
|
try
|
||||||
range.surroundContents anchor
|
range.surroundContents anchor
|
||||||
if !Conf['Clean Links'] and parentClone and anchor.firstChild
|
# if !Conf['Clean Links'] and parentClone and anchor.firstChild
|
||||||
$.replace anchor.firstChild, parentClone
|
# $.replace anchor.firstChild, parentClone
|
||||||
endNode
|
true
|
||||||
|
catch
|
||||||
|
false
|
||||||
|
|
||||||
|
cleanLink: (anchor) ->
|
||||||
|
# TODO
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user