Start bolting on Appchan X

Broken as shit.
This commit is contained in:
Zixaphir 2013-03-19 10:56:11 -07:00
parent 6d59cc03f1
commit d09ab8a19f
7 changed files with 650 additions and 123 deletions

View File

@ -16,6 +16,7 @@ module.exports = (grunt) ->
'lib/ui.coffee'
'lib/$.coffee'
'lib/polyfill.coffee'
'src/appchan.coffee'
'src/features.coffee'
'src/qr.coffee'
'src/report.coffee'

View File

@ -1,7 +1,7 @@
// ==UserScript==
// @name 4chan X Beta
// @version 3.0.0
// @namespace 4chan-X
// @name appchan-x
// @version 2.0.0
// @namespace appchan-x
// @description Cross-browser userscript for maximum lurking on 4chan.
// @copyright 2009-2011 James Campos <james.r.campos@gmail.com>
// @copyright 2012-2013 Nicolas Stepien <stepien.nicolas@gmail.com>
@ -15,7 +15,7 @@
// @grant GM_deleteValue
// @grant GM_openInTab
// @run-at document-start
// @updateURL https://github.com/MayhemYDG/4chan-x/raw/v3/4chan-X.meta.js
// @downloadURL https://github.com/MayhemYDG/4chan-x/raw/v3/4chan-X.user.js
// @updateURL https://github.com/zixaphir/appchan-x/raw/Av2/appchan-x.meta.js
// @downloadURL https://github.com/zixaphir/appchan-x/raw/Av2/appchan-x.user.js
// @icon data:image/gif;base64,R0lGODlhEAAQAKECAAAAAGbMM////////yH5BAEKAAIALAAAAAAQABAAAAIxlI+pq+D9DAgUoFkPDlbs7lGiI2bSVnKglnJMOL6omczxVZK3dH/41AG6Lh7i6qUoAAA7
// ==/UserScript==

File diff suppressed because one or more lines are too long

View File

@ -1,12 +1,12 @@
{
"name": "4chan-X",
"version": "3.0.0",
"description": "Cross-browser userscript for maximum lurking on 4chan.",
"name": "appchan-x",
"version": "2.0.0",
"description": "The most comprehensive 4chan userscript.",
"meta": {
"name": "4chan X Beta",
"repo": "https://github.com/MayhemYDG/4chan-x/",
"page": "http://mayhemydg.github.com/4chan-x/",
"mainBranch": "v3",
"name": "appchan-x",
"repo": "https://github.com/zixaphir/appchan-x/",
"page": "http://zixaphir.github.com/appchan-x/",
"mainBranch": "Av2",
"matches": [
"*://api.4chan.org/*",
"*://boards.4chan.org/*",
@ -25,10 +25,11 @@
},
"repository": {
"type": "git",
"url": "git://github.com/MayhemYDG/4chan-x.git"
"url": "git://github.com/zixaphir/appchan-x.git"
},
"author": "Nicolas Stepien <stepien.nicolas@gmail.com>",
"author": "Zixaphir <zixaphirmoxphar@gmail.com>",
"contributors": [
"Nicolas Stepien <stepien.nicolas@gmail.com>",
"James Campos <james.r.campos@gmail.com>"
],
"license": "MIT",

266
src/appchan.coffee Normal file
View File

@ -0,0 +1,266 @@
Style =
init: ->
@agent = {
'gecko': '-moz-'
'webkit': '-webkit-'
'presto': '-o-'
}[$.engine]
@sizing = "#{if $.engine is 'gecko' then @agent else ''}box-sizing"
$.ready ->
return unless $.id 'navtopright'
Style.padding.nav = $ "#boardNavDesktop", d.body
Style.padding.pages = $(".pagelist", d.body)
Style.padding()
$.on window, "resize", Style.padding
# Give ExLinks and 4sight a little time to append their dialog links
setTimeout (->
Style.iconPositions()
if exLink = $ "#navtopright .exlinksOptionsLink", d.body
$.on exLink, "click", ->
setTimeout Style.rice, 100
), 500
Main.callbacks.push @node
@setup()
setup: ->
if d.head
@addStyleReady()
@remStyle()
unless Style.headCount
return @cleanup()
@observe()
observe: ->
if MutationObserver
Style.observer = new MutationObserver onMutationObserver = @wrapper
Style.observer.observe d,
childList: true
subtree: true
else
$.on d, 'DOMNodeInserted', @wrapper
wrapper: ->
if d.head
if Style.addStyleReady
Style.addStyleReady()
Style.remStyle()
if not Style.headCount or d.readyState is 'complete'
if Style.observer
Style.observer.disconnect()
else
$.off d, 'DOMNodeInserted', Style.wrapper
Style.cleanup()
cleanup: ->
delete Style.observe
delete Style.wrapper
delete Style.remStyle
delete Style.headCount
delete Style.cleanup
addStyle: (theme) ->
_conf = Conf
unless theme
theme = Themes[_conf['theme']]
MascotTools.init _conf["mascot"]
Style.layoutCSS.textContent = Style.layout()
Style.themeCSS.textContent = Style.theme(theme)
Style.iconPositions()
headCount: 12
addStyleReady: ->
theme = Themes[Conf['theme']]
$.extend Style,
layoutCSS: $.addStyle Style.layout(), 'layout'
themeCSS: $.addStyle Style.theme(theme), 'theme'
icons: $.addStyle "", 'icons'
paddingSheet: $.addStyle "", 'padding'
mascot: $.addStyle "", 'mascotSheet'
# Non-customizable
$.addStyle Style.jsColorCSS(), 'jsColor'
delete Style.addStyleReady
remStyle: ->
nodes = d.head.children
i = nodes.length
while i--
break unless Style.headCount
node = nodes[i]
if (node.nodeName is 'STYLE' and !node.id) or ("#{node.rel}".contains('stylesheet') and node.href[..3] isnt 'data')
Style.headCount--
$.rm node
continue
return
filter: (text, background) ->
matrix = (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}
"
fgHex = Style.colorToHex text
bgHex = Style.colorToHex background
string = matrix {
r: parseInt(fgHex.substr(0, 2), 16) / 255
g: parseInt(fgHex.substr(2, 2), 16) / 255
b: parseInt(fgHex.substr(4, 2), 16) / 255
}, {
r: parseInt(bgHex.substr(0, 2), 16) / 255
g: parseInt(bgHex.substr(2, 2), 16) / 255
b: parseInt(bgHex.substr(4, 2), 16) / 255
}
return "filter: url(\"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><filter id='filters' color-interpolation-filters='sRGB'><feColorMatrix values='#{string} 0 0 0 1 0' /></filter></svg>#filters\");"
Banner =
init: ->
$.asap (-> doc), ->
$.asap (-> $ '.abovePostForm'), Banner.ready
ready: ->
banner = $ ".boardBanner"
title = $.el "div",
id: "boardTitle"
children = banner.children
i = children.length
nodes = []
while i--
child = children[i]
if child.tagName.toLowerCase() is "img"
child.id = "Banner"
continue
if Conf['Custom Board Titles']
cachedTest = child.innerHTML
if not Conf['Persistent Custom Board Titles'] or cachedTest is $.get "#{g.BOARD}.#{child.className}.orig", cachedTest
child.innerHTML = $.get "#{g.BOARD}.#{child.className}", cachedTest
else
$.set "#{g.BOARD}.#{child.className}.orig", cachedTest
$.set "#{g.BOARD}.#{child.className}", cachedTest
$.on child, 'click', (e) ->
if e.shiftKey
@contentEditable = true
$.on child, 'keydown', (e) ->
e.stopPropagation()
$.on child, 'focus', ->
@textContent = @innerHTML
$.on child, 'blur', ->
$.set "#{g.BOARD}.#{@className}", @textContent
@innerHTML = @textContent
@contentEditable = false
nodes.push child
$.add title, nodes.reverse()
$.after banner, title
return
GlobalMessage =
init: ->
$.asap (-> doc), ->
$.asap (-> $.id 'delform'), GlobalMessage.ready
ready: ->
if el = $ "#globalMessage", d.body
for child in el.children
child.cssText = ""
return
Rice =
init: ->
$.ready ->
Rice.nodes d.body
checkclick: ->
@check.click()
selectclick: ->
e.stopPropagation()
if Rice.ul
return Rice.remSelect()
rect = @getBoundingClientRect()
{clientHeight} = d.documentElement
ul = Rice.ul = $.el 'ul',
id: "selectrice"
{style} = ul
style.width = "#{rect.width}px"
if clientHeight - rect.bottom < 200
style.bottom = "#{clientHeight - rect.top}px"
else
style.top = "#{rect.bottom}px"
style.left = "#{rect.left}px"
input = @previousSibling
for option in input.options
li = $.el 'li',
textContent: option.textContent
li.setAttribute 'data-value', option.value
$.on li, 'click', (e) ->
e.stopPropagation()
container = @parentElement.parentElement
input = container.previousSibling
container.firstChild.textContent = @textContent
input.value = @getAttribute 'data-value'
ev = document.createEvent 'HTMLEvents'
ev.initEvent "change", true, true
$.event input, ev
Rice.remSelect()
$.add ul, li
$.on ul, 'click scroll blur', (e) ->
e.stopPropagation()
$.on d, 'click scroll blur resize', Rice.remSelect
$.add @, ul
remSelect: ->
$.off d, 'click scroll blur resize', Rice.remSelect
$.rm Rice.ul
delete Rice.ul
nodes: (source) ->
checkboxes = $$('[type=checkbox]:not(.riced)', source)
checkrice = Rice.checkbox
for input in checkboxes
checkrice input
selects = $$('select:not(.riced)', source)
selectrice = Rice.select
for input in selects
selectrice input
return
node: ->
Rice.checkbox $ '.postInfo input', @
checkbox: (input) ->
return if $.hasClass input, 'riced'
$.addClass input, 'riced'
div = $.el 'div',
className: 'rice'
div.check = input
$.after input, div
if div.parentElement.tagName.toLowerCase() != 'label'
$.on div, 'click', Rice.click
select: (input) ->
$.addClass input, 'riced'
div = $.el 'div',
className: 'selectrice'
innerHTML: "<div>#{input.options[input.selectedIndex].textContent or null}</div>"
$.on div, "click", (e),
$.after input, div

View File

@ -118,6 +118,7 @@ class Notification
CatalogLinks =
init: ->
$.ready @ready
return unless Conf['Catalog Links']
el = $.el 'a',
id: 'toggleCatalog'
@ -163,6 +164,12 @@ CatalogLinks =
"//boards.4chan.org/#{board}/catalog"
)
ready: ->
if catalogLink = ($('.pages.cataloglink a', d.body) or $ '[href=".././catalog"]', d.body)
if !g.VIEW is thread
$.add d.body, catalogLink
catalogLink.id = 'catalog'
Settings =
init: ->
# 4chan X settings link

View File

@ -391,42 +391,8 @@ Main =
# c.timeEnd 'All initializations'
$.on d, 'AddCallback', Main.addCallback
$.on d, '4chanMainInit', Main.initStyle
$.ready Main.initReady
initStyle: ->
return unless Main.isThisPageLegit()
# disable the mobile layout
$('link[href*=mobile]', d.head)?.disabled = true
$.addClass doc, $.engine
$.addClass doc, 'fourchan-x'
$.addStyle Main.css
if g.VIEW is 'catalog'
$.addClass doc, $.id('base-css').href.match(/catalog_(\w+)/)[1].replace('_new', '').replace /_+/g, '-'
return
style = 'yotsuba-b'
mainStyleSheet = $ 'link[title=switch]', d.head
styleSheets = $$ 'link[rel="alternate stylesheet"]', d.head
setStyle = ->
$.rmClass doc, style
for styleSheet in styleSheets
if styleSheet.href is mainStyleSheet.href
style = styleSheet.title.toLowerCase().replace('new', '').trim().replace /\s+/g, '-'
break
$.addClass doc, style
setStyle()
return unless mainStyleSheet
if MutationObserver = window.MutationObserver or window.WebKitMutationObserver or window.OMutationObserver
observer = new MutationObserver setStyle
observer.observe mainStyleSheet,
attributes: true
attributeFilter: ['href']
else
# XXX this doesn't seem to work?
$.on mainStyleSheet, 'DOMAttrModified', setStyle
initReady: ->
if d.title is '4chan - 404 Not Found'
if Conf['404 Redirect'] and g.VIEW is 'thread'
@ -536,14 +502,5 @@ Main =
Main.thisPageIsLegit = !$('link[href*="favicon-status.ico"]', d.head) and d.title isnt '4chan - Temporarily Offline'
Main.thisPageIsLegit
css: """
<%= grunt.file.read('css/style.css') %>
<%= grunt.file.read('css/yotsuba.css') %>
<%= grunt.file.read('css/yotsuba-b.css') %>
<%= grunt.file.read('css/futaba.css') %>
<%= grunt.file.read('css/burichan.css') %>
<%= grunt.file.read('css/tomorrow.css') %>
<%= grunt.file.read('css/photon.css') %>
"""
Main.init()