4chan-x/src/Theming/Style.coffee
2014-02-16 04:16:33 -07:00

195 lines
5.8 KiB
CoffeeScript

Style =
sheets: {}
init: ->
Style.svgs = {
<% if (type === 'crx') { %>
el: $.el 'div',
id: 'svg_filters'
<% } %>
}
theme = Themes[Conf[g.THEMESTRING]] or Themes['Yotsuba B']
items = [
['layout', Style.layout]
['theme', Style.theme theme]
['emoji', Emoji.css()]
['dynamic', Style.dynamic()]
['padding', ""]
['mascots', ""]
]
i = 0
while item = items[i++]
Style.sheets[item[0]] = $.addStyle item[1], item[0]
# Non-customizable
$.addStyle JSColor.css(), 'jsColor'
$.asap (-> d.head), Style.observe
$.asap (-> d.body), @asapInit
$.asap (-> Header.bar.parentElement), Style.padding
$.on window, "resize", Style.padding
$.ready @readyInit
asapInit: ->
<% if (type === 'crx') { %>
$.addClass doc, 'blink'
<% } else { %>
$.addClass doc, 'gecko'
<% } %>
$.addClass doc, 'fourchan-x'
$.addClass doc, 'appchan-x'
$.addClass doc, g.VIEW
<% if (type === 'crx') { %>
$.add d.body, Style.svgs.el
<% } %>
for title, cat of Config.style
for name, setting of cat
continue if !Conf[name] or setting[2] is 'text' or name in ['NSFW/SFW Themes', 'NSFW/SFW Mascots']
hyphenated = "#{name}#{if setting[2] then " #{Conf[name]}" else ""}".toLowerCase().replace(/^4/, 'four').replace /\s+/g, '-'
$.addClass doc, hyphenated
return
readyInit: ->
Style.iconPositions()
if exLink = $ "#navtopright .exlinksOptionsLink", d.body
$.on exLink, "click", ->
setTimeout Rice.nodes, 100
observe: ->
Style.observer = new MutationObserver onMutationObserver = Style.wrapper
Style.observer.observe d.head,
childList: true
subtree: true
wrapper: ->
first = {addedNodes: d.head.children}
Style.remStyle first
if d.readyState is 'complete'
Style.observer.disconnect()
remStyle: ({addedNodes}) ->
i = addedNodes.length
while i--
{nodeName, rel, id, href, textContent} = node = addedNodes[i]
if nodeName is 'STYLE'
continue if id or /\.typeset/.test textContent
else if nodeName is 'LINK'
continue if rel and (!/stylesheet/.test(rel) or /flags.*\.css$/.test(href) or href[..3] is 'data')
else
continue
$.rm node
return
generateFilter: (id, values) -> """<%= grunt.file.read('src/General/html/Features/Filters.svg').replace(/>\s+</g, '><') %>"""
matrix: ->
colors = []
rgb = ['r', 'g', 'b']
for arg in arguments
hex = (new Color arg).raw
color = {}
i = 0
while val = rgb[i]
color[val] = parseInt(hex.substr((2 * i++), 2), 16) / 255
colors.push color
colors
filter: ([fg, bg]) ->
"#{bg.r} #{-fg.r} 0 0 #{fg.r} #{bg.g} #{-fg.g} 0 0 #{fg.g} #{bg.b} #{-fg.b} 0 0 #{fg.b}"
silhouette: ([fg]) ->
"0 0 0 0 #{fg.r} 0 0 0 0 #{fg.g} 0 0 0 0 #{fg.b}"
layout: """<%=
grunt.file.read('src/General/css/layout.css').replace(/\s+/g, ' ').trim()
+ ' ' +
grunt.file.read('src/General/css/font-awesome.css').replace(/\s+/g, ' ').replace(/\\/g, '\\\\').trim()
%>"""
dynamic: ->
sidebarLocation = if Conf["Sidebar Location"] is "left"
["left", "right"]
else
["right", "left" ]
if Conf['editMode'] is "theme"
editSpace = {}
editSpace[sidebarLocation[1]] = 300
editSpace[sidebarLocation[0]] = 0
else
editSpace =
left: 0
right: 0
"""<%= grunt.file.read('src/General/css/dynamic.css').replace(/\s+/g, ' ').trim() %>"""
setTheme: (theme) -> Style.sheets.theme.textContent = Style.theme theme
theme: (theme) ->
bgColor = new Color backgroundC = theme["Background Color"]
replybg = new Color theme["Reply Background"]
replyRGB = "rgb(#{replybg.shiftRGB parseInt(Conf['Silhouette Contrast'], 10), true})"
Style.lightTheme = bgColor.isLight()
svgs = [
['captcha-filter', "values='#{Style.filter Style.matrix theme["Text"], theme["Input Background"]} 0 0 0 1 0'"]
['mascot-filter', "values='#{Style.silhouette Style.matrix replyRGB} 0 0 0 1 0'"]
['grayscale', 'id="color" type="saturate" values="0"']
['icons-filter', "values='-.6 0 0 0 1 0 -.6 0 0 1 0 0 -.6 0 1 0 0 0 1 0'"]
]
for svg, i in svgs
<% if (type === 'crx') { %>
svgs[i] <% } else { %>
Style.svgs[svg[0].replace /\-/, ""] <% } %> = Style.generateFilter svg[0], svg[1]
<% if (type === 'crx') { %>
Style.svgs.el.innerHTML = svgs.join ''
<% } %>
"""<%= grunt.file.read('src/General/css/theme.css').replace(/\s+/g, ' ').trim() %>""" + <%= grunt.file.read('src/General/css/themeoptions.css').replace(/\s+/g, ' ').trim() %>
iconPositions: ->
# Slideout Navigation
slideNav = $.el 'span',
id: 'so-nav'
innerHTML: '<i class=a-icon></a>'
exec = -> if g.VIEW is 'catalog' then $ '#threads .thread' else true
$.asap exec, ->
$.add slideNav, $.id('boardNavDesktopFoot')
Header.addShortcut slideNav, true
# Announcements
if Conf['Announcements'] is 'slideout'
if (psa = $.id 'globalMessage') and !psa.hidden
psaIcon = $.el 'i',
id: 'so-psa'
innerHTML: '<i class=a-icon></a>'
$.add psaIcon, psa
Header.addShortcut psaIcon, true
if g.VIEW is 'thread'
el = $('body > div.navLinks > a')
el.textContent = ''
el.id = 'returnIcon'
el.className = 'a-icon'
Header.addShortcut el, true
padding: ->
navHeight = Header.bar.offsetHeight
pageHeight = ($ '.pagelist', d.body)?.offsetHeight or 15
Style.sheets.padding.textContent = """<%= grunt.file.read('src/General/css/padding.nav.css').replace(/\s+/g, ' ').trim() %> """ +
if pageHeight
"""<%= grunt.file.read('src/General/css/padding.pages.css').replace(/\s+/g, ' ').trim() %>"""
else ''