Start working on the new HTML format.

This commit is contained in:
Nicolas Stepien 2012-04-28 14:54:48 +02:00
parent 77cc33ad75
commit 55cbf0ddf4
2 changed files with 61 additions and 135 deletions

View File

@ -72,7 +72,7 @@
*/ */
(function() { (function() {
var $, $$, Anonymize, AutoGif, Conf, Config, ExpandComment, ExpandThread, Favicon, FileInfo, Filter, GetTitle, ImageExpand, ImageHover, Keybinds, Main, Nav, Options, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, Quotify, Redirect, ReplyHiding, ReportButton, RevealSpoilers, Sauce, StrikethroughQuotes, ThreadHiding, ThreadStats, Threading, Time, TitlePost, UI, Unread, Updater, Watcher, d, g, _base; var $, $$, Anonymize, AutoGif, Conf, Config, ExpandComment, ExpandThread, Favicon, FileInfo, Filter, GetTitle, ImageExpand, ImageHover, Keybinds, Main, Nav, Options, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, Quotify, Redirect, ReplyHiding, ReportButton, RevealSpoilers, Sauce, StrikethroughQuotes, ThreadHiding, ThreadStats, Time, TitlePost, UI, Unread, Updater, Watcher, d, g, _base;
Config = { Config = {
main: { main: {
@ -791,7 +791,6 @@
} }
doc = d.implementation.createHTMLDocument(''); doc = d.implementation.createHTMLDocument('');
doc.documentElement.innerHTML = req.response; doc.documentElement.innerHTML = req.response;
Threading.op($('body > form', doc).firstChild);
node = d.importNode(doc.getElementById(replyID)); node = d.importNode(doc.getElementById(replyID));
quotes = node.getElementsByClassName('quotelink'); quotes = node.getElementsByClassName('quotelink');
for (_i = 0, _len = quotes.length; _i < _len; _i++) { for (_i = 0, _len = quotes.length; _i < _len; _i++) {
@ -1347,7 +1346,7 @@
} }
return $('textarea', QR.el).focus(); return $('textarea', QR.el).focus();
}); });
$.before($('form[name=post]'), link); $.before($.id('postForm'), link);
} }
script = $.el('script', { script = $.el('script', {
textContent: 'Recaptcha.focus_response_field=function(){}' textContent: 'Recaptcha.focus_response_field=function(){}'
@ -1841,7 +1840,7 @@
}); });
ta.style.cssText = $.get('QR.size', ''); ta.style.cssText = $.get('QR.size', '');
} }
mimeTypes = $('.rules').firstChild.textContent.match(/: (.+) /)[1].toLowerCase().replace(/\w+/g, function(type) { mimeTypes = $('ul.rules').firstElementChild.textContent.match(/: (.+) /)[1].toLowerCase().replace(/\w+/g, function(type) {
switch (type) { switch (type) {
case 'jpg': case 'jpg':
return 'image/jpeg'; return 'image/jpeg';
@ -2379,46 +2378,6 @@
} }
}; };
Threading = {
op: function(node) {
var nodes, op;
nodes = [];
while (node.nodeName !== 'BLOCKQUOTE') {
nodes.push(node);
node = node.nextSibling;
}
nodes.push(node);
node = node.nextSibling;
op = $.el('div', {
className: 'op'
});
$.add(op, nodes);
op.id = $('input', op).name;
return $.before(node, op);
},
thread: function(node) {
var div, nodes;
node = Threading.op(node);
if (g.REPLY) {
return;
}
nodes = [];
while (node.nodeName !== 'HR') {
nodes.push(node);
node = node.nextElementSibling;
}
div = $.el('div', {
className: 'thread'
});
$.add(div, nodes);
$.before(node, div);
node = node.nextElementSibling;
if (!(node.align || node.nodeName === 'CENTER')) {
return Threading.thread(node);
}
}
};
ThreadHiding = { ThreadHiding = {
init: function() { init: function() {
var a, hiddenThreads, op, thread, _i, _len, _ref; var a, hiddenThreads, op, thread, _i, _len, _ref;
@ -3078,18 +3037,19 @@
}; };
GetTitle = function(thread) { GetTitle = function(thread) {
var el, span; var el, op, span;
el = $('.filetitle', thread); op = $('.op', thread);
el = $('.subject', op);
if (!el.textContent) { if (!el.textContent) {
el = $('blockquote', thread); el = $('blockquote', op);
if (!el.textContent) { if (!el.textContent) {
el = $('.postername', thread); el = $('.nameBlock', op);
} }
} }
span = $.el('span', { span = $.el('span', {
innerHTML: el.innerHTML.replace(/<br>/g, ' ') innerHTML: el.innerHTML.replace(/<br>/g, ' ')
}); });
return "/" + g.BOARD + "/ - " + span.textContent; return "/" + g.BOARD + "/ - " + (span.textContent.trim());
}; };
TitlePost = { TitlePost = {
@ -3254,7 +3214,7 @@
} }
doc = d.implementation.createHTMLDocument(''); doc = d.implementation.createHTMLDocument('');
doc.documentElement.innerHTML = req.response; doc.documentElement.innerHTML = req.response;
node = id === threadID ? Threading.op($('body > form', doc).firstChild) : doc.getElementById(id); node = doc.getElementById(id);
newInline = QuoteInline.table(id, node.innerHTML); newInline = QuoteInline.table(id, node.innerHTML);
_ref = $$('.quotelink', newInline); _ref = $$('.quotelink', newInline);
for (_i = 0, _len = _ref.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
@ -3355,7 +3315,7 @@
} }
doc = d.implementation.createHTMLDocument(''); doc = d.implementation.createHTMLDocument('');
doc.documentElement.innerHTML = req.response; doc.documentElement.innerHTML = req.response;
node = id === threadID ? Threading.op($('body > form', doc).firstChild) : doc.getElementById(id); node = doc.getElementById(id);
qp.innerHTML = node.innerHTML; qp.innerHTML = node.innerHTML;
post = { post = {
root: qp, root: qp,
@ -3961,7 +3921,6 @@
val = Conf[key]; val = Conf[key];
Conf[key] = $.get(key, val); Conf[key] = $.get(key, val);
} }
$.on(window, 'message', Main.message);
switch (location.hostname) { switch (location.hostname) {
case 'sys.4chan.org': case 'sys.4chan.org':
if (/report/.test(location.search)) { if (/report/.test(location.search)) {
@ -3984,11 +3943,12 @@
} }
$.ready(Options.init); $.ready(Options.init);
if (Conf['Quick Reply'] && Conf['Hide Original Post Form'] && g.BOARD !== 'f') { if (Conf['Quick Reply'] && Conf['Hide Original Post Form'] && g.BOARD !== 'f') {
Main.css += 'form[name=post] { display: none; }'; Main.css += '#postForm { display: none; }';
} }
Main.addStyle(); Main.addStyle();
now = Date.now(); now = Date.now();
if (Conf['Check for Updates'] && $.get('lastUpdate', 0) < now - 6 * $.HOUR) { if (Conf['Check for Updates'] && $.get('lastUpdate', 0) < now - 6 * $.HOUR) {
$.on(window, 'message', Main.message);
$.ready(function() { $.ready(function() {
return $.add(d.head, $.el('script', { return $.add(d.head, $.el('script', {
src: 'https://raw.github.com/mayhemydg/4chan-x/master/latest.js' src: 'https://raw.github.com/mayhemydg/4chan-x/master/latest.js'
@ -4071,7 +4031,7 @@
return $.ready(Main.ready); return $.ready(Main.ready);
}, },
ready: function() { ready: function() {
var MutationObserver, form, nav, node, nodes, observer, _i, _j, _len, _len1, _ref, _ref1; var MutationObserver, a, board, nav, node, nodes, observer, _i, _j, _len, _len1, _ref, _ref1;
if (d.title === '4chan - 404') { if (d.title === '4chan - 404') {
Redirect.init(); Redirect.init();
return; return;
@ -4081,13 +4041,13 @@
} }
$.addClass(d.body, "chanx_" + (Main.version.split('.')[1])); $.addClass(d.body, "chanx_" + (Main.version.split('.')[1]));
$.addClass(d.body, $.engine); $.addClass(d.body, $.engine);
_ref = ['navtop', 'navbot']; _ref = ['boardNavDesktop', 'boardNavDesktopFoot'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
nav = _ref[_i]; nav = _ref[_i];
$.addClass($("a[href$='/" + g.BOARD + "/']", $.id(nav)), 'current'); if (a = $("a[href$='/" + g.BOARD + "/']", $.id(nav))) {
$.addClass(a, 'current');
}
} }
form = $('form[name=delform]');
Threading.thread(form.firstElementChild);
Favicon.init(); Favicon.init();
if (Conf['Quick Reply']) { if (Conf['Quick Reply']) {
QR.init(); QR.init();
@ -4147,8 +4107,9 @@
}); });
} }
} }
board = $('.board');
nodes = []; nodes = [];
_ref1 = $$('.op, a + table', form); _ref1 = $$('.post', board);
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
node = _ref1[_j]; node = _ref1[_j];
nodes.push(Main.preParse(node)); nodes.push(Main.preParse(node));
@ -4156,12 +4117,12 @@
Main.node(nodes, true); Main.node(nodes, true);
if (MutationObserver = window.WebKitMutationObserver || window.MozMutationObserver || window.OMutationObserver || window.MutationObserver) { if (MutationObserver = window.WebKitMutationObserver || window.MozMutationObserver || window.OMutationObserver || window.MutationObserver) {
observer = new MutationObserver(Main.observer); observer = new MutationObserver(Main.observer);
return observer.observe(form, { return observer.observe(board, {
childList: true, childList: true,
subtree: true subtree: true
}); });
} else { } else {
return $.on(form, 'DOMNodeInserted', Main.listener); return $.on(board, 'DOMNodeInserted', Main.listener);
} }
}, },
flatten: function(parent, obj) { flatten: function(parent, obj) {
@ -4196,13 +4157,13 @@
var klass, post; var klass, post;
klass = node.className; klass = node.className;
post = { post = {
root: node, root: node.parentNode,
el: klass === 'op' ? node : node.firstChild.firstChild.lastChild, el: node,
"class": klass, "class": klass,
id: node.getElementsByTagName('input')[0].name, id: node.id.slice(1),
threadId: g.THREAD_ID || $.x('ancestor::div[@class="thread"]', node).firstChild.id, threadId: g.THREAD_ID || $.x('ancestor::div[@class="thread"]', node).id.slice(1),
isInlined: /\binline\b/.test(klass), isInlined: /\binline\b/.test(klass),
filesize: node.getElementsByClassName('filesize')[0] || false, fileinfo: node.getElementsByClassName('fileInfo')[0] || false,
quotes: node.getElementsByClassName('quotelink'), quotes: node.getElementsByClassName('quotelink'),
backlinks: node.getElementsByClassName('backlink') backlinks: node.getElementsByClassName('backlink')
}; };
@ -4275,6 +4236,9 @@ a[href="javascript:;"] {\
display: none;\ display: none;\
}\ }\
\ \
h1 {\
text-align: center;\
}\
.autohide:not(:hover) > form {\ .autohide:not(:hover) > form {\
display: none;\ display: none;\
}\ }\

View File

@ -628,7 +628,6 @@ ExpandComment =
doc = d.implementation.createHTMLDocument '' doc = d.implementation.createHTMLDocument ''
doc.documentElement.innerHTML = req.response doc.documentElement.innerHTML = req.response
Threading.op $('body > form', doc).firstChild
# Import the node to fix quote.hashes # Import the node to fix quote.hashes
# as they're empty when in a different document. # as they're empty when in a different document.
node = d.importNode doc.getElementById replyID node = d.importNode doc.getElementById replyID
@ -1014,9 +1013,9 @@ QR =
link = $.el 'h1', innerHTML: "<a href=javascript:;>#{if g.REPLY then 'Quick Reply' else 'New Thread'}</a>" link = $.el 'h1', innerHTML: "<a href=javascript:;>#{if g.REPLY then 'Quick Reply' else 'New Thread'}</a>"
$.on link.firstChild, 'click', -> $.on link.firstChild, 'click', ->
QR.open() QR.open()
$('select', QR.el).value = 'new' unless g.REPLY $('select', QR.el).value = 'new' unless g.REPLY
$('textarea', QR.el).focus() $('textarea', QR.el).focus()
$.before $('form[name=post]'), link $.before $.id('postForm'), link
# Prevent original captcha input from being focused on reload. # Prevent original captcha input from being focused on reload.
script = $.el 'script', script = $.el 'script',
@ -1405,7 +1404,7 @@ QR =
ta.style.cssText = $.get 'QR.size', '' ta.style.cssText = $.get 'QR.size', ''
# Allow only this board's supported files. # Allow only this board's supported files.
mimeTypes = $('.rules').firstChild.textContent.match(/: (.+) /)[1].toLowerCase().replace /\w+/g, (type) -> mimeTypes = $('ul.rules').firstElementChild.textContent.match(/: (.+) /)[1].toLowerCase().replace /\w+/g, (type) ->
switch type switch type
when 'jpg' when 'jpg'
'image/jpeg' 'image/jpeg'
@ -1876,39 +1875,6 @@ Options =
Unread.update true Unread.update true
@nextElementSibling.innerHTML = "<img src=#{Favicon.unreadSFW}> <img src=#{Favicon.unreadNSFW}> <img src=#{Favicon.unreadDead}>" @nextElementSibling.innerHTML = "<img src=#{Favicon.unreadSFW}> <img src=#{Favicon.unreadNSFW}> <img src=#{Favicon.unreadDead}>"
Threading =
op: (node) ->
nodes = []
until node.nodeName is 'BLOCKQUOTE'
nodes.push node
node = node.nextSibling
nodes.push node # Add the blockquote.
node = node.nextSibling
op = $.el 'div',
className: 'op'
$.add op, nodes
op.id = $('input', op).name
$.before node, op
thread: (node) ->
node = Threading.op node
return if g.REPLY
nodes = []
until node.nodeName is 'HR'
nodes.push node
node = node.nextElementSibling # Skip text nodes.
div = $.el 'div',
className: 'thread'
$.add div, nodes
$.before node, div
node = node.nextElementSibling
# {N,}SFW
unless node.align or node.nodeName is 'CENTER'
Threading.thread node
ThreadHiding = ThreadHiding =
init: -> init: ->
hiddenThreads = $.get "hiddenThreads/#{g.BOARD}/", {} hiddenThreads = $.get "hiddenThreads/#{g.BOARD}/", {}
@ -2407,13 +2373,14 @@ FileInfo =
r: -> FileInfo.data.resolution r: -> FileInfo.data.resolution
GetTitle = (thread) -> GetTitle = (thread) ->
el = $ '.filetitle', thread op = $ '.op', thread
if not el.textContent el = $ '.subject', op
el = $ 'blockquote', thread unless el.textContent
if not el.textContent el = $ 'blockquote', op
el = $ '.postername', thread unless el.textContent
el = $ '.nameBlock', op
span = $.el 'span', innerHTML: el.innerHTML.replace /<br>/g, ' ' span = $.el 'span', innerHTML: el.innerHTML.replace /<br>/g, ' '
"/#{g.BOARD}/ - #{span.textContent}" "/#{g.BOARD}/ - #{span.textContent.trim()}"
TitlePost = TitlePost =
init: -> init: ->
@ -2525,11 +2492,7 @@ QuoteInline =
doc = d.implementation.createHTMLDocument '' doc = d.implementation.createHTMLDocument ''
doc.documentElement.innerHTML = req.response doc.documentElement.innerHTML = req.response
node = node = doc.getElementById id
if id is threadID #OP
Threading.op $('body > form', doc).firstChild
else
doc.getElementById id
newInline = QuoteInline.table id, node.innerHTML newInline = QuoteInline.table id, node.innerHTML
for quote in $$ '.quotelink', newInline for quote in $$ '.quotelink', newInline
if (href = quote.getAttribute 'href') is quote.hash #add pathname to normal quotes if (href = quote.getAttribute 'href') is quote.hash #add pathname to normal quotes
@ -2599,11 +2562,7 @@ QuotePreview =
doc = d.implementation.createHTMLDocument '' doc = d.implementation.createHTMLDocument ''
doc.documentElement.innerHTML = req.response doc.documentElement.innerHTML = req.response
node = node = doc.getElementById id
if id is threadID #OP
Threading.op $('body > form', doc).firstChild
else
doc.getElementById id
qp.innerHTML = node.innerHTML qp.innerHTML = node.innerHTML
post = post =
root: qp root: qp
@ -3043,12 +3002,10 @@ Main =
g.REPLY = true g.REPLY = true
g.THREAD_ID = pathname[2] g.THREAD_ID = pathname[2]
#load values from localStorage # Load values from localStorage.
for key, val of Conf for key, val of Conf
Conf[key] = $.get key, val Conf[key] = $.get key, val
$.on window, 'message', Main.message
switch location.hostname switch location.hostname
when 'sys.4chan.org' when 'sys.4chan.org'
if /report/.test location.search if /report/.test location.search
@ -3063,12 +3020,13 @@ Main =
$.ready Options.init $.ready Options.init
if Conf['Quick Reply'] and Conf['Hide Original Post Form'] and g.BOARD isnt 'f' if Conf['Quick Reply'] and Conf['Hide Original Post Form'] and g.BOARD isnt 'f'
Main.css += 'form[name=post] { display: none; }' Main.css += '#postForm { display: none; }'
Main.addStyle() Main.addStyle()
now = Date.now() now = Date.now()
if Conf['Check for Updates'] and $.get('lastUpdate', 0) < now - 6*$.HOUR if Conf['Check for Updates'] and $.get('lastUpdate', 0) < now - 6*$.HOUR
$.on window, 'message', Main.message
$.ready -> $.add d.head, $.el 'script', src: 'https://raw.github.com/mayhemydg/4chan-x/master/latest.js' $.ready -> $.add d.head, $.el 'script', src: 'https://raw.github.com/mayhemydg/4chan-x/master/latest.js'
$.set 'lastUpdate', now $.set 'lastUpdate', now
@ -3153,10 +3111,10 @@ Main =
return return
$.addClass d.body, "chanx_#{Main.version.split('.')[1]}" $.addClass d.body, "chanx_#{Main.version.split('.')[1]}"
$.addClass d.body, $.engine $.addClass d.body, $.engine
for nav in ['navtop', 'navbot'] for nav in ['boardNavDesktop', 'boardNavDesktopFoot']
$.addClass $("a[href$='/#{g.BOARD}/']", $.id nav), 'current' if a = $ "a[href$='/#{g.BOARD}/']", $.id nav
form = $ 'form[name=delform]' # Gotta make it work in temporary boards.
Threading.thread form.firstElementChild $.addClass a, 'current'
Favicon.init() Favicon.init()
# Major features. # Major features.
@ -3201,18 +3159,19 @@ Main =
if Conf['Index Navigation'] if Conf['Index Navigation']
setTimeout -> Nav.init() setTimeout -> Nav.init()
board = $ '.board'
nodes = [] nodes = []
for node in $$ '.op, a + table', form for node in $$ '.post', board
nodes.push Main.preParse node nodes.push Main.preParse node
Main.node nodes, true Main.node nodes, true
if MutationObserver = window.WebKitMutationObserver or window.MozMutationObserver or window.OMutationObserver or window.MutationObserver if MutationObserver = window.WebKitMutationObserver or window.MozMutationObserver or window.OMutationObserver or window.MutationObserver
observer = new MutationObserver Main.observer observer = new MutationObserver Main.observer
observer.observe form, observer.observe board,
childList: true childList: true
subtree: true subtree: true
else else
$.on form, 'DOMNodeInserted', Main.listener $.on board, 'DOMNodeInserted', Main.listener
flatten: (parent, obj) -> flatten: (parent, obj) ->
if obj instanceof Array if obj instanceof Array
@ -3239,13 +3198,13 @@ Main =
preParse: (node) -> preParse: (node) ->
klass = node.className klass = node.className
post = post =
root: node root: node.parentNode
el: if klass is 'op' then node else node.firstChild.firstChild.lastChild el: node
class: klass class: klass
id: node.getElementsByTagName('input')[0].name id: node.id[1..]
threadId: g.THREAD_ID or $.x('ancestor::div[@class="thread"]', node).firstChild.id threadId: g.THREAD_ID or $.x('ancestor::div[@class="thread"]', node).id[1..]
isInlined: /\binline\b/.test klass isInlined: /\binline\b/.test klass
filesize: node.getElementsByClassName('filesize')[0] or false fileinfo: node.getElementsByClassName('fileInfo')[0] or false
quotes: node.getElementsByClassName 'quotelink' quotes: node.getElementsByClassName 'quotelink'
backlinks: node.getElementsByClassName 'backlink' backlinks: node.getElementsByClassName 'backlink'
post.img = if post.filesize then node.getElementsByTagName('img')[0] else false post.img = if post.filesize then node.getElementsByTagName('img')[0] else false
@ -3292,6 +3251,9 @@ a[href="javascript:;"] {
display: none; display: none;
} }
h1 {
text-align: center;
}
.autohide:not(:hover) > form { .autohide:not(:hover) > form {
display: none; display: none;
} }