Tweak/rewrite Linkify.

This commit is contained in:
Mayhem 2013-08-19 12:21:49 +02:00
parent 58531319ca
commit 6d5f422c3f

View File

@ -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