Add Linkification.
This commit is contained in:
parent
a1e8d1a924
commit
202d7617e3
@ -31,6 +31,7 @@ module.exports = (grunt) ->
|
||||
'src/Quotelinks/**/*'
|
||||
'src/Posting/**/*'
|
||||
'src/Images/**/*'
|
||||
'src/Linkification/**/*'
|
||||
'src/Menu/**/*'
|
||||
'src/Monitoring/**/*'
|
||||
'src/Archive/**/*'
|
||||
|
||||
@ -27,6 +27,9 @@ Config =
|
||||
'Image Hover': [false, 'Show a floating expanded image on hover.']
|
||||
'Sauce': [true, 'Add sauce links to images.']
|
||||
'Reveal Spoilers': [false, 'Reveal spoiler thumbnails.']
|
||||
'Linkification':
|
||||
'Linkify': [true, 'Convert text links into hyperlinks.']
|
||||
'Clean Links': [true, 'Remove spoiler texts commonly used to bypass banned links.']
|
||||
'Menu':
|
||||
'Menu': [true, 'Add a drop-down menu to posts.']
|
||||
'Report Link': [true, 'Add a report link to the menu.']
|
||||
|
||||
@ -128,6 +128,7 @@ Main =
|
||||
initFeature 'Index Navigation', Nav
|
||||
initFeature 'Keybinds', Keybinds
|
||||
initFeature 'Show Dice Roll', Dice
|
||||
initFeature 'Linkify', Linkify
|
||||
# c.timeEnd 'All initializations'
|
||||
|
||||
$.on d, 'AddCallback', Main.addCallback
|
||||
|
||||
92
src/Linkification/Linkify.coffee
Normal file
92
src/Linkification/Linkify.coffee
Normal file
@ -0,0 +1,92 @@
|
||||
Linkify =
|
||||
init: ->
|
||||
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
|
||||
|
||||
@globalCatchAll = ///#{@catchAll.source}///g
|
||||
|
||||
Post::callbacks.push
|
||||
name: 'Linkify'
|
||||
cb: @node
|
||||
|
||||
node: ->
|
||||
return if @isClone or !links = @info.comment.match Linkify.globalCatchAll
|
||||
walker = d.createTreeWalker @nodes.comment, 4, null, false
|
||||
anchor = false
|
||||
while (node = walker.nextNode())?
|
||||
{parentNode} = node
|
||||
if parentNode.nodeName is 'A'
|
||||
# prettyprint has some issues
|
||||
if parentNode.textContent is links[0]
|
||||
delete links[0]
|
||||
walker.currentNode = parentNode.lastChild
|
||||
continue
|
||||
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.sourround 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
|
||||
{parentNode} = node
|
||||
if parentNode.nodeName is 'S' and Conf['Clean Links']
|
||||
$.replace parentNode, node
|
||||
continue unless start[...link.length] is link
|
||||
endIndex = link[start.length - data.length...].length
|
||||
walker.currentNode = Linkify.sourround anchor, link, index, endIndex, startNode, node
|
||||
anchor = false
|
||||
return
|
||||
|
||||
parseLink: (link) ->
|
||||
unless result = link.match @catchAll
|
||||
return false
|
||||
[link, protocol, isMagnet] = result
|
||||
try
|
||||
decodeURIComponent link
|
||||
catch
|
||||
return false
|
||||
target = if isMagnet or /^(irc|ftps?)$/.test protocol
|
||||
'_self'
|
||||
else
|
||||
'_blank'
|
||||
href = if protocol
|
||||
link
|
||||
else
|
||||
"http://#{link}"
|
||||
anchor = $.el 'a',
|
||||
target: target
|
||||
href: href
|
||||
rel: 'noreferrer'
|
||||
[anchor, link]
|
||||
|
||||
sourround: (anchor, link, startIndex, endIndex, startNode, endNode = startNode) ->
|
||||
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.setStart startNode, startIndex
|
||||
range.setEnd endNode, endIndex
|
||||
try
|
||||
range.surroundContents anchor
|
||||
if !Conf['Clean Links'] and parentClone and anchor.firstChild
|
||||
$.replace anchor.firstChild, parentClone
|
||||
catch
|
||||
endNode
|
||||
@ -72,3 +72,5 @@ ExpandComment =
|
||||
Fourchan.code.call post
|
||||
if g.BOARD.ID is 'sci'
|
||||
Fourchan.math.call post
|
||||
if Conf['Linkify']
|
||||
Linkify.node.call post
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user