continue quest to merge ccd0
This commit is contained in:
parent
6f84ae9abe
commit
7652c1e49b
@ -29,7 +29,6 @@ module.exports = (grunt) ->
|
|||||||
return '' unless grunt.config('pkg').tests_enabled
|
return '' unless grunt.config('pkg').tests_enabled
|
||||||
"throw new Error 'Assertion failed: ' + `#{JSON.stringify statement}` unless #{statement}"
|
"throw new Error 'Assertion failed: ' + `#{JSON.stringify statement}` unless #{statement}"
|
||||||
|
|
||||||
|
|
||||||
# Project configuration.
|
# Project configuration.
|
||||||
grunt.initConfig
|
grunt.initConfig
|
||||||
pkg: grunt.file.readJSON 'package.json'
|
pkg: grunt.file.readJSON 'package.json'
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -15,15 +15,15 @@ PostHiding =
|
|||||||
cb: @node
|
cb: @node
|
||||||
|
|
||||||
node: ->
|
node: ->
|
||||||
return if !@isReply and g.VIEW isnt 'index' or @isClone
|
return if !@isReply or @isClone or @isFetchedQuote
|
||||||
|
|
||||||
if data = PostHiding.db.get {boardID: @board.ID, threadID: @thread.ID, postID: @ID}
|
if data = PostHiding.db.get {boardID: @board.ID, threadID: @thread.ID, postID: @ID}
|
||||||
if data.thisPost is false
|
if data.thisPost
|
||||||
|
@hide 'Manually hidden', data.makeStub, data.hideRecursively
|
||||||
|
else
|
||||||
label = "Recursively hidden for quoting No.#{@}"
|
label = "Recursively hidden for quoting No.#{@}"
|
||||||
Recursive.apply 'hide', @, label, data.makeStub, true
|
Recursive.apply 'hide', @, label, data.makeStub, true
|
||||||
Recursive.add 'hide', @, label, data.makeStub, true
|
Recursive.add 'hide', @, label, data.makeStub, true
|
||||||
else
|
|
||||||
@hide 'Manually hidden', data.makeStub, data.hideRecursively
|
|
||||||
|
|
||||||
return unless Conf['Post Hiding']
|
return unless Conf['Post Hiding']
|
||||||
if @isReply
|
if @isReply
|
||||||
@ -83,12 +83,9 @@ PostHiding =
|
|||||||
@cb = -> PostHiding.menu.hide post
|
@cb = -> PostHiding.menu.hide post
|
||||||
$.on @el, 'click', @cb
|
$.on @el, 'click', @cb
|
||||||
true
|
true
|
||||||
thisPost =
|
thisPost = el: UI.checkbox 'thisPost', ' This post', true
|
||||||
el: $.el 'label', innerHTML: '<input type=checkbox name=thisPost checked> This post'
|
replies = el: UI.checkbox 'replies', ' Hide replies', Conf['Recursive Hiding']
|
||||||
replies =
|
makeStub = el: UI.checkbox 'makeStub', ' Make stub', Conf['Stubs']
|
||||||
el: $.el 'label', innerHTML: "<input type=checkbox name=replies checked=#{Conf['Recursive Hiding']}> Hide replies"
|
|
||||||
makeStub =
|
|
||||||
el: $.el 'label', innerHTML: "<input type=checkbox name=makeStub checked=#{Conf['Stubs']}> Make stub"
|
|
||||||
|
|
||||||
Menu.menu.addEntry
|
Menu.menu.addEntry
|
||||||
el: $.el 'div',
|
el: $.el 'div',
|
||||||
@ -107,12 +104,12 @@ PostHiding =
|
|||||||
$.on @el, 'click', @cb
|
$.on @el, 'click', @cb
|
||||||
true
|
true
|
||||||
thisPost =
|
thisPost =
|
||||||
el: $.el 'label', innerHTML: '<input type=checkbox name=thisPost> This post'
|
el: UI.checkbox 'thisPost', ' This post', false
|
||||||
open: (post) ->
|
open: (post) ->
|
||||||
@el.firstChild.checked = post.isHidden
|
@el.firstChild.checked = post.isHidden
|
||||||
true
|
true
|
||||||
replies =
|
replies =
|
||||||
el: $.el 'label', innerHTML: '<input type=checkbox name=replies> Unhide replies'
|
el: UI.checkbox 'replies', ' Show replies', false
|
||||||
open: (post) ->
|
open: (post) ->
|
||||||
data = PostHiding.db.get {boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID}
|
data = PostHiding.db.get {boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID}
|
||||||
@el.firstChild.checked = if 'hideRecursively' of data then data.hideRecursively else Conf['Recursive Hiding']
|
@el.firstChild.checked = if 'hideRecursively' of data then data.hideRecursively else Conf['Recursive Hiding']
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
Recursive =
|
Recursive =
|
||||||
recursives: {}
|
recursives: {}
|
||||||
init: ->
|
init: ->
|
||||||
|
return unless g.VIEW in ['index', 'thread']
|
||||||
Post.callbacks.push
|
Post.callbacks.push
|
||||||
name: 'Recursive'
|
name: 'Recursive'
|
||||||
cb: @node
|
cb: @node
|
||||||
|
|
||||||
node: ->
|
node: ->
|
||||||
return if @isClone
|
return if @isClone or @isFetchedQuote
|
||||||
for quote in @quotes when obj = Recursive.recursives[quote]
|
for quote in @quotes when obj = Recursive.recursives[quote]
|
||||||
for recursive, i in obj.recursives
|
for recursive, i in obj.recursives
|
||||||
@[recursive] obj.args[i]...
|
@[recursive] obj.args[i]...
|
||||||
|
|||||||
@ -2,48 +2,63 @@ Build =
|
|||||||
staticPath: '//s.4cdn.org/image/'
|
staticPath: '//s.4cdn.org/image/'
|
||||||
gifIcon: if window.devicePixelRatio >= 2 then '@2x.gif' else '.gif'
|
gifIcon: if window.devicePixelRatio >= 2 then '@2x.gif' else '.gif'
|
||||||
spoilerRange: {}
|
spoilerRange: {}
|
||||||
shortFilename: (filename, isReply) ->
|
unescape: (text) ->
|
||||||
# FILENAME SHORTENING SCIENCE:
|
return text unless text?
|
||||||
# OPs have a +10 characters threshold.
|
text.replace(/<[^>]*>/g, '').replace /&(amp|#039|quot|lt|gt);/g, (c) ->
|
||||||
# The file extension is not taken into account.
|
{'&': '&', ''': "'", '"': '"', '<': '<', '>': '>'}[c]
|
||||||
threshold = if isReply then 30 else 40
|
shortFilename: (filename) ->
|
||||||
|
threshold = 30
|
||||||
ext = filename.match(/\.[^.]+$/)[0]
|
ext = filename.match(/\.[^.]+$/)[0]
|
||||||
if filename.length - ext.length > threshold
|
if filename.length - ext.length > threshold
|
||||||
"#{filename[...threshold - 5]}(...)#{ext}"
|
"#{filename[...threshold - 5]}(...)#{ext}"
|
||||||
else
|
else
|
||||||
filename
|
filename
|
||||||
thumbRotate: do ->
|
thumbRotate: do ->
|
||||||
n = 0
|
t = 0
|
||||||
-> n = (n + 1) % 2
|
-> t = (if t then 0 else 1)
|
||||||
|
sameThread: (boardID, threadID) ->
|
||||||
|
g.VIEW is 'thread' and g.BOARD.ID is boardID and g.THREADID is +threadID
|
||||||
|
postURL: (boardID, threadID, postID) ->
|
||||||
|
if Build.sameThread boardID, threadID
|
||||||
|
"#p#{postID}"
|
||||||
|
else
|
||||||
|
Build.path boardID, threadID, postID
|
||||||
path: (boardID, threadID, postID, fragment) ->
|
path: (boardID, threadID, postID, fragment) ->
|
||||||
path = "/#{boardID}/thread/#{threadID}"
|
path = "/#{boardID}/thread/#{threadID}"
|
||||||
path += "/#{g.SLUG}" if g.SLUG? and threadID is g.THREADID
|
if g.SLUG? and threadID is g.THREADID
|
||||||
path += "##{fragment or 'p'}#{postID}" if postID
|
path += "/#{g.SLUG}"
|
||||||
|
if postID
|
||||||
|
path += "##{fragment or 'p'}#{postID}"
|
||||||
path
|
path
|
||||||
postFromObject: (data, boardID) ->
|
postFromObject: (data, boardID) ->
|
||||||
o =
|
o =
|
||||||
# id
|
# id
|
||||||
postID: data.no
|
postID: data.no
|
||||||
threadID: data.resto or data.no
|
threadID: data.resto or data.no
|
||||||
boardID: boardID
|
boardID: boardID
|
||||||
# info
|
# info
|
||||||
name: data.name
|
name: Build.unescape data.name
|
||||||
capcode: data.capcode
|
capcode: data.capcode
|
||||||
tripcode: data.trip
|
tripcode: data.trip
|
||||||
uniqueID: data.id
|
uniqueID: data.id
|
||||||
email: if data.email then encodeURI data.email.replace /"/g, '"' else ''
|
email: Build.unescape data.email
|
||||||
subject: data.sub
|
subject: Build.unescape data.sub
|
||||||
flagCode: data.country
|
flagCode: data.country
|
||||||
flagName: data.country_name
|
flagName: Build.unescape data.country_name
|
||||||
date: data.now
|
date: data.now
|
||||||
dateUTC: data.time
|
dateUTC: data.time
|
||||||
comment: data.com
|
comment: {innerHTML: data.com or ''}
|
||||||
# thread status
|
# thread status
|
||||||
isSticky: !!data.sticky
|
isSticky: !!data.sticky
|
||||||
isClosed: !!data.closed
|
isClosed: !!data.closed
|
||||||
|
isArchived: !!data.archived
|
||||||
# file
|
# file
|
||||||
if data.ext or data.filedeleted
|
if data.filedeleted
|
||||||
o.file =
|
o.file =
|
||||||
|
isDeleted: true
|
||||||
|
else if data.ext
|
||||||
|
o.file =
|
||||||
|
name: (Build.unescape data.filename) + data.ext
|
||||||
name: data.filename + data.ext
|
name: data.filename + data.ext
|
||||||
timestamp: "#{data.tim}#{data.ext}"
|
timestamp: "#{data.tim}#{data.ext}"
|
||||||
url: if boardID is 'f'
|
url: if boardID is 'f'
|
||||||
@ -58,9 +73,10 @@ Build =
|
|||||||
theight: data.tn_h
|
theight: data.tn_h
|
||||||
twidth: data.tn_w
|
twidth: data.tn_w
|
||||||
isSpoiler: !!data.spoiler
|
isSpoiler: !!data.spoiler
|
||||||
isDeleted: !!data.filedeleted
|
isDeleted: false
|
||||||
|
tag: data.tag
|
||||||
Build.post o
|
Build.post o
|
||||||
post: (o, isArchived) ->
|
post: (o) ->
|
||||||
###
|
###
|
||||||
This function contains code from 4chan-JS (https://github.com/4chan/4chan-JS).
|
This function contains code from 4chan-JS (https://github.com/4chan/4chan-JS).
|
||||||
@license: https://github.com/4chan/4chan-JS/blob/master/LICENSE
|
@license: https://github.com/4chan/4chan-JS/blob/master/LICENSE
|
||||||
@ -68,174 +84,186 @@ Build =
|
|||||||
{
|
{
|
||||||
postID, threadID, boardID
|
postID, threadID, boardID
|
||||||
name, capcode, tripcode, uniqueID, email, subject, flagCode, flagName, date, dateUTC
|
name, capcode, tripcode, uniqueID, email, subject, flagCode, flagName, date, dateUTC
|
||||||
isSticky, isClosed
|
|
||||||
comment
|
comment
|
||||||
file
|
file
|
||||||
} = o
|
} = o
|
||||||
|
name or= ''
|
||||||
|
subject or= ''
|
||||||
isOP = postID is threadID
|
isOP = postID is threadID
|
||||||
{staticPath, gifIcon} = Build
|
{staticPath, gifIcon} = Build
|
||||||
|
|
||||||
tripcode = if tripcode
|
### Name Block ###
|
||||||
" <span class=postertrip>#{tripcode}</span>"
|
|
||||||
else
|
|
||||||
''
|
|
||||||
|
|
||||||
if email
|
|
||||||
emailStart = '<a href="mailto:' + email + '" class="useremail">'
|
|
||||||
emailEnd = '</a>'
|
|
||||||
else
|
|
||||||
emailStart = ''
|
|
||||||
emailEnd = ''
|
|
||||||
|
|
||||||
switch capcode
|
switch capcode
|
||||||
when 'admin', 'admin_highlight'
|
when 'admin', 'admin_highlight'
|
||||||
capcodeClass = " capcodeAdmin"
|
capcodeClass = ' capcodeAdmin'
|
||||||
capcodeStart = " <strong class='capcode hand id_admin'" +
|
capcodeStart = <%= html(' <strong class="capcode hand id_admin" title="Highlight posts by the Administrator">## Admin</strong>') %>
|
||||||
"title='Highlight posts by the Administrator'>## Admin</strong>"
|
capcodeIcon = <%= html(' <img src="${staticPath}adminicon${gifIcon}" alt="Admin Icon" title="This user is the 4chan Administrator." class="identityIcon retina">') %>
|
||||||
capcodeIcon = " <img src='#{staticPath}adminicon#{gifIcon}' " +
|
|
||||||
"title='This user is the 4chan Administrator.' class=identityIcon>"
|
|
||||||
when 'mod'
|
when 'mod'
|
||||||
capcodeClass = " capcodeMod"
|
capcodeClass = ' capcodeMod'
|
||||||
capcodeStart = " <strong class='capcode hand id_mod' " +
|
capcodeStart = <%= html(' <strong class="capcode hand id_mod" title="Highlight posts by Moderators">## Mod</strong>') %>
|
||||||
"title='Highlight posts by Moderators'>## Mod</strong>"
|
capcodeIcon = <%= html(' <img src="${staticPath}modicon${gifIcon}" alt="Mod Icon" title="This user is a 4chan Moderator." class="identityIcon retina">') %>
|
||||||
capcodeIcon = " <img src='#{staticPath}modicon#{gifIcon}' " +
|
capcodeClass = ' capcodeDeveloper'
|
||||||
"title='This user is a 4chan Moderator.' class=identityIcon>"
|
capcodeStart = <%= html(' <strong class="capcode hand id_developer" title="Highlight posts by Developers">## Developer</strong>') %>
|
||||||
when 'developer'
|
capcodeIcon = <%= html(' <img src="${staticPath}developericon${gifIcon}" alt="Developer Icon" title="This user is a 4chan Developer." class="identityIcon retina">') %>
|
||||||
capcodeClass = " capcodeDeveloper"
|
|
||||||
capcodeStart = " <strong class='capcode hand id_developer' " +
|
|
||||||
"title='Highlight posts by Developers'>## Developer</strong>"
|
|
||||||
capcodeIcon = " <img src='#{staticPath}developericon#{gifIcon}' " +
|
|
||||||
"title='This user is a 4chan Developer.' class=identityIcon>"
|
|
||||||
else
|
else
|
||||||
capcodeClass = ''
|
capcodeClass = ''
|
||||||
capcodeStart = ''
|
capcodeStart = <%= html('') %>
|
||||||
capcodeIcon = ''
|
capcodeIcon = if isOP and boardID is 'f' then <%= html('') %> else <%= html(' ') %>
|
||||||
|
|
||||||
userID =
|
nameClass = if capcode then ' capcode' else ''
|
||||||
if !capcode and uniqueID
|
|
||||||
" <span class='posteruid id_#{uniqueID}'>(ID: " +
|
tripcodeField = if tripcode
|
||||||
"<span class=hand title='Highlight posts by this ID'>#{uniqueID}</span>)</span> "
|
<%= html(' <span class="postertrip">${tripcode}</span>') %>
|
||||||
else
|
else
|
||||||
''
|
<%= html('') %>
|
||||||
|
|
||||||
|
emailField = <%= html('<span class="name${nameClass}">${name}</span>&{tripcodeField}&{capcodeStart}') %>
|
||||||
|
if email
|
||||||
|
emailProcessed = encodeURIComponent(email).replace /%40/g, '@'
|
||||||
|
emailField = <%= html('<a href="mailto:${emailProcessed}" class="useremail">&{emailField}</a>') %>
|
||||||
|
|
||||||
|
userID = if !capcode and uniqueID
|
||||||
|
<%= html(' <span class="posteruid id_${uniqueID}">(ID: <span class="hand" title="Highlight posts by this ID">${uniqueID}</span>)</span>') %>
|
||||||
|
else
|
||||||
|
<%= html('') %>
|
||||||
|
|
||||||
flag = unless flagCode
|
flag = unless flagCode
|
||||||
''
|
<%= html('') %>
|
||||||
else if boardID is 'pol'
|
else if false
|
||||||
" <img src='#{staticPath}country/troll/#{flagCode.toLowerCase()}.gif' title='#{flagName}' class=countryFlag>"
|
<%= html(' <img src="${staticPath}country/troll/${flagCode.toLowerCase()}.gif" alt="${flagCode}" title="${flagName}" class="countryFlag">') %>
|
||||||
else
|
else
|
||||||
" <span title='#{flagName}' class='flag flag-#{flagCode.toLowerCase()}'></span>"
|
<%= html(' <span title="${flagName}" class="flag flag-${flagCode.toLowerCase()}"></span>') %>
|
||||||
|
|
||||||
if file?.isDeleted
|
nameBlock = <%= html(
|
||||||
fileHTML = if isOP
|
'<span class="nameBlock${capcodeClass}">' +
|
||||||
"<div class=file><span class=fileThumb>" +
|
'&{emailField}&{capcodeIcon}&{userID}&{flag}' +
|
||||||
"<img src='#{staticPath}filedeleted#{gifIcon}' class=fileDeleted>" +
|
'</span> '
|
||||||
"</span></div>"
|
) %>
|
||||||
else
|
|
||||||
"<div class=file><span class=fileThumb>" +
|
### Post Info ###
|
||||||
"<img src='#{staticPath}filedeleted-res#{gifIcon}' class=fileDeletedRes>" +
|
|
||||||
"</span></div>"
|
subjectField = if isOP or boardID is 'f'
|
||||||
|
<%= html('<span class="subject">${subject}</span> ') %>
|
||||||
|
else
|
||||||
|
<%= html('') %>
|
||||||
|
|
||||||
|
desktop2 = if isOP and boardID is 'f' then '' else ' desktop'
|
||||||
|
|
||||||
|
postLink = Build.postURL boardID, threadID, postID
|
||||||
|
quoteLink = if Build.sameThread boardID, threadID
|
||||||
|
"javascript:quote('#{+postID}');"
|
||||||
|
else
|
||||||
|
"/#{boardID}/thread/#{threadID}#q#{postID}"
|
||||||
|
|
||||||
|
icons = for type in ['Sticky', 'Closed', 'Archived'] when o["is#{type}"] and !(type is 'Closed' and o.isArchived)
|
||||||
|
typeLC = type.toLowerCase()
|
||||||
|
<%= html(' <img src="${staticPath}${typeLC}${gifIcon}" alt="${type}" title="${type}" class="${typeLC}Icon retina">') %>
|
||||||
|
|
||||||
|
replyLink = if isOP and g.VIEW is 'index'
|
||||||
|
<%= html(' <span>[<a href="/${boardID}/thread/${threadID}" class="replylink">Reply</a>]</span>') %>
|
||||||
|
else
|
||||||
|
<%= html('') %>
|
||||||
|
|
||||||
|
postInfo = <%= html(
|
||||||
|
'<div class="postInfo desktop" id="pi${postID}">' +
|
||||||
|
'<input type="checkbox" name="${postID}" value="delete"> ' +
|
||||||
|
'&{subjectField}' +
|
||||||
|
'&{nameBlock}' +
|
||||||
|
'<span class="dateTime" data-utc="${dateUTC}">${date}</span> ' +
|
||||||
|
'<span class="postNum${desktop2}">' +
|
||||||
|
'<a href="${postLink}" title="Link to this post">No.</a>' +
|
||||||
|
'<a href="${quoteLink}" title="Reply to this post">${postID}</a>' +
|
||||||
|
'@{icons}&{replyLink}' +
|
||||||
|
'</span>' +
|
||||||
|
'</div>'
|
||||||
|
) %>
|
||||||
|
|
||||||
|
### File Info ###
|
||||||
|
|
||||||
|
fileCont = if file?.isDeleted
|
||||||
|
<%= html(
|
||||||
|
'<span class="fileThumb">' +
|
||||||
|
'<img src="${staticPath}filedeleted-res${gifIcon}" alt="File deleted." class="fileDeletedRes retina">' +
|
||||||
|
'</span>'
|
||||||
|
) %>
|
||||||
|
else if file and boardID is 'f'
|
||||||
|
<%= html(
|
||||||
|
'<div class="fileInfo"><span class="fileText" id="fT${postID}">' +
|
||||||
|
'File: <a data-width="${file.width}" data-height="${file.height}" href="${file.url}" target="_blank">${file.name}</a>' +
|
||||||
|
'-(${$.bytesToString(file.size)}, ${file.width}x${file.height}, ${file.tag})' +
|
||||||
|
'</span></div>'
|
||||||
|
) %>
|
||||||
else if file
|
else if file
|
||||||
fileSize = $.bytesToString file.size
|
|
||||||
fileThumb = file.turl
|
|
||||||
if file.isSpoiler
|
if file.isSpoiler
|
||||||
fileSize = "Spoiler Image, #{fileSize}"
|
shortFilename = 'Spoiler Image'
|
||||||
unless isArchived
|
if spoilerRange = Build.spoilerRange[boardID]
|
||||||
fileThumb = "#{staticPath}spoiler"
|
# Randomize the spoiler image.
|
||||||
if spoilerRange = Build.spoilerRange[boardID]
|
fileThumb = "//s.4cdn.org/image/spoiler-#{boardID}#{Math.floor 1 + spoilerRange * Math.random()}.png"
|
||||||
# Randomize the spoiler image.
|
else
|
||||||
fileThumb += "-#{boardID}" + Math.floor 1 + spoilerRange * Math.random()
|
fileThumb = '//s.4cdn.org/image/spoiler.png'
|
||||||
fileThumb += '.png'
|
file.twidth = file.theight = 100
|
||||||
file.twidth = file.theight = 100
|
|
||||||
|
|
||||||
imgSrc = if boardID is 'f'
|
|
||||||
''
|
|
||||||
else
|
else
|
||||||
"<a class='fileThumb#{if file.isSpoiler then ' imgspoiler' else ''}' href=\"#{file.url}\" target=_blank>" +
|
shortFilename = Build.shortFilename file.name, !isOP
|
||||||
"<img src='#{fileThumb}' alt='#{fileSize}' data-md5=#{file.MD5} style='height: #{file.theight}px; width: #{file.twidth}px;'>" +
|
fileThumb = file.turl
|
||||||
"</a>"
|
|
||||||
|
|
||||||
# html -> text, translate WebKit's %22s into "s
|
fileSize = $.bytesToString file.size
|
||||||
a = $.el 'a', innerHTML: file.name
|
fileDims = if file.url[-4..] is '.pdf' then 'PDF' else "#{file.width}x#{file.height}"
|
||||||
filename = a.textContent.replace /%22/g, '"'
|
|
||||||
# shorten filename, get html
|
|
||||||
a.textContent = Build.shortFilename filename
|
|
||||||
shortFilename = a.innerHTML
|
|
||||||
# get html
|
|
||||||
a.textContent = filename
|
|
||||||
filename = a.innerHTML.replace /'/g, '''
|
|
||||||
|
|
||||||
fileDims = if file.name[-3..] is 'pdf' then 'PDF' else "#{file.width}x#{file.height}"
|
fileLink = if file.isSpoiler or file.name is shortFilename
|
||||||
fileInfo = "<div class=fileText #{if file.isSpoiler then "title='#{filename}'" else ''}>File: " +
|
<%= html('<a href="${file.url}" target="_blank">${shortFilename}</a>') %>
|
||||||
"<a href=\"#{file.url}\" #{if filename isnt shortFilename and !file.isSpoiler then " title='#{filename}'" else ''} target=_blank>#{if file.isSpoiler then 'Spoiler Image' else shortFilename}</a>" +
|
else
|
||||||
" (#{fileSize}, #{fileDims})</div>"
|
<%= html('<a title="${file.name}" href="${file.url}" target="_blank">${shortFilename}</a>') %>
|
||||||
|
|
||||||
fileHTML = "<div class=file>#{fileInfo}#{imgSrc}</div>"
|
fileText = if file.isSpoiler
|
||||||
|
<%= html('<div class="fileText" id="fT${postID}" title="${file.name}">File: &{fileLink} (${fileSize}, ${fileDims})</div>') %>
|
||||||
|
else
|
||||||
|
<%= html('<div class="fileText" id="fT${postID}">File: &{fileLink} (${fileSize}, ${fileDims})</div>') %>
|
||||||
|
|
||||||
|
<%= html(
|
||||||
|
'&{fileText}' +
|
||||||
|
'<a class="fileThumb${file.isSpoiler ? " imgspoiler" : ""}" href="${file.url}" target="_blank">' +
|
||||||
|
'<img src="${fileThumb}" alt="${fileSize}" data-md5="${file.MD5}" style="height: ${file.theight}px; width: ${file.twidth}px;">' +
|
||||||
|
'</a>'
|
||||||
|
) %>
|
||||||
|
|
||||||
|
fileBlock = if file
|
||||||
|
<%= html('<div class="file" id="f${postID}">&{fileCont}</div>') %>
|
||||||
else
|
else
|
||||||
fileHTML = ''
|
<%= html('') %>
|
||||||
|
|
||||||
sticky = if isSticky
|
### Whole Post ###
|
||||||
" <img src=#{staticPath}sticky#{gifIcon} title=Sticky class=stickyIcon>"
|
|
||||||
else
|
|
||||||
''
|
|
||||||
closed = if isClosed
|
|
||||||
" <img src=#{staticPath}closed#{gifIcon} title=Closed class=closedIcon>"
|
|
||||||
else
|
|
||||||
''
|
|
||||||
|
|
||||||
if isOP and g.VIEW is 'index'
|
highlightPost = if capcode is 'admin_highlight' then ' highlightPost' else ''
|
||||||
pageNum = Index.liveThreadData.keys.indexOf("#{postID}") // Index.threadsNumPerPage + 1
|
|
||||||
pageIcon = " <span class=page-num title='This thread is on page #{pageNum} in the original index.'>Page #{pageNum}</span>"
|
message = <%= html('<blockquote class="postMessage" id="m${postID}">&{comment}</blockquote>') %>
|
||||||
replyLink = " <span>[<a href='#{Build.path boardID, threadID}' class=replylink>Reply</a>]</span>"
|
|
||||||
|
wholePost = if isOP
|
||||||
|
<%= html(
|
||||||
|
'<div id="p${postID}" class="post op${highlightPost}">' +
|
||||||
|
'&{fileBlock}&{postInfo}&{message}' +
|
||||||
|
'</div>'
|
||||||
|
) %>
|
||||||
else
|
else
|
||||||
pageIcon = ''
|
<%= html(
|
||||||
replyLink = ''
|
'<div class="sideArrows" id="sa${postID}">>></div>' +
|
||||||
|
'<div id="p${postID}" class="post reply${highlightPost}">' +
|
||||||
|
'&{postInfo}&{fileBlock}&{message}' +
|
||||||
|
'</div>'
|
||||||
|
) %>
|
||||||
|
|
||||||
container = $.el 'div',
|
container = $.el 'div',
|
||||||
id: "pc#{postID}"
|
|
||||||
className: "postContainer #{if isOP then 'op' else 'reply'}Container"
|
className: "postContainer #{if isOP then 'op' else 'reply'}Container"
|
||||||
innerHTML: \
|
id: "pc#{postID}"
|
||||||
(if isOP then '' else "<div class=sideArrows>>></div>") +
|
$.extend container, wholePost
|
||||||
"<div id=p#{postID} class='post #{if isOP then 'op' else 'reply'}#{
|
|
||||||
if capcode is 'admin_highlight'
|
|
||||||
' highlightPost'
|
|
||||||
else
|
|
||||||
''
|
|
||||||
}'>" +
|
|
||||||
|
|
||||||
(if isOP then fileHTML else '') +
|
# Fix pathnames
|
||||||
|
|
||||||
"<div class=postInfo>" +
|
|
||||||
"<input type=checkbox name=#{postID} value=delete> " +
|
|
||||||
"<span class=subject>#{subject or ''}</span> " +
|
|
||||||
"<span class='nameBlock#{capcodeClass}'>" +
|
|
||||||
emailStart +
|
|
||||||
"<span class=name>#{name or ''}</span>" + tripcode +
|
|
||||||
capcodeStart + emailEnd + capcodeIcon + userID + flag +
|
|
||||||
' </span> ' +
|
|
||||||
"<span class=dateTime data-utc=#{dateUTC}>#{date}</span> " +
|
|
||||||
"<span class='postNum'>" +
|
|
||||||
"<a href=#{Build.path boardID, threadID, postID} title='Link to this post'>No.</a>" +
|
|
||||||
"<a href='#{
|
|
||||||
if g.VIEW is 'thread' and g.THREADID is threadID
|
|
||||||
"javascript:quote(#{postID})"
|
|
||||||
else
|
|
||||||
Build.path boardID, threadID, postID, 'q'
|
|
||||||
}' title='Reply to this post'>#{postID}</a>" +
|
|
||||||
pageIcon + sticky + closed + replyLink +
|
|
||||||
'</span>' +
|
|
||||||
'</div>' +
|
|
||||||
|
|
||||||
(if isOP then '' else fileHTML) +
|
|
||||||
|
|
||||||
"<blockquote class=postMessage>#{comment or ''}</blockquote> " +
|
|
||||||
|
|
||||||
'</div>'
|
|
||||||
|
|
||||||
# Fix quote pathnames in index or cross-{board,thread} posts
|
|
||||||
for quote in $$ '.quotelink', container
|
for quote in $$ '.quotelink', container
|
||||||
href = quote.getAttribute 'href'
|
href = quote.getAttribute 'href'
|
||||||
continue unless href[0] is '#'
|
if (href[0] is '#') and !(Build.sameThread boardID, threadID)
|
||||||
quote.href = Build.path boardID, threadID, href[2..]
|
quote.href = (Build.path boardID, threadID) + href
|
||||||
|
else if (match = href.match /^\/([^\/]+)\/thread\/(\d+)/) and (Build.sameThread match[1], match[2])
|
||||||
|
quote.href = href.match(/(#[^#]*)?$/)[0] or '#'
|
||||||
|
|
||||||
container
|
container
|
||||||
|
|
||||||
@ -284,14 +312,14 @@ Build =
|
|||||||
pageCount = Index.liveThreadData.keys.indexOf("#{thread.ID}") // Index.threadsNumPerPage + 1
|
pageCount = Index.liveThreadData.keys.indexOf("#{thread.ID}") // Index.threadsNumPerPage + 1
|
||||||
|
|
||||||
subject = if thread.OP.info.subject
|
subject = if thread.OP.info.subject
|
||||||
"<div class='subject'>#{thread.OP.nodes.subject.innerHTML}</div>"
|
<%= html("<div class='subject'>${thread.OP.nodes.subject.innerHTML}</div>") %>
|
||||||
else
|
else
|
||||||
''
|
''
|
||||||
comment = thread.OP.nodes.comment.innerHTML.replace /(<br>\s*){2,}/g, '<br>'
|
comment = thread.OP.nodes.comment.innerHTML.replace /(<br>\s*){2,}/g, '<br>'
|
||||||
|
|
||||||
root = $.el 'div',
|
root = $.el 'div',
|
||||||
className: 'catalog-thread'
|
className: 'catalog-thread'
|
||||||
innerHTML: <%= importHTML('Features/Thread-catalog-view') %>
|
<%= importHTML('Features/Thread-catalog-view') %>
|
||||||
|
|
||||||
root.dataset.fullID = thread.fullID
|
root.dataset.fullID = thread.fullID
|
||||||
$.addClass root, 'pinned' if thread.isPinned
|
$.addClass root, 'pinned' if thread.isPinned
|
||||||
|
|||||||
@ -3,7 +3,7 @@ Get =
|
|||||||
{OP} = thread
|
{OP} = thread
|
||||||
excerpt = OP.info.subject?.trim() or
|
excerpt = OP.info.subject?.trim() or
|
||||||
OP.info.comment.replace(/\n+/g, ' // ') or
|
OP.info.comment.replace(/\n+/g, ' // ') or
|
||||||
OP.getNameBlock()
|
OP.info.nameBlock
|
||||||
if excerpt.length > 70
|
if excerpt.length > 70
|
||||||
excerpt = "#{excerpt[...67]}..."
|
excerpt = "#{excerpt[...67]}..."
|
||||||
"/#{thread.board}/ - #{excerpt}"
|
"/#{thread.board}/ - #{excerpt}"
|
||||||
|
|||||||
@ -85,11 +85,11 @@ Index =
|
|||||||
@pagelist = $.el 'div',
|
@pagelist = $.el 'div',
|
||||||
className: 'pagelist'
|
className: 'pagelist'
|
||||||
hidden: true
|
hidden: true
|
||||||
innerHTML: <%= importHTML('Features/Index-pagelist') %>
|
<%= importHTML('Features/Index-pagelist') %>
|
||||||
|
|
||||||
@navLinks = $.el 'div',
|
@navLinks = $.el 'div',
|
||||||
className: 'navLinks'
|
className: 'navLinks'
|
||||||
innerHTML: <%= importHTML('Features/Index-navlinks') %>
|
<%= importHTML('Features/Index-navlinks') %>
|
||||||
@timeEl = $ 'time#index-last-refresh', @navLinks
|
@timeEl = $ 'time#index-last-refresh', @navLinks
|
||||||
|
|
||||||
@searchInput = $ '#index-search', @navLinks
|
@searchInput = $ '#index-search', @navLinks
|
||||||
|
|||||||
@ -53,7 +53,7 @@ Settings =
|
|||||||
Settings.dialog = dialog = $.el 'div',
|
Settings.dialog = dialog = $.el 'div',
|
||||||
id: 'appchanx-settings'
|
id: 'appchanx-settings'
|
||||||
class: 'dialog'
|
class: 'dialog'
|
||||||
innerHTML: <%= importHTML('Settings/Settings') %>
|
<%= importHTML('Settings/Settings') %>
|
||||||
|
|
||||||
Settings.overlay = overlay = $.el 'div',
|
Settings.overlay = overlay = $.el 'div',
|
||||||
id: 'overlay'
|
id: 'overlay'
|
||||||
@ -189,7 +189,7 @@ Settings =
|
|||||||
$.clear -> window.location.reload() if confirm 'Reset successful. Reload now?'
|
$.clear -> window.location.reload() if confirm 'Reset successful. Reload now?'
|
||||||
|
|
||||||
filter: (section) ->
|
filter: (section) ->
|
||||||
section.innerHTML = <%= importHTML('Settings/Filter-select') %>
|
$.extend section, <%= importHTML('Settings/Filter-select') %>
|
||||||
select = $ 'select', section
|
select = $ 'select', section
|
||||||
$.on select, 'change', Settings.selectFilter
|
$.on select, 'change', Settings.selectFilter
|
||||||
Settings.selectFilter.call select
|
Settings.selectFilter.call select
|
||||||
@ -207,10 +207,10 @@ Settings =
|
|||||||
$.on ta, 'change', $.cb.value
|
$.on ta, 'change', $.cb.value
|
||||||
$.add div, ta
|
$.add div, ta
|
||||||
return
|
return
|
||||||
div.innerHTML = <%= importHTML('Settings/Filter-guide') %>
|
$.extend div, <%= importHTML('Settings/Filter-guide') %>
|
||||||
|
|
||||||
sauce: (section) ->
|
sauce: (section) ->
|
||||||
section.innerHTML = <%= importHTML('Settings/Sauce') %>
|
$.extend section, <%= importHTML('Settings/Sauce') %>
|
||||||
ta = $ 'textarea', section
|
ta = $ 'textarea', section
|
||||||
$.get 'sauces', Conf['sauces'], (item) ->
|
$.get 'sauces', Conf['sauces'], (item) ->
|
||||||
# XXX remove .replace func after 31-7-2013 (v1 transitioning)
|
# XXX remove .replace func after 31-7-2013 (v1 transitioning)
|
||||||
@ -229,7 +229,7 @@ Settings =
|
|||||||
$.on ta, 'change', $.cb.value
|
$.on ta, 'change', $.cb.value
|
||||||
|
|
||||||
advanced: (section) ->
|
advanced: (section) ->
|
||||||
section.innerHTML = <%= importHTML('Settings/Advanced') %>
|
$.extend section, <%= importHTML('Settings/Advanced') %>
|
||||||
items = {}
|
items = {}
|
||||||
inputs = {}
|
inputs = {}
|
||||||
for name in ['boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'usercss']
|
for name in ['boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'usercss']
|
||||||
@ -388,7 +388,7 @@ Settings =
|
|||||||
CustomCSS.update()
|
CustomCSS.update()
|
||||||
|
|
||||||
keybinds: (section) ->
|
keybinds: (section) ->
|
||||||
section.innerHTML = <%= importHTML('Settings/Keybinds') %>
|
$.extend section, <%= importHTML('Settings/Keybinds') %>
|
||||||
|
|
||||||
tbody = $ 'tbody', section
|
tbody = $ 'tbody', section
|
||||||
items = {}
|
items = {}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ class Post
|
|||||||
root: root
|
root: root
|
||||||
post: post
|
post: post
|
||||||
info: info
|
info: info
|
||||||
|
nameBlock: $ '.nameBlock', info
|
||||||
comment: $ '.postMessage', post
|
comment: $ '.postMessage', post
|
||||||
links: []
|
links: []
|
||||||
quotelinks: []
|
quotelinks: []
|
||||||
@ -25,6 +26,10 @@ class Post
|
|||||||
@thread.isClosed = !!$ '.closedIcon', info
|
@thread.isClosed = !!$ '.closedIcon', info
|
||||||
|
|
||||||
@info = {}
|
@info = {}
|
||||||
|
@info.nameBlock = if Conf['Anonymize']
|
||||||
|
'Anonymous'
|
||||||
|
else
|
||||||
|
@nodes.nameBlock.textContent.trim()
|
||||||
if subject = $ '.subject', info
|
if subject = $ '.subject', info
|
||||||
@nodes.subject = subject
|
@nodes.subject = subject
|
||||||
@info.subject = subject.textContent
|
@info.subject = subject.textContent
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user