143 lines
4.9 KiB
CoffeeScript
143 lines
4.9 KiB
CoffeeScript
SW.yotsuba =
|
|
isOPContainerThread: false
|
|
|
|
urls:
|
|
thread: ({boardID, threadID}) -> "#{location.protocol}//#{BoardConfig.domain(boardID)}/#{boardID}/thread/#{threadID}"
|
|
|
|
selectors:
|
|
board: '.board'
|
|
thread: '.thread'
|
|
threadDivider: '.board > hr'
|
|
summary: '.summary'
|
|
postContainer: '.postContainer'
|
|
sideArrows: '.sideArrows'
|
|
post: '.post'
|
|
infoRoot: '.postInfo'
|
|
info:
|
|
subject: '.subject'
|
|
name: '.name'
|
|
email: '.useremail'
|
|
tripcode: '.postertrip'
|
|
uniqueIDRoot: '.posteruid'
|
|
uniqueID: '.posteruid > .hand'
|
|
capcode: '.capcode.hand'
|
|
pass: '.n-pu'
|
|
flag: '.flag, .countryFlag'
|
|
date: '.dateTime'
|
|
nameBlock: '.nameBlock'
|
|
quote: '.postNum > a:nth-of-type(2)'
|
|
reply: '.replylink'
|
|
icons:
|
|
isSticky: '.stickyIcon'
|
|
isClosed: '.closedIcon'
|
|
isArchived: '.archivedIcon'
|
|
file:
|
|
text: '.file > :first-child'
|
|
link: '.fileText > a'
|
|
thumb: 'a.fileThumb > [data-md5]'
|
|
comment: '.postMessage'
|
|
spoiler: 's'
|
|
quotelink: ':not(pre) > .quotelink' # XXX https://github.com/4chan/4chan-JS/issues/77: 4chan currently creates quote links inside [code] tags; ignore them
|
|
boardList: '#boardNavDesktop > .boardList'
|
|
styleSheet: 'link[title=switch]'
|
|
|
|
xpath:
|
|
thread: 'div[contains(concat(" ",@class," ")," thread ")]'
|
|
postContainer: 'div[contains(@class,"postContainer")]'
|
|
|
|
regexp:
|
|
quotelink:
|
|
///
|
|
^https?://boards\.4chan(?:nel)?\.org/+
|
|
([^/]+) # boardID
|
|
/+thread/+
|
|
(\d+) # threadID
|
|
(?:[/?][^#]*)?
|
|
(?:#p
|
|
(\d+) # postID
|
|
)?
|
|
$
|
|
///
|
|
|
|
bgColoredEl: ->
|
|
$.el 'div', className: 'reply'
|
|
|
|
isThisPageLegit: ->
|
|
# not 404 error page or similar.
|
|
location.hostname in ['boards.4chan.org', 'boards.4channel.org'] and
|
|
d.doctype and
|
|
!$('link[href*="favicon-status.ico"]', d.head) and
|
|
d.title not in ['4chan - Temporarily Offline', '4chan - Error', '504 Gateway Time-out', 'MathJax Equation Source']
|
|
|
|
is404: ->
|
|
# XXX Sometimes threads don't 404 but are left over as stubs containing one garbage reply post.
|
|
d.title in ['4chan - Temporarily Offline', '4chan - 404 Not Found'] or (g.VIEW is 'thread' and $('.board') and not $('.opContainer'))
|
|
|
|
isIncomplete: ->
|
|
return g.VIEW in ['index', 'thread'] and not $('.board + *')
|
|
|
|
isAuxiliaryPage: ->
|
|
location.hostname not in ['boards.4chan.org', 'boards.4channel.org']
|
|
|
|
scriptData: ->
|
|
for script in $$ 'script:not([src])', d.head
|
|
return script.textContent if /\bcooldowns *=/.test script.textContent
|
|
''
|
|
|
|
parseThreadMetadata: (thread) ->
|
|
scriptData = @scriptData()
|
|
thread.postLimit = /\bbumplimit *= *1\b/.test scriptData
|
|
thread.fileLimit = /\bimagelimit *= *1\b/.test scriptData
|
|
thread.ipCount = if (m = scriptData.match /\bunique_ips *= *(\d+)\b/) then +m[1]
|
|
|
|
if g.BOARD.ID is 'f' and thread.OP.file
|
|
{file} = thread.OP
|
|
$.ajax "#{location.protocol}//a.4cdn.org/f/thread/#{thread}.json",
|
|
timeout: $.MINUTE
|
|
onloadend: ->
|
|
if @response
|
|
file.text.dataset.md5 = file.MD5 = @response.posts[0].md5
|
|
|
|
parseNodes: (post, nodes) ->
|
|
# Add CSS classes to sticky/closed icons on /f/ to match other boards.
|
|
if post.boardID is 'f'
|
|
for type in ['Sticky', 'Closed'] when (icon = $ "img[alt=#{type}]", nodes.info)
|
|
$.addClass icon, "#{type.toLowerCase()}Icon", 'retina'
|
|
|
|
parseFile: (post, file) ->
|
|
{text, link, thumb} = file
|
|
return false if not (info = link.nextSibling?.textContent.match /\(([\d.]+ [KMG]?B).*\)/)
|
|
$.extend file,
|
|
name: text.title or link.title or link.textContent
|
|
size: info[1]
|
|
dimensions: info[0].match(/\d+x\d+/)?[0]
|
|
tag: info[0].match(/,[^,]*, ([a-z]+)\)/i)?[1]
|
|
MD5: text.dataset.md5
|
|
if thumb
|
|
$.extend file,
|
|
thumbURL: thumb.src
|
|
MD5: thumb.dataset.md5
|
|
isSpoiler: $.hasClass thumb.parentNode, 'imgspoiler'
|
|
if file.isSpoiler
|
|
file.thumbURL = if (m = link.href.match /\d+(?=\.\w+$)/) then "#{location.protocol}//#{ImageHost.thumbHost()}/#{post.board}/#{m[0]}s.jpg"
|
|
true
|
|
|
|
cleanComment: (bq) ->
|
|
if (abbr = $ '.abbr', bq) # 'Comment too long' or 'EXIF data available'
|
|
for node in $$ '.abbr + br, .exif', bq
|
|
$.rm node
|
|
for i in [0...2]
|
|
$.rm br if (br = abbr.previousSibling) and br.nodeName is 'BR'
|
|
$.rm abbr
|
|
|
|
cleanCommentDisplay: (bq) ->
|
|
$.rm b if (b = $ 'b', bq) and /^Rolled /.test(b.textContent)
|
|
$.rm $('.fortune', bq)
|
|
|
|
insertTags: (bq) ->
|
|
for node in $$ 's, .removed-spoiler', bq
|
|
$.replace node, [$.tn('[spoiler]'), node.childNodes..., $.tn '[/spoiler]']
|
|
for node in $$ '.prettyprint', bq
|
|
$.replace node, [$.tn('[code]'), node.childNodes..., $.tn '[/code]']
|
|
return
|