HTML templates
This commit is contained in:
parent
36fad05cab
commit
cff287c9c3
@ -1,7 +1,30 @@
|
||||
module.exports = (grunt) ->
|
||||
|
||||
importHTML = (filename) ->
|
||||
"'''#{grunt.file.read("src/General/html/#{filename}.html").replace(/^\s+|\s+$</gm, '').replace(/\n/g, '')}'''"
|
||||
"(innerHTML: #{JSON.stringify grunt.file.read("src/General/html/#{filename}.html").replace(/^\s+|\s+$</gm, '').replace(/\n/g, '')})"
|
||||
|
||||
html = (template) ->
|
||||
parts = template.split /([\$&@]){([^}]*)}/
|
||||
parts2 = []
|
||||
checkText = ''
|
||||
for part, i in parts
|
||||
switch i % 3
|
||||
when 0
|
||||
parts2.push JSON.stringify part unless part is ''
|
||||
checkText += part
|
||||
when 1
|
||||
if /<[^>]*$/.test(checkText) and not (part is '$' and /\=['"][^"'<>]*$/.test checkText)
|
||||
throw new Error "Illegal insertion into HTML template: #{template}"
|
||||
expr = parts[i+1]
|
||||
expr = "(#{expr})" for x in parts[i+1].split ')'
|
||||
parts2.push switch part
|
||||
when '$' then "E#{expr}"
|
||||
when '&' then "#{expr}.innerHTML"
|
||||
when '@' then "#{expr}.map((x) -> x.innerHTML).join('')"
|
||||
unless /^(<\w+( [\w-]+(='[^"'<>]*'|="[^"'<>]*")?)*>|<\/\w+>|[^"'<>]*)*$/.test checkText
|
||||
throw new Error "HTML template is ill-formed: #{template}"
|
||||
output = if parts2.length is 0 then '""' else parts2.join ' + '
|
||||
"(innerHTML: #{output})"
|
||||
|
||||
# Project configuration.
|
||||
grunt.initConfig
|
||||
@ -12,6 +35,7 @@ module.exports = (grunt) ->
|
||||
get: ->
|
||||
pkg = grunt.config 'pkg'
|
||||
pkg.importHTML = importHTML
|
||||
pkg.html = html
|
||||
pkg.tests_enabled or= false
|
||||
pkg
|
||||
enumerable: true
|
||||
|
||||
@ -137,8 +137,8 @@ ThreadHiding =
|
||||
makeButton: (thread, type) ->
|
||||
a = $.el 'a',
|
||||
className: "#{type}-thread-button"
|
||||
innerHTML: "<span class='fa fa-#{if type is 'hide' then 'minus' else 'plus'}-square'></span>"
|
||||
href: 'javascript:;'
|
||||
$.extend a, <%= html('<span class="fa fa-${if type is "hide" then "minus" else "plus"}-square"></span>') %>
|
||||
a.dataset.fullID = thread.fullID
|
||||
$.on a, 'click', ThreadHiding.toggle
|
||||
a
|
||||
|
||||
@ -39,7 +39,7 @@ Build =
|
||||
flagName: Build.unescape data.country_name
|
||||
date: data.now
|
||||
dateUTC: data.time
|
||||
h_comment: data.com or ''
|
||||
comment: {innerHTML: data.com or ''}
|
||||
# thread status
|
||||
isSticky: !!data.sticky
|
||||
isClosed: !!data.closed
|
||||
@ -75,86 +75,75 @@ Build =
|
||||
postID, threadID, boardID
|
||||
name, capcode, tripcode, uniqueID, email, subject, flagCode, flagName, date, dateUTC
|
||||
isSticky, isClosed
|
||||
comment
|
||||
file
|
||||
} = o
|
||||
name or= ''
|
||||
subject or= ''
|
||||
h_comment = o.h_comment
|
||||
isOP = postID is threadID
|
||||
|
||||
if Build.initPixelRatio >= 2
|
||||
h_retina = '@2x'
|
||||
else
|
||||
h_retina = ''
|
||||
retina = if Build.initPixelRatio >= 2 then '@2x' else ''
|
||||
|
||||
### Name Block ###
|
||||
|
||||
switch capcode
|
||||
when 'admin', 'admin_highlight'
|
||||
h_capcodeClass = ' capcodeAdmin'
|
||||
h_capcodeStart = ' <strong class="capcode hand id_admin" title="Highlight posts by the Administrator">## Admin</strong>'
|
||||
h_capcodeIcon = "<img src='//s.4cdn.org/image/adminicon#{h_retina}.gif' alt='Admin Icon' title='This user is the 4chan Administrator.' class='identityIcon retina'>"
|
||||
capcodeClass = ' capcodeAdmin'
|
||||
capcodeStart = <%= html(' <strong class="capcode hand id_admin" title="Highlight posts by the Administrator">## Admin</strong>') %>
|
||||
capcodeIcon = <%= html('<img src="//s.4cdn.org/image/adminicon${retina}.gif" alt="Admin Icon" title="This user is the 4chan Administrator." class="identityIcon retina">') %>
|
||||
when 'mod'
|
||||
h_capcodeClass = ' capcodeMod'
|
||||
h_capcodeStart = ' <strong class="capcode hand id_mod" title="Highlight posts by Moderators">## Mod</strong>'
|
||||
h_capcodeIcon = "<img src='//s.4cdn.org/image/modicon#{h_retina}.gif' alt='Mod Icon' title='This user is a 4chan Moderator.' class='identityIcon retina'>"
|
||||
capcodeClass = ' capcodeMod'
|
||||
capcodeStart = <%= html(' <strong class="capcode hand id_mod" title="Highlight posts by Moderators">## Mod</strong>') %>
|
||||
capcodeIcon = <%= html('<img src="//s.4cdn.org/image/modicon${retina}.gif" alt="Mod Icon" title="This user is a 4chan Moderator." class="identityIcon retina">') %>
|
||||
when 'developer'
|
||||
h_capcodeClass = ' capcodeDeveloper'
|
||||
h_capcodeStart = ' <strong class="capcode hand id_developer" title="Highlight posts by Developers">## Developer</strong>'
|
||||
h_capcodeIcon = "<img src='//s.4cdn.org/image/developericon#{h_retina}.gif' alt='Developer Icon' title='This user is a 4chan Developer.' class='identityIcon retina'>"
|
||||
capcodeClass = ' capcodeDeveloper'
|
||||
capcodeStart = <%= html(' <strong class="capcode hand id_developer" title="Highlight posts by Developers">## Developer</strong>') %>
|
||||
capcodeIcon = <%= html('<img src="//s.4cdn.org/image/developericon${retina}.gif" alt="Developer Icon" title="This user is a 4chan Developer." class="identityIcon retina">') %>
|
||||
else
|
||||
h_capcodeClass = ''
|
||||
h_capcodeStart = ''
|
||||
h_capcodeIcon = ''
|
||||
capcodeClass = ''
|
||||
capcodeStart = <%= html('') %>
|
||||
capcodeIcon = <%= html('') %>
|
||||
|
||||
if capcode
|
||||
h_nameClass = ' capcode'
|
||||
nameClass = if capcode then ' capcode' else ''
|
||||
|
||||
tripcodeField = if tripcode
|
||||
<%= html(' <span class="postertrip">${tripcode}</span>') %>
|
||||
else
|
||||
h_nameClass = ''
|
||||
<%= html('') %>
|
||||
|
||||
if tripcode
|
||||
h_tripcode = " <span class='postertrip'>#{E tripcode}</span>"
|
||||
else
|
||||
h_tripcode = ''
|
||||
|
||||
h_emailCont = "<span class='name#{h_nameClass}'>#{E name}</span>#{h_tripcode}#{h_capcodeStart}"
|
||||
emailField = <%= html('<span class="name${nameClass}">${name}</span>&{tripcodeField}&{capcodeStart}') %>
|
||||
if email
|
||||
emailProcessed = encodeURIComponent(email).replace /%40/g, '@'
|
||||
h_email = "<a href='mailto:#{E emailProcessed}' class='useremail'>#{h_emailCont}</a>"
|
||||
else
|
||||
h_email = h_emailCont
|
||||
emailField = <%= html('<a href="mailto:${emailProcessed}" class="useremail">&{emailField}</a>') %>
|
||||
unless isOP and boardID is 'f'
|
||||
h_email += ' '
|
||||
emailField = <%= html('&{emailField} ') %>
|
||||
|
||||
if !capcode and uniqueID
|
||||
h_userID = " <span class='posteruid id_#{E uniqueID}'>(ID: <span class='hand' title='Highlight posts by this ID'>#{E uniqueID}</span>)</span>"
|
||||
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
|
||||
h_userID = ''
|
||||
<%= html('') %>
|
||||
|
||||
unless flagCode
|
||||
h_flag = ''
|
||||
flag = unless flagCode
|
||||
<%= html('') %>
|
||||
else if boardID is 'pol'
|
||||
<%= html('<img src="//s.4cdn.org/image/country/troll/${flagCode.toLowerCase()}.gif" alt="${flagCode}" title="${flagName}" class="countryFlag">') %>
|
||||
else
|
||||
flagCodeLC = flagCode.toLowerCase()
|
||||
if boardID is 'pol'
|
||||
h_flag = "<img src='//s.4cdn.org/image/country/troll/#{E flagCodeLC}.gif' alt='#{E flagCode}' title='#{E flagName}' class='countryFlag'>"
|
||||
else
|
||||
h_flag = "<span title='#{E flagName}' class='flag flag-#{E flagCodeLC}'></span>"
|
||||
<%= html('<span title="${flagName}" class="flag flag-${flagCode.toLowerCase()}"></span>') %>
|
||||
|
||||
h_nameBlock = "<span class='nameBlock#{h_capcodeClass}'>"
|
||||
h_nameBlock += "#{h_email}#{h_capcodeIcon}#{h_userID}#{h_flag}"
|
||||
h_nameBlock += '</span> '
|
||||
nameBlock = <%= html(
|
||||
'<span class="nameBlock${capcodeClass}">' +
|
||||
'&{emailField}&{capcodeIcon}&{userID}&{flag}' +
|
||||
'</span> '
|
||||
) %>
|
||||
|
||||
### Post Info ###
|
||||
|
||||
if isOP or boardID is 'f'
|
||||
h_subject = "<span class='subject'>#{E subject}</span> "
|
||||
subjectField = if isOP or boardID is 'f'
|
||||
<%= html('<span class="subject">${subject}</span> ') %>
|
||||
else
|
||||
h_subject = ''
|
||||
<%= html('') %>
|
||||
|
||||
if isOP and boardID is 'f'
|
||||
h_desktop2 = ''
|
||||
else
|
||||
h_desktop2 = ' desktop'
|
||||
desktop2 = if isOP and boardID is 'f' then '' else ' desktop'
|
||||
|
||||
postLink = Build.postURL boardID, threadID, postID
|
||||
quoteLink = if Build.sameThread boardID, threadID
|
||||
@ -162,56 +151,59 @@ Build =
|
||||
else
|
||||
"/#{boardID}/thread/#{threadID}\#q#{postID}"
|
||||
|
||||
if isOP and g.VIEW is 'index' and Conf['JSON Navigation']
|
||||
pageIcon = if isOP and g.VIEW is 'index' and Conf['JSON Navigation']
|
||||
pageNum = Math.floor(Index.liveThreadIDs.indexOf(postID) / Index.threadsNumPerPage) + 1
|
||||
h_pageIcon = " <span class='page-num' title='This thread is on page #{+pageNum} in the original index.'>[#{+pageNum}]</span>"
|
||||
<%= html(' <span class="page-num" title="This thread is on page ${pageNum} in the original index.">[${pageNum}]</span>') %>
|
||||
else
|
||||
h_pageIcon = ''
|
||||
<%= html('') %>
|
||||
|
||||
if isSticky
|
||||
h_sticky = " <img src='//s.4cdn.org/image/sticky#{h_retina}.gif' alt='Sticky' title='Sticky' class='stickyIcon retina'>"
|
||||
sticky = if isSticky
|
||||
<%= html(' <img src="//s.4cdn.org/image/sticky${retina}.gif" alt="Sticky" title="Sticky" class="stickyIcon retina">') %>
|
||||
else
|
||||
h_sticky = ''
|
||||
<%= html('') %>
|
||||
|
||||
if isClosed
|
||||
h_closed = " <img src='//s.4cdn.org/image/closed#{h_retina}.gif' alt='Closed' title='Closed' class='closedIcon retina'>"
|
||||
closed = if isClosed
|
||||
<%= html(' <img src="//s.4cdn.org/image/closed${retina}.gif" alt="Closed" title="Closed" class="closedIcon retina">') %>
|
||||
else
|
||||
h_closed = ''
|
||||
<%= html('') %>
|
||||
|
||||
if isOP and g.VIEW is 'index'
|
||||
h_replyLink = " <span>[<a href='/#{E boardID}/thread/#{+threadID}' class='replylink'>Reply</a>]</span>"
|
||||
replyLink = if isOP and g.VIEW is 'index'
|
||||
<%= html(' <span>[<a href="/${boardID}/thread/${threadID}" class="replylink">Reply</a>]</span>') %>
|
||||
else
|
||||
h_replyLink = ''
|
||||
<%= html('') %>
|
||||
|
||||
h_postInfo = "<div class='postInfo desktop' id='pi#{+postID}'>"
|
||||
h_postInfo += "<input type='checkbox' name='#{+postID}' value='delete'> "
|
||||
h_postInfo += h_subject
|
||||
h_postInfo += h_nameBlock
|
||||
h_postInfo += "<span class='dateTime' data-utc='#{+dateUTC}'>#{E date}</span> "
|
||||
h_postInfo += "<span class='postNum#{h_desktop2}'>"
|
||||
h_postInfo += "<a href='#{E postLink}' title='Link to this post'>No.</a>"
|
||||
h_postInfo += "<a href='#{E quoteLink}' title='Reply to this post'>#{+postID}</a>"
|
||||
h_postInfo += "#{h_pageIcon}#{h_sticky}#{h_closed}#{h_replyLink}"
|
||||
h_postInfo += '</span>'
|
||||
h_postInfo += '</div>'
|
||||
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>' +
|
||||
'&{pageIcon}&{sticky}&{closed}&{replyLink}' +
|
||||
'</span>' +
|
||||
'</div>'
|
||||
) %>
|
||||
|
||||
### File Info ###
|
||||
|
||||
if file?.isDeleted
|
||||
h_fileCont = '<span class="fileThumb">'
|
||||
h_fileCont += "<img src='//s.4cdn.org/image/filedeleted-res#{h_retina}.gif' alt='File deleted.' class='fileDeletedRes retina'>"
|
||||
h_fileCont += '</span>'
|
||||
fileCont = if file?.isDeleted
|
||||
<%= html(
|
||||
'<span class="fileThumb">' +
|
||||
'<img src="//s.4cdn.org/image/filedeleted-res${retina}.gif" alt="File deleted." class="fileDeletedRes retina">' +
|
||||
'</span>'
|
||||
) %>
|
||||
else if file and boardID is 'f'
|
||||
fileSize = $.bytesToString file.size
|
||||
h_fileCont = "<div class='fileInfo'><span class='fileText' id='fT#{+postID}'>"
|
||||
h_fileCont += "File: <a data-width='#{+file.width}' data-height='#{+file.height}' href='#{E file.url}' target='_blank'>#{E file.name}</a>"
|
||||
h_fileCont += "-(#{E fileSize}, #{+file.width}x#{+file.height}, #{E file.tag})"
|
||||
h_fileCont += '</span></div>'
|
||||
<%= 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
|
||||
if file.isSpoiler
|
||||
h_fileTitle1 = "title='#{E file.name}'"
|
||||
shortFilename = 'Spoiler Image'
|
||||
h_spoilerClass = ' imgspoiler'
|
||||
if spoilerRange = Build.spoilerRange[boardID]
|
||||
# Randomize the spoiler image.
|
||||
fileThumb = "//s.4cdn.org/image/spoiler-#{boardID}#{Math.floor 1 + spoilerRange * Math.random()}.png"
|
||||
@ -219,58 +211,58 @@ Build =
|
||||
fileThumb = '//s.4cdn.org/image/spoiler.png'
|
||||
file.twidth = file.theight = 100
|
||||
else
|
||||
h_fileTitle1 = ''
|
||||
shortFilename = Build.shortFilename file.name, !isOP
|
||||
h_spoilerClass = ''
|
||||
fileThumb = file.turl
|
||||
|
||||
if file.isSpoiler or file.name is shortFilename
|
||||
h_fileTitle2 = ''
|
||||
fileSize = $.bytesToString file.size
|
||||
fileDims = if file.url[-4..] is '.pdf' then 'PDF' else "#{+file.width}x#{+file.height}"
|
||||
|
||||
fileLink = if file.isSpoiler or file.name is shortFilename
|
||||
<%= html('<a href="${file.url}" target="_blank">${shortFilename}</a>') %>
|
||||
else
|
||||
h_fileTitle2 = "title='#{E file.name}'"
|
||||
<%= html('<a title="${file.name}" href="${file.url}" target="_blank">${shortFilename}</a>') %>
|
||||
|
||||
fileSize = $.bytesToString file.size
|
||||
|
||||
if file.url[-4..] is '.pdf'
|
||||
h_fileDims = 'PDF'
|
||||
fileText = if file.isSpoiler
|
||||
<%= html('<div class="fileText" id="fT${postID}" title="${file.name}">File: &{fileLink} (${fileSize}, ${fileDims})</div>') %>
|
||||
else
|
||||
h_fileDims = "#{+file.width}x#{+file.height}"
|
||||
<%= html('<div class="fileText" id="fT${postID}">File: &{fileLink} (${fileSize}, ${fileDims})</div>') %>
|
||||
|
||||
h_fileCont = "<div class='fileText' id='fT#{+postID}' #{h_fileTitle1}>"
|
||||
h_fileCont += "File: <a #{h_fileTitle2} href='#{E file.url}' target='_blank'>#{E shortFilename}</a> (#{E fileSize}, #{h_fileDims})"
|
||||
h_fileCont += '</div>'
|
||||
h_fileCont += "<a class='fileThumb#{h_spoilerClass}' href='#{E file.url}' target='_blank'>"
|
||||
h_fileCont += "<img src='#{E fileThumb}' alt='#{E fileSize}' data-md5='#{E file.MD5}' style='height: #{+file.theight}px; width: #{+file.twidth}px;'>"
|
||||
h_fileCont += '</a>'
|
||||
<%= html(
|
||||
'&{fileText}' +
|
||||
'<a class="fileThumb${if file.isSpoiler then " imgspoiler" else ""}" href="${file.url}" target="_blank">' +
|
||||
'<img src="${fileThumb}" alt="${fileSize}" data-md5="${file.MD5}" style="height: ${file.theight}px; width: ${+file.twidth}px;">' +
|
||||
'</a>'
|
||||
) %>
|
||||
|
||||
if file
|
||||
h_file = "<div class='file' id='f#{+postID}'>#{h_fileCont}</div>"
|
||||
fileBlock = if file
|
||||
<%= html('<div class="file" id="f${postID}">&{fileCont}</div>') %>
|
||||
else
|
||||
h_file = ''
|
||||
<%= html('') %>
|
||||
|
||||
### Whole Post ###
|
||||
|
||||
if capcode is 'admin_highlight'
|
||||
h_highlightPost = ' highlightPost'
|
||||
else
|
||||
h_highlightPost = ''
|
||||
highlightPost = if capcode is 'admin_highlight' then ' highlightPost' else ''
|
||||
|
||||
h_message = "<blockquote class='postMessage' id='m#{+postID}'>#{h_comment}</blockquote>"
|
||||
message = <%= html('<blockquote class="postMessage" id="m${postID}">&{comment}</blockquote>') %>
|
||||
|
||||
if isOP
|
||||
h_post = "<div id='p#{+postID}' class='post op#{h_highlightPost}'>"
|
||||
h_post += "#{h_file}#{h_postInfo}#{h_message}"
|
||||
h_post += '</div>'
|
||||
wholePost = if isOP
|
||||
<%= html(
|
||||
'<div id="p${postID}" class="post op${highlightPost}">' +
|
||||
'&{fileBlock}&{postInfo}&{message}' +
|
||||
'</div>'
|
||||
) %>
|
||||
else
|
||||
h_post = "<div class='sideArrows' id='sa#{+postID}'>>></div>"
|
||||
h_post += "<div id='p#{+postID}' class='post reply#{h_highlightPost}'>"
|
||||
h_post += "#{h_postInfo}#{h_file}#{h_message}"
|
||||
h_post += '</div>'
|
||||
<%= html(
|
||||
'<div class="sideArrows" id="sa${postID}">>></div>' +
|
||||
'<div id="p${postID}" class="post reply${highlightPost}">' +
|
||||
'&{postInfo}&{fileBlock}&{message}' +
|
||||
'</div>'
|
||||
) %>
|
||||
|
||||
container = $.el 'div',
|
||||
className: "postContainer #{if isOP then 'op' else 'reply'}Container"
|
||||
id: "pc#{postID}"
|
||||
innerHTML: h_post
|
||||
$.extend container, wholePost
|
||||
|
||||
# Fix pathnames
|
||||
for quote in $$ '.quotelink', container
|
||||
|
||||
@ -159,21 +159,24 @@ Get =
|
||||
root.textContent = data.error
|
||||
return
|
||||
|
||||
# convert comment to html
|
||||
h_comment = E (data.comment or '')
|
||||
# https://github.com/eksopl/fuuka/blob/master/Board/Yotsuba.pm#L413-452
|
||||
# https://github.com/eksopl/asagi/blob/master/src/main/java/net/easymodo/asagi/Yotsuba.java#L109-138
|
||||
h_comment = h_comment.replace ///
|
||||
\n
|
||||
|
|
||||
\[/?[a-z]+(:lit)?\]
|
||||
///g, Get.parseMarkup
|
||||
|
||||
h_comment = h_comment
|
||||
# greentext
|
||||
.replace(/(^|>)(>[^<$]*)(<|$)/g, '$1<span class="quote">$2</span>$3')
|
||||
# quotes
|
||||
.replace /((>){2}(>\/[a-z\d]+\/)?\d+)/g, '<span class="deadlink">$1</span>'
|
||||
comment = (data.comment or '').split /(\n|\[\/?(?:b|spoiler|code|moot|banned)\])/
|
||||
comment = for text, i in comment
|
||||
if i % 2 is 1
|
||||
Get.archiveTags[text]
|
||||
else
|
||||
greentext = text[0] is '>'
|
||||
text = text.replace /(\[\/?[a-z]+):lit(\])/, '$1$2'
|
||||
text = for text2, j in text.split /(>>(?:>\/[a-z\d]+\/)?\d+)/g
|
||||
if j % 2 is 1
|
||||
<%= html('<span class="deadlink">${text2}</span>') %>
|
||||
else
|
||||
<%= html('${text2}') %>
|
||||
text = <%= html('@{text}') %>
|
||||
text = <%= html('<span class="quote">&{text}</span>') %> if greentext
|
||||
text
|
||||
comment = <%= html('@{comment}') %>
|
||||
|
||||
threadID = +data.thread_num
|
||||
o =
|
||||
@ -195,7 +198,7 @@ Get =
|
||||
flagName: data.poster_country_name
|
||||
date: data.fourchan_date
|
||||
dateUTC: data.timestamp
|
||||
h_comment: h_comment
|
||||
comment: comment
|
||||
# file
|
||||
if data.media?.media_filename
|
||||
o.file =
|
||||
@ -221,17 +224,15 @@ Get =
|
||||
post.isFetchedQuote = true
|
||||
Main.callbackNodes Post, [post]
|
||||
Get.insert post, root, context
|
||||
parseMarkup: (text) ->
|
||||
{
|
||||
'\n': '<br>'
|
||||
'[b]': '<b>'
|
||||
'[/b]': '</b>'
|
||||
'[spoiler]': '<s>'
|
||||
'[/spoiler]': '</s>'
|
||||
'[code]': '<pre class="prettyprint">'
|
||||
'[/code]': '</pre>'
|
||||
'[moot]': '<div style="padding:5px;margin-left:.5em;border-color:#faa;border:2px dashed rgba(255,0,0,.1);border-radius:2px">'
|
||||
'[/moot]': '</div>'
|
||||
'[banned]': '<strong style="color: red;">'
|
||||
'[/banned]': '</strong>'
|
||||
}[text] or text.replace ':lit', ''
|
||||
archiveTags:
|
||||
'\n': <%= html('<br>') %>
|
||||
'[b]': <%= html('<b>') %>
|
||||
'[/b]': <%= html('</b>') %>
|
||||
'[spoiler]': <%= html('<s>') %>
|
||||
'[/spoiler]': <%= html('</s>') %>
|
||||
'[code]': <%= html('<pre class="prettyprint">') %>
|
||||
'[/code]': <%= html('</pre>') %>
|
||||
'[moot]': <%= html('<div style="padding:5px;margin-left:.5em;border-color:#faa;border:2px dashed rgba(255,0,0,.1);border-radius:2px">') %>
|
||||
'[/moot]': <%= html('</div>') %>
|
||||
'[banned]': <%= html('<strong style="color: red;">') %>
|
||||
'[/banned]': <%= html('</strong>') %>
|
||||
|
||||
@ -5,6 +5,9 @@ doc = d.documentElement
|
||||
g =
|
||||
VERSION: '<%= version %>'
|
||||
NAMESPACE: '<%= meta.name %>.'
|
||||
NAME: '<%= meta.name %>'
|
||||
FAQ: '<%= meta.faq %>'
|
||||
CHANGELOG: '<%= meta.repo %>blob/<%= meta.mainBranch %>/CHANGELOG.md'
|
||||
boards: {}
|
||||
E = (text) ->
|
||||
(text+'').replace /[&"'<>]/g, (x) ->
|
||||
|
||||
@ -4,7 +4,7 @@ Header =
|
||||
|
||||
menuButton = $.el 'span',
|
||||
className: 'menu-button'
|
||||
innerHTML: '<i></i>'
|
||||
$.extend menuButton, <%= html('<i></i>') %>
|
||||
|
||||
barFixedToggler = UI.checkbox 'Fixed Header', ' Fixed Header'
|
||||
headerToggler = UI.checkbox 'Header auto-hide', ' Auto-hide header'
|
||||
@ -132,7 +132,13 @@ Header =
|
||||
fourchannav = $.id 'boardNavDesktop'
|
||||
Header.boardList = boardList = $.el 'span',
|
||||
id: 'board-list'
|
||||
innerHTML: "<span id='custom-board-list'></span><span id='full-board-list' hidden><span class='hide-board-list-container brackets-wrap'><a href='javascript:;' class='hide-board-list-button'> - </a></span> #{fourchannav.innerHTML}</span>"
|
||||
$.extend boardList, <%= html(
|
||||
'<span id="custom-board-list"></span>' +
|
||||
'<span id="full-board-list" hidden>' +
|
||||
'<span class="hide-board-list-container brackets-wrap"><a href="javascript:;" class="hide-board-list-button"> - </a></span> ' +
|
||||
'&{fourchannav}' +
|
||||
'</span>'
|
||||
) %>
|
||||
for a in $$ 'a', boardList
|
||||
if a.pathname.split('/')[1] is g.BOARD.ID
|
||||
a.className = 'current'
|
||||
@ -442,11 +448,11 @@ Header =
|
||||
return
|
||||
|
||||
el = $.el 'span',
|
||||
innerHTML: '''
|
||||
<%= meta.name %> needs your permission to show desktop notifications.
|
||||
[<a href='<%= meta.faq %>#why-is-4chan-x-asking-for-permission-to-show-desktop-notifications' target=_blank>FAQ</a>]<br>
|
||||
<button>Authorize</button> or <button>Disable</button>
|
||||
'''
|
||||
<%= html(
|
||||
'${g.NAME} needs your permission to show desktop notifications. ' +
|
||||
'[<a href="${g.FAQ}#why-is-4chan-x-asking-for-permission-to-show-desktop-notifications" target="_blank">FAQ</a>]<br>' +
|
||||
'<button>Authorize</button> or <button>Disable</button>'
|
||||
) %>
|
||||
[authorize, disable] = $$ 'button', el
|
||||
$.on authorize, 'click', ->
|
||||
Notification.requestPermission (status) ->
|
||||
|
||||
@ -15,9 +15,9 @@ Index =
|
||||
modeEntry =
|
||||
el: $.el 'span', textContent: 'Index mode'
|
||||
subEntries: [
|
||||
{ el: $.el 'label', innerHTML: '<input type="radio" name="Index Mode" value="paged"> Paged' }
|
||||
{ el: $.el 'label', innerHTML: '<input type="radio" name="Index Mode" value="infinite"> Infinite scrolling' }
|
||||
{ el: $.el 'label', innerHTML: '<input type="radio" name="Index Mode" value="all pages"> All threads' }
|
||||
{ el: $.el 'label', <%= html('<input type="radio" name="Index Mode" value="paged"> Paged') %> }
|
||||
{ el: $.el 'label', <%= html('<input type="radio" name="Index Mode" value="infinite"> Infinite scrolling') %> }
|
||||
{ el: $.el 'label', <%= html('<input type="radio" name="Index Mode" value="all pages"> All threads') %> }
|
||||
]
|
||||
for label in modeEntry.subEntries
|
||||
input = label.el.firstChild
|
||||
@ -28,11 +28,11 @@ Index =
|
||||
sortEntry =
|
||||
el: $.el 'span', textContent: 'Sort by'
|
||||
subEntries: [
|
||||
{ el: $.el 'label', innerHTML: '<input type="radio" name="Index Sort" value="bump"> Bump order' }
|
||||
{ el: $.el 'label', innerHTML: '<input type="radio" name="Index Sort" value="lastreply"> Last reply' }
|
||||
{ el: $.el 'label', innerHTML: '<input type="radio" name="Index Sort" value="birth"> Creation date' }
|
||||
{ el: $.el 'label', innerHTML: '<input type="radio" name="Index Sort" value="replycount"> Reply count' }
|
||||
{ el: $.el 'label', innerHTML: '<input type="radio" name="Index Sort" value="filecount"> File count' }
|
||||
{ el: $.el 'label', <%= html('<input type="radio" name="Index Sort" value="bump"> Bump order') %> }
|
||||
{ el: $.el 'label', <%= html('<input type="radio" name="Index Sort" value="lastreply"> Last reply') %> }
|
||||
{ el: $.el 'label', <%= html('<input type="radio" name="Index Sort" value="birth"> Creation date') %> }
|
||||
{ el: $.el 'label', <%= html('<input type="radio" name="Index Sort" value="replycount"> Reply count') %> }
|
||||
{ el: $.el 'label', <%= html('<input type="radio" name="Index Sort" value="filecount"> File count') %> }
|
||||
]
|
||||
for label in sortEntry.subEntries
|
||||
input = label.el.firstChild
|
||||
@ -66,10 +66,10 @@ Index =
|
||||
@pagelist = $.el 'div',
|
||||
className: 'pagelist'
|
||||
hidden: true
|
||||
innerHTML: <%= importHTML('Features/Index-pagelist') %>
|
||||
$.extend @pagelist, <%= importHTML('Features/Index-pagelist') %>
|
||||
@navLinks = $.el 'div',
|
||||
className: 'navLinks'
|
||||
innerHTML: <%= importHTML('Features/Index-navlinks') %>
|
||||
$.extend @navLinks, <%= importHTML('Features/Index-navlinks') %>
|
||||
$('.returnlink a', @navLinks).href = "//boards.4chan.org/#{g.BOARD}/"
|
||||
$('.cataloglink a', @navLinks).href = "//boards.4chan.org/#{g.BOARD}/catalog"
|
||||
@searchInput = $ '#index-search', @navLinks
|
||||
|
||||
@ -189,7 +189,7 @@ Main =
|
||||
return if previousversion is g.VERSION
|
||||
if previousversion
|
||||
el = $.el 'span',
|
||||
innerHTML: '<%= meta.name %> has been updated to <a href="<%= meta.repo %>blob/<%= meta.mainBranch %>/CHANGELOG.md" target="_blank">version <%= version %></a>.'
|
||||
<%= html('${g.NAME} has been updated to <a href="${g.CHANGELOG}" target="_blank">version ${g.VERSION}</a>.') %>
|
||||
new Notice 'info', el, 15
|
||||
else
|
||||
Settings.open()
|
||||
@ -230,7 +230,7 @@ Main =
|
||||
return
|
||||
|
||||
div = $.el 'div',
|
||||
innerHTML: "#{+errors.length} errors occurred. [<a href='javascript:;'>show</a>]"
|
||||
<%= html('${errors.length} errors occurred. [<a href="javascript:;">show</a>]') %>
|
||||
$.on div.lastElementChild, 'click', ->
|
||||
[@textContent, logs.hidden] = if @textContent is 'show'
|
||||
['hide', false]
|
||||
|
||||
@ -34,7 +34,7 @@ Settings =
|
||||
Settings.dialog = dialog = $.el 'div',
|
||||
id: 'fourchanx-settings'
|
||||
className: 'dialog'
|
||||
innerHTML: <%= importHTML('Settings/Settings') %>
|
||||
$.extend dialog, <%= importHTML('Settings/Settings') %>
|
||||
|
||||
$.on $('.export', Settings.dialog), 'click', Settings.export
|
||||
$.on $('.import', Settings.dialog), 'click', Settings.import
|
||||
@ -90,8 +90,7 @@ Settings =
|
||||
inputs = {}
|
||||
for key, obj of Config.main
|
||||
fs = $.el 'fieldset',
|
||||
innerHTML: '<legend></legend>'
|
||||
fs.firstElementChild.textContent = key
|
||||
<%= html('<legend>${key}</legend>') %>
|
||||
for key, arr of obj
|
||||
description = arr[1]
|
||||
div = $.el 'div'
|
||||
@ -112,7 +111,7 @@ Settings =
|
||||
return
|
||||
|
||||
div = $.el 'div',
|
||||
innerHTML: '<button></button><span class="description">: Clear manually-hidden threads and posts on all boards. Reload the page to apply.'
|
||||
<%= html('<button></button><span class="description">: Clear manually-hidden threads and posts on all boards. Reload the page to apply.') %>
|
||||
button = $ 'button', div
|
||||
$.get {hiddenThreads: {}, hiddenPosts: {}}, ({hiddenThreads, hiddenPosts}) ->
|
||||
hiddenNum = 0
|
||||
@ -247,7 +246,7 @@ Settings =
|
||||
$.clear -> window.location.reload() if confirm 'Reset successful. Reload now?'
|
||||
|
||||
filter: (section) ->
|
||||
section.innerHTML = <%= importHTML('Settings/Filter-select') %>
|
||||
$.extend section, <%= importHTML('Settings/Filter-select') %>
|
||||
select = $ 'select', section
|
||||
$.on select, 'change', Settings.selectFilter
|
||||
Settings.selectFilter.call select
|
||||
@ -265,11 +264,11 @@ Settings =
|
||||
$.on ta, 'change', $.cb.value
|
||||
$.add div, ta
|
||||
return
|
||||
div.innerHTML = <%= importHTML('Settings/Filter-guide') %>
|
||||
$.extend div, <%= importHTML('Settings/Filter-guide') %>
|
||||
$('.warning', div).hidden = Conf['Filter']
|
||||
|
||||
sauce: (section) ->
|
||||
section.innerHTML = <%= importHTML('Settings/Sauce') %>
|
||||
$.extend section, <%= importHTML('Settings/Sauce') %>
|
||||
$('.warning', section).hidden = Conf['Sauce']
|
||||
ta = $ 'textarea', section
|
||||
$.get 'sauces', Conf['sauces'], (item) ->
|
||||
@ -277,7 +276,7 @@ Settings =
|
||||
$.on ta, 'change', $.cb.value
|
||||
|
||||
advanced: (section) ->
|
||||
section.innerHTML = <%= importHTML('Settings/Advanced') %>
|
||||
$.extend section, <%= importHTML('Settings/Advanced') %>
|
||||
warning.hidden = Conf[warning.dataset.feature] for warning in $$ '.warning', section
|
||||
|
||||
items = {}
|
||||
@ -387,7 +386,7 @@ Settings =
|
||||
textContent: archive
|
||||
value: archive
|
||||
|
||||
td.innerHTML = '<select></select>'
|
||||
$.extend td, <%= html('<select></select>') %>
|
||||
select = td.firstElementChild
|
||||
unless select.disabled = length is 1
|
||||
# XXX GM can't into datasets
|
||||
@ -441,7 +440,7 @@ Settings =
|
||||
CustomCSS.update()
|
||||
|
||||
keybinds: (section) ->
|
||||
section.innerHTML = <%= importHTML('Settings/Keybinds') %>
|
||||
$.extend section, <%= importHTML('Settings/Keybinds') %>
|
||||
$('.warning', section).hidden = Conf['Keybinds']
|
||||
|
||||
tbody = $ 'tbody', section
|
||||
@ -449,8 +448,7 @@ Settings =
|
||||
inputs = {}
|
||||
for key, arr of Config.hotkeys
|
||||
tr = $.el 'tr',
|
||||
innerHTML: '<td></td><td><input class="field"></td>'
|
||||
tr.firstElementChild.textContent = arr[1]
|
||||
<%= html('<td>${arr[1]}</td><td><input class="field"></td>') %>
|
||||
input = $ 'input', tr
|
||||
input.name = key
|
||||
input.spellcheck = false
|
||||
|
||||
@ -46,9 +46,11 @@ $.ajax = do ->
|
||||
blockedError = (url) ->
|
||||
return if blockedURLs[url]
|
||||
blockedURLs[url] = true
|
||||
h_message = '<%= meta.name %> was blocked from loading the following URL:<br><span></span><br>'
|
||||
h_message += '[<a href="<%= meta.faq %>#why-was-4chan-x-blocked-from-loading-a-url" target="_blank">More info</a>]'
|
||||
message = $.el 'div', innerHTML: h_message
|
||||
message = $.el 'div',
|
||||
<%= html(
|
||||
'${g.NAME} was blocked from loading the following URL:<br><span></span><br>' +
|
||||
'[<a href="${g.FAQ}#why-was-4chan-x-blocked-from-loading-a-url" target="_blank">More info</a>]'
|
||||
) %>
|
||||
$('span', message).textContent = (if /^\/\//.test url then location.protocol else '') + url
|
||||
new Notice 'error', message, 30, -> delete blockedURLs[url]
|
||||
(url, options, extra={}) ->
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
class Notice
|
||||
constructor: (type, content, @timeout, @onclose) ->
|
||||
@el = $.el 'div',
|
||||
innerHTML: '<a href="javascript:;" class="close fa fa-times" title="Close"></a><div class="message"></div>'
|
||||
<%= html('<a href="javascript:;" class="close fa fa-times" title="Close"></a><div class="message"></div>') %>
|
||||
@el.style.opacity = 0
|
||||
@setType type
|
||||
$.on @el.firstElementChild, 'click', @close
|
||||
|
||||
@ -36,7 +36,7 @@ Gallery =
|
||||
|
||||
nodes.el = dialog = $.el 'div',
|
||||
id: 'a-gallery'
|
||||
innerHTML: <%= importHTML('Features/Gallery') %>
|
||||
$.extend dialog, <%= importHTML('Features/Gallery') %>
|
||||
|
||||
nodes[key] = $ value, dialog for key, value of {
|
||||
buttons: '.gal-buttons'
|
||||
@ -288,7 +288,7 @@ Gallery =
|
||||
createSubEntries: ->
|
||||
subEntries = ['Hide Thumbnails', 'Fit Width', 'Fit Height', 'Scroll to Post'].map Gallery.menu.createSubEntry
|
||||
|
||||
delayLabel = $.el 'label', innerHTML: 'Slide Delay: <input type="number" name="Slide Delay" min="0" step="any" class="field">'
|
||||
delayLabel = $.el 'label', <%= html('Slide Delay: <input type="number" name="Slide Delay" min="0" step="any" class="field">') %>
|
||||
delayInput = delayLabel.firstElementChild
|
||||
delayInput.value = Gallery.delay
|
||||
$.on delayInput, 'change', Gallery.cb.setDelay
|
||||
|
||||
@ -10,6 +10,8 @@ ImageExpand =
|
||||
$.on @EAI, 'click', @cb.toggleAll
|
||||
Header.addShortcut @EAI, 3
|
||||
$.on d, 'scroll visibilitychange', @cb.playVideos
|
||||
@videoControls = $.el 'span', className: 'video-controls'
|
||||
$.extend @videoControls, <%= html('\u00A0<a href="javascript:;" title="You can also contract the video by dragging it to the left.">contract</a>') %>
|
||||
|
||||
Post.callbacks.push
|
||||
name: 'Image Expansion'
|
||||
@ -219,10 +221,6 @@ ImageExpand =
|
||||
if controls
|
||||
ImageCommon.addControls fullImage
|
||||
|
||||
videoControls: $.el 'span',
|
||||
className: 'video-controls'
|
||||
innerHTML: '\u00A0<a href="javascript:;" title="You can also contract the video by dragging it to the left.">contract</a>'
|
||||
|
||||
videoCB: do ->
|
||||
# dragging to the left contracts the video
|
||||
mousedown = false
|
||||
|
||||
@ -14,7 +14,7 @@ ImageLoader =
|
||||
return unless Conf['Image Prefetching'] and g.VIEW is 'thread'
|
||||
|
||||
prefetch = $.el 'label',
|
||||
innerHTML: '<input type="checkbox" name="prefetch"> Prefetch Images'
|
||||
<%= html('<input type="checkbox" name="prefetch"> Prefetch Images') %>
|
||||
|
||||
@el = prefetch.firstElementChild
|
||||
$.on @el, 'change', @toggle
|
||||
|
||||
@ -175,8 +175,7 @@ Linkify =
|
||||
try
|
||||
$.cache service.api(uid), (-> Linkify.cb.title @, data), responseType: 'json'
|
||||
catch err
|
||||
link.innerHTML = '<span class="warning">Title Link Blocked</span> (are you using NoScript?)</a>'
|
||||
$.prepend link, $.tn "[#{key}] "
|
||||
$.extend link, <%= html('[${key}] <span class="warning">Title Link Blocked</span> (are you using NoScript?)</a>') %>
|
||||
return
|
||||
|
||||
cb:
|
||||
@ -239,7 +238,7 @@ Linkify =
|
||||
key: 'gist'
|
||||
regExp: /.*(?:gist.github.com.*\/)([^\/][^\/]*)$/
|
||||
el: (a) ->
|
||||
div = $.el 'iframe',
|
||||
$.el 'iframe',
|
||||
# Github doesn't allow embedding straight from the site, so we use an external site to bypass that.
|
||||
src: "http://www.purplegene.com/script?url=https://gist.github.com/#{a.dataset.uid}.js"
|
||||
title:
|
||||
@ -251,10 +250,7 @@ Linkify =
|
||||
regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/
|
||||
style: 'border: 0; width: auto; height: auto;'
|
||||
el: (a) ->
|
||||
el = $.el 'div'
|
||||
el.innerHTML = '<a target="_blank"><img></a>'
|
||||
el.firstChild.href = el.firstChild.firstChild.src = a.href
|
||||
el
|
||||
$.el 'div', <%= html('<a target="_blank" href="${a.href}"><img src="${a.href}"></a>') %>
|
||||
,
|
||||
key: 'InstallGentoo'
|
||||
regExp: /.*(?:paste.installgentoo.com\/view\/)([0-9a-z_]+)/
|
||||
@ -297,17 +293,13 @@ Linkify =
|
||||
return div.textContent = "ERROR: Not a valid filetype" unless embed
|
||||
switch embed.type
|
||||
when 'video/mp4', 'video/webm', 'video/ogv'
|
||||
el.innerHTML = '<video autoplay loop><source type="video/mp4"><source type="video/webm"><source type="video/ogg"></video>'
|
||||
for ext, i in ['mp4', 'webm', 'ogv']
|
||||
$.extend el, <%= html('<video autoplay loop><source type="video/mp4"><source type="video/webm"></video>') %>
|
||||
for ext, i in ['mp4', 'webm']
|
||||
el.firstChild.children[i].src = "https://mediacru.sh/#{a.dataset.uid}.#{ext}"
|
||||
when 'image/svg+xml', 'image/png', 'image/gif', 'image/jpeg'
|
||||
el.innerHTML = '<a target="_blank"><img></a>'
|
||||
el.firstChild.href = a.href
|
||||
el.firstChild.firstChild.src = "https://mediacru.sh/#{file.file}"
|
||||
$.extend el, <%= html('<a target="_blank" href="${a.href}"><img src="https://mediacru.sh/${file.file}"></a>') %>
|
||||
when 'audio/mpeg', 'audio/ogg'
|
||||
el.innerHTML = '<audio controls><source type="audio/ogg"><source type="audio/mpeg"></audio>'
|
||||
for ext, i in ['ogg', 'mp3']
|
||||
el.firstChild.children[i].src = "https://mediacru.sh/#{a.dataset.uid}.#{ext}"
|
||||
$.extend el, <%= html('<audio controls><source type="audio/ogg" src="https://mediacru.sh/${a.dataset.uid}.ogg"></audio>') %>
|
||||
else
|
||||
el.textContent = "ERROR: No valid filetype."
|
||||
el
|
||||
@ -350,14 +342,14 @@ Linkify =
|
||||
idparam = {'b': 'archive_id', 'c': 'chapter_id'}
|
||||
obj = $.el 'object',
|
||||
data: 'http://www.twitch.tv/widgets/archive_embed_player.swf'
|
||||
obj.innerHTML = '<param name="allowFullScreen" value="true"><param name="flashvars">'
|
||||
$.extend obj, <%= html('<param name="allowFullScreen" value="true"><param name="flashvars">') %>
|
||||
obj.children[1].value = "channel=#{channel}&start_volume=25&auto_play=false&#{idparam[type]}=#{id}"
|
||||
obj
|
||||
else
|
||||
channel = (/(\w+)/.exec a.dataset.uid)[0]
|
||||
obj = $.el 'object',
|
||||
data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=#{channel}"
|
||||
obj.innerHTML = '<param name="allowFullScreen" value="true"><param name="flashvars">'
|
||||
$.extend obj, <%= html('<param name="allowFullScreen" value="true"><param name="flashvars">') %>
|
||||
obj.children[1].value = "hostname=www.twitch.tv&channel=#{channel}&auto_play=true&start_volume=25"
|
||||
obj
|
||||
,
|
||||
|
||||
@ -16,8 +16,8 @@ Menu =
|
||||
makeButton: do ->
|
||||
a = $.el 'a',
|
||||
className: 'menu-button'
|
||||
innerHTML: '<i class="fa fa-angle-down"></i>'
|
||||
href: 'javascript:;'
|
||||
$.extend a, <%= html('<i class="fa fa-angle-down"></i>') %>
|
||||
->
|
||||
button = a.cloneNode true
|
||||
$.on button, 'click', Menu.toggle
|
||||
|
||||
@ -22,10 +22,9 @@ PSAHiding =
|
||||
$.on entry.el, 'click', PSAHiding.toggle
|
||||
|
||||
PSAHiding.btn = btn = $.el 'span',
|
||||
innerHTML: '[<a href="javascript:;">Dismiss</a>]'
|
||||
title: 'Mark announcement as read and hide.'
|
||||
className: 'hide-announcement'
|
||||
href: 'javascript:;'
|
||||
$.extend btn, <%= html('[<a href="javascript:;">Dismiss</a>]') %>
|
||||
$.on btn, 'click', PSAHiding.toggle
|
||||
|
||||
$.get 'hiddenPSA', 0, ({hiddenPSA}) ->
|
||||
|
||||
@ -7,58 +7,34 @@ FileInfo =
|
||||
cb: @node
|
||||
node: ->
|
||||
return if !@file or @isClone
|
||||
@file.text.innerHTML = '<span class="file-info"></span>'
|
||||
$.extend @file.text, <%= html('<span class="file-info"></span>') %>
|
||||
FileInfo.format Conf['fileInfo'], @, @file.text.firstElementChild
|
||||
format: (formatString, post, outputNode) ->
|
||||
FileInfo.innerHTML = ''
|
||||
output = []
|
||||
formatString.replace /%(.)|[^%]+/g, (s, c) ->
|
||||
if c of FileInfo.formatters
|
||||
output.push if c of FileInfo.formatters
|
||||
FileInfo.formatters[c].call post
|
||||
else
|
||||
FileInfo.innerHTML += E s
|
||||
<%= html('${s}') %>
|
||||
''
|
||||
outputNode.innerHTML = FileInfo.innerHTML
|
||||
$.extend outputNode, <%= html('@{output}') %>
|
||||
formatters:
|
||||
t: ->
|
||||
timestamp = @file.URL.match(/\d+\..+$/)[0]
|
||||
FileInfo.innerHTML += E timestamp
|
||||
T: ->
|
||||
FileInfo.innerHTML += "<a href='#{E @file.URL}' target='_blank'>"
|
||||
FileInfo.formatters.t.call @
|
||||
FileInfo.innerHTML += '</a>'
|
||||
l: ->
|
||||
FileInfo.innerHTML += "<a href='#{E @file.URL}' target='_blank'>"
|
||||
FileInfo.formatters.n.call @
|
||||
FileInfo.innerHTML += '</a>'
|
||||
L: ->
|
||||
FileInfo.innerHTML += "<a href='#{E @file.URL}' target='_blank'>"
|
||||
FileInfo.formatters.N.call @
|
||||
FileInfo.innerHTML += '</a>'
|
||||
t: -> <%= html('${@file.URL.match(/\\d+\\..+$/)[0]}') %>
|
||||
T: -> <%= html('<a href="${@file.URL}" target="_blank">&{FileInfo.formatters.t.call @}</a>') %>
|
||||
l: -> <%= html('<a href="${@file.URL}" target="_blank">&{FileInfo.formatters.n.call @}</a>') %>
|
||||
L: -> <%= html('<a href="${@file.URL}" target="_blank">&{FileInfo.formatters.N.call @}</a>') %>
|
||||
n: ->
|
||||
fullname = @file.name
|
||||
shortname = Build.shortFilename @file.name, @isReply
|
||||
if fullname is shortname
|
||||
FileInfo.innerHTML += E fullname
|
||||
<%= html('${fullname}') %>
|
||||
else
|
||||
FileInfo.innerHTML += "<span class='fnswitch'><span class='fntrunc'>#{E shortname}</span><span class='fnfull'>#{E fullname}</span></span>"
|
||||
N: ->
|
||||
FileInfo.innerHTML += E @file.name
|
||||
p: ->
|
||||
if @file.isSpoiler
|
||||
FileInfo.innerHTML += 'Spoiler, '
|
||||
s: ->
|
||||
FileInfo.innerHTML += E @file.size
|
||||
B: ->
|
||||
sizeB = Math.round(@file.sizeInBytes)
|
||||
FileInfo.innerHTML += "#{+sizeB} Bytes"
|
||||
K: ->
|
||||
sizeKB = Math.round(@file.sizeInBytes/1024)
|
||||
FileInfo.innerHTML += "#{+sizeKB} KB"
|
||||
M: ->
|
||||
sizeMB = Math.round(@file.sizeInBytes/1048576*100)/100
|
||||
FileInfo.innerHTML += "#{+sizeMB} MB"
|
||||
r: ->
|
||||
dim = @file.dimensions or 'PDF'
|
||||
FileInfo.innerHTML += E dim
|
||||
'%': ->
|
||||
FileInfo.innerHTML += '%'
|
||||
<%= html('<span class="fnswitch"><span class="fntrunc">${shortname}</span><span class="fnfull">${fullname}</span></span>') %>
|
||||
N: -> <%= html('${@file.name}') %>
|
||||
p: -> if @file.isSpoiler then <%= html('Spoiler, ') %> else <%= html('') %>
|
||||
s: -> <%= html('${@file.size}') %>
|
||||
B: -> <%= html('${Math.round @file.sizeInBytes} Bytes') %>
|
||||
K: -> <%= html('${Math.round(@file.sizeInBytes/1024)} KB') %>
|
||||
M: -> <%= html('${Math.round(@file.sizeInBytes/1048576*100)/100} MB') %>
|
||||
r: -> <%= html('${@file.dimensions or "PDF"}') %>
|
||||
'%': -> <%= html('%') %>
|
||||
|
||||
@ -2,16 +2,19 @@ ThreadStats =
|
||||
init: ->
|
||||
return if g.VIEW isnt 'thread' or !Conf['Thread Stats']
|
||||
|
||||
countHTML = <%= html('<span id="post-count">0</span> / <span id="file-count">0</span>') %>
|
||||
countHTML = <%= html('&{countHTML} / <span id="file-count">0</span>') %> if Conf['Page Count in Stats']
|
||||
|
||||
if Conf['Updater and Stats in Header']
|
||||
@dialog = sc = $.el 'span',
|
||||
innerHTML: "<span id='post-count'>0</span> / <span id='file-count'>0</span>#{if Conf['Page Count in Stats'] then ' / <span id="page-count">0</span>' else ''}"
|
||||
id: 'thread-stats'
|
||||
title: 'Post Count / File Count' + (if Conf["Page Count in Stats"] then " / Page Count" else "")
|
||||
$.extend sc, countHTML
|
||||
$.ready ->
|
||||
Header.addShortcut sc
|
||||
else
|
||||
@dialog = sc = UI.dialog 'thread-stats', 'bottom: 0px; right: 0px;',
|
||||
innerHTML: "<div class='move' title='Post Count / File Count#{if Conf['Page Count in Stats'] then ' / Page Count' else ''}'><span id='post-count'>0</span> / <span id='file-count'>0</span>#{if Conf['Page Count in Stats'] then ' / <span id="page-count">0</span>' else ''}</div>"
|
||||
<%= html('<div class="move" title="Post Count / File Count${if Conf["Page Count in Stats"] then " / Page Count" else ""}">&{countHTML}</div>') %>
|
||||
$.ready =>
|
||||
$.add d.body, sc
|
||||
|
||||
|
||||
@ -4,13 +4,13 @@ ThreadUpdater =
|
||||
|
||||
if Conf['Updater and Stats in Header']
|
||||
@dialog = sc = $.el 'span',
|
||||
innerHTML: '<span id="update-status"></span><span id="update-timer" title="Update now"></span>'
|
||||
id: 'updater'
|
||||
$.extend sc, <%= html('<span id="update-status"></span><span id="update-timer" title="Update now"></span>') %>
|
||||
$.ready ->
|
||||
Header.addShortcut sc
|
||||
else
|
||||
@dialog = sc = UI.dialog 'updater', 'bottom: 0px; left: 0px;',
|
||||
innerHTML: '<div class="move"></div><span id="update-status"></span><span id="update-timer" title="Update now"></span>'
|
||||
<%= html('<div class="move"></div><span id="update-status"></span><span id="update-timer" title="Update now"></span>') %>
|
||||
$.addClass doc, 'float'
|
||||
$.ready =>
|
||||
$.addClass doc, 'float'
|
||||
@ -26,8 +26,8 @@ ThreadUpdater =
|
||||
$.on @status, 'click', @update
|
||||
|
||||
updateLink = $.el 'span',
|
||||
innerHTML: '<a href="javascript:;">Update</a>'
|
||||
className: 'brackets-wrap updatelink'
|
||||
$.extend updateLink, <%= html('<a href="javascript:;">Update</a>') %>
|
||||
$.ready ->
|
||||
$.add $('.navLinksBot'), [$.tn(' '), updateLink]
|
||||
$.on updateLink.firstElementChild, 'click', @update
|
||||
@ -46,7 +46,7 @@ ThreadUpdater =
|
||||
subEntries.push el: el
|
||||
|
||||
@settings = $.el 'span',
|
||||
innerHTML: '<a href="javascript:;">Interval</a>'
|
||||
<%= html('<a href="javascript:;">Interval</a>') %>
|
||||
|
||||
$.on @settings, 'click', @intervalShortcut
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ ThreadWatcher =
|
||||
className: 'disabled fa fa-eye'
|
||||
|
||||
@db = new DataBoard 'watchedThreads', @refresh, true
|
||||
@dialog = UI.dialog 'thread-watcher', 'top: 50px; left: 0px;', innerHTML: <%= importHTML('Monitoring/ThreadWatcher') %>
|
||||
@dialog = UI.dialog 'thread-watcher', 'top: 50px; left: 0px;', <%= importHTML('Monitoring/ThreadWatcher') %>
|
||||
@status = $ '#watcher-status', @dialog
|
||||
@list = @dialog.lastElementChild
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ QR.captcha =
|
||||
imgContainer = $.el 'div',
|
||||
className: 'captcha-img'
|
||||
title: 'Reload reCAPTCHA'
|
||||
innerHTML: '<img>'
|
||||
$.extend imgContainer, <%= html('<img>') %>
|
||||
input = $.el 'input',
|
||||
className: 'captcha-input field'
|
||||
title: 'Verification'
|
||||
|
||||
@ -45,9 +45,9 @@ QR =
|
||||
return unless QR.postingIsEnabled
|
||||
|
||||
link = $.el 'h1',
|
||||
innerHTML: "<a href='javascript:;' class='qr-link'>#{if g.VIEW is 'thread' then 'Reply to Thread' else 'Start a Thread'}</a>"
|
||||
className: "qr-link-container"
|
||||
|
||||
$.extend link, <%= html('<a href="javascript:;" class="qr-link">${if g.VIEW is "thread" then "Reply to Thread" else "Start a Thread"}</a>') %>
|
||||
|
||||
QR.link = link.firstElementChild
|
||||
$.on link.firstChild, 'click', ->
|
||||
$.event 'CloseMenu'
|
||||
@ -58,8 +58,8 @@ QR =
|
||||
|
||||
if Conf['Bottom QR Link'] and g.VIEW is 'thread'
|
||||
linkBot = $.el 'div',
|
||||
innerHTML: '<a href="javascript:;" class="qr-link-bottom">Reply to Thread</a>'
|
||||
className: "brackets-wrap qr-link-container-bottom"
|
||||
$.extend linkBot, <%= html('<a href="javascript:;" class="qr-link-bottom">Reply to Thread</a>') %>
|
||||
|
||||
$.on linkBot.firstElementChild, 'click', ->
|
||||
$.event 'CloseMenu'
|
||||
@ -422,7 +422,7 @@ QR =
|
||||
|
||||
dialog: ->
|
||||
QR.nodes = nodes =
|
||||
el: dialog = UI.dialog 'qr', 'top:0;right:0;', innerHTML: <%= importHTML('Features/QuickReply') %>
|
||||
el: dialog = UI.dialog 'qr', 'top:0;right:0;', <%= importHTML('Features/QuickReply') %>
|
||||
|
||||
setNode = (name, query) ->
|
||||
nodes[name] = $ query, dialog
|
||||
@ -484,17 +484,16 @@ QR =
|
||||
nodes.spoiler.parentElement.hidden = true
|
||||
|
||||
if g.BOARD.ID is 'f' and g.VIEW isnt 'thread'
|
||||
nodes.flashTag = $.el 'select',
|
||||
name: 'filetag'
|
||||
innerHTML: '''
|
||||
<option value=0>Hentai</option>
|
||||
<option value=6>Porn</option>
|
||||
<option value=1>Japanese</option>
|
||||
<option value=2>Anime</option>
|
||||
<option value=3>Game</option>
|
||||
<option value=5>Loop</option>
|
||||
<option value=4 selected>Other</option>
|
||||
'''
|
||||
nodes.flashTag = $.el 'select', name: 'filetag'
|
||||
$.extend nodes.flashTag, <%= html(
|
||||
'<option value="0">Hentai</option>' +
|
||||
'<option value="6">Porn</option>' +
|
||||
'<option value="1">Japanese</option>' +
|
||||
'<option value="2">Anime</option>' +
|
||||
'<option value="3">Game</option>' +
|
||||
'<option value="5">Loop</option>' +
|
||||
'<option value="4" selected>Other</option>'
|
||||
) %>
|
||||
nodes.flashTag.dataset.default = '4'
|
||||
$.add nodes.form, nodes.flashTag
|
||||
|
||||
@ -682,10 +681,11 @@ QR =
|
||||
QR.cooldown.auto = false
|
||||
QR.status()
|
||||
QR.error $.el 'span',
|
||||
innerHTML: '''
|
||||
4chan X encountered an error while posting.
|
||||
[<a href="//4chan.org/banned" target="_blank">Banned?</a>] [<a href="<%= meta.faq %>#what-does-4chan-x-encountered-an-error-while-posting-please-try-again-mean" target="_blank">More info</a>]
|
||||
'''
|
||||
<%= html(
|
||||
'4chan X encountered an error while posting. ' +
|
||||
'[<a href="//4chan.org/banned" target="_blank">Banned?</a>] ' +
|
||||
'[<a href="${g.FAQ}#what-does-4chan-x-encountered-an-error-while-posting-please-try-again-mean" target="_blank">More info</a>]'
|
||||
) %>
|
||||
extra =
|
||||
form: $.formData formData
|
||||
upCallbacks:
|
||||
@ -718,9 +718,9 @@ QR =
|
||||
if ban = $ '.banType', resDoc # banned/warning
|
||||
err = $.el 'span',
|
||||
if ban.textContent.toLowerCase() is 'banned'
|
||||
innerHTML: "You are banned on #{$('.board', resDoc).innerHTML}! ;_;<br>Click <a href='//www.4chan.org/banned' target='_blank'>here</a> to see the reason."
|
||||
<%= html('You are banned on &{$(".board", resDoc)}! ;_;<br>Click <a href="//www.4chan.org/banned" target="_blank">here</a> to see the reason.') %>
|
||||
else
|
||||
innerHTML: "You were issued a warning on #{$('.board', resDoc).innerHTML} as #{$('.nameBlock', resDoc).innerHTML}.<br>Reason: #{$('.reason', resDoc).innerHTML}"
|
||||
<%= html('You were issued a warning on &{$(".board", resDoc)} as &{$(".nameBlock", resDoc)}.<br>Reason: &{$(".reason", resDoc)}') %>
|
||||
else if err = resDoc.getElementById 'errmsg' # error!
|
||||
$('a', err)?.target = '_blank' # duplicate image link
|
||||
else if resDoc.title isnt 'Post successful!'
|
||||
|
||||
@ -4,7 +4,7 @@ QR.post = class
|
||||
className: 'qr-preview'
|
||||
draggable: true
|
||||
href: 'javascript:;'
|
||||
innerHTML: '<a class="remove fa fa-times-circle" title="Remove"></a><label hidden><input type="checkbox"> Spoiler</label><span></span>'
|
||||
$.extend el, <%= html('<a class="remove fa fa-times-circle" title="Remove"></a><label hidden><input type="checkbox"> Spoiler</label><span></span>') %>
|
||||
|
||||
@nodes =
|
||||
el: el
|
||||
|
||||
@ -8,7 +8,7 @@ QuoteThreading =
|
||||
|
||||
@enabled = true
|
||||
@controls = $.el 'span',
|
||||
innerHTML: '<label><input id="threadingControl" type="checkbox" checked> Threading</label>'
|
||||
<%= html('<label><input id="threadingControl" type="checkbox" checked> Threading</label>') %>
|
||||
|
||||
input = $ 'input', @controls
|
||||
$.on input, 'change', @toggle
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user