From 81a2da0d277f23885887588499fc6202a6a5d79c Mon Sep 17 00:00:00 2001 From: seaweedchan Date: Fri, 16 Aug 2013 03:13:49 -0700 Subject: [PATCH 1/4] Release 4chan X v1.2.31. --- CHANGELOG.md | 3 +++ LICENSE | 2 +- builds/4chan-X.meta.js | 2 +- builds/4chan-X.user.js | 6 +++--- builds/crx/manifest.json | 2 +- builds/crx/script.js | 4 ++-- latest.js | 2 +- package.json | 2 +- 8 files changed, 13 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90f272c15..ea3f49ba3 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### v1.2.31 +*2013-08-16* + **seaweedchan**: ![Board title editing in action](src/General/img/changelog/1.2.31.png) diff --git a/LICENSE b/LICENSE index aceb0a5bd..8dee57dec 100755 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ /* -* 4chan X - Version 1.2.30 - 2013-08-16 +* 4chan X - Version 1.2.31 - 2013-08-16 * * Licensed under the MIT license. * https://github.com/seaweedchan/4chan-x/blob/master/LICENSE diff --git a/builds/4chan-X.meta.js b/builds/4chan-X.meta.js index fabd74d47..fb1001bc2 100755 --- a/builds/4chan-X.meta.js +++ b/builds/4chan-X.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.2.30 +// @version 1.2.31 // @namespace 4chan-X // @description Cross-browser userscript for maximum lurking on 4chan. // @license MIT; https://github.com/seaweedchan/4chan-x/blob/master/LICENSE diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index abd10d448..3183fe205 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -1,7 +1,7 @@ // Generated by CoffeeScript // ==UserScript== // @name 4chan X -// @version 1.2.30 +// @version 1.2.31 // @namespace 4chan-X // @description Cross-browser userscript for maximum lurking on 4chan. // @license MIT; https://github.com/seaweedchan/4chan-x/blob/master/LICENSE @@ -19,7 +19,7 @@ // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAgMAAAAqbBEUAAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAHFJREFUKFOt0LENACEIBdBv4Qju4wgWanEj3D6OcIVMKaitYHEU/jwTCQj8W75kiVCSBvdQ5/AvfVHBin11BgdRq3ysBgfwBDRrj3MCIA+oAQaku/Q1cNctrAmyDl577tOThYt/Y1RBM4DgOHzM0HFTAyLukH/cmRnqAAAAAElFTkSuQmCC // ==/UserScript== /* -* 4chan X - Version 1.2.30 - 2013-08-16 +* 4chan X - Version 1.2.31 - 2013-08-16 * * Licensed under the MIT license. * https://github.com/seaweedchan/4chan-x/blob/master/LICENSE @@ -328,7 +328,7 @@ doc = d.documentElement; g = { - VERSION: '1.2.30', + VERSION: '1.2.31', NAMESPACE: '4chan X.', boards: {}, threads: {}, diff --git a/builds/crx/manifest.json b/builds/crx/manifest.json index fca026759..056a5fbab 100755 --- a/builds/crx/manifest.json +++ b/builds/crx/manifest.json @@ -1,6 +1,6 @@ { "name": "4chan X", - "version": "1.2.30", + "version": "1.2.31", "manifest_version": 2, "description": "Cross-browser userscript for maximum lurking on 4chan.", "icons": { diff --git a/builds/crx/script.js b/builds/crx/script.js index 7ab55f0ac..065477c4a 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript /* -* 4chan X - Version 1.2.30 - 2013-08-16 +* 4chan X - Version 1.2.31 - 2013-08-16 * * Licensed under the MIT license. * https://github.com/seaweedchan/4chan-x/blob/master/LICENSE @@ -310,7 +310,7 @@ doc = d.documentElement; g = { - VERSION: '1.2.30', + VERSION: '1.2.31', NAMESPACE: '4chan X.', boards: {}, threads: {}, diff --git a/latest.js b/latest.js index 55297f0d8..4ebaadb4f 100755 --- a/latest.js +++ b/latest.js @@ -1 +1 @@ -postMessage({version:'1.2.30'},'*') +postMessage({version:'1.2.31'},'*') diff --git a/package.json b/package.json index 9be61ba63..f97571aed 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "4chan-X", - "version": "1.2.30", + "version": "1.2.31", "description": "Cross-browser userscript for maximum lurking on 4chan.", "meta": { From 61b2a51836a4f328889dc371b8fa965c4bffa2c0 Mon Sep 17 00:00:00 2001 From: seaweedchan Date: Fri, 16 Aug 2013 05:30:10 -0700 Subject: [PATCH 2/4] More optimizations --- builds/4chan-X.user.js | 66 +++++++++++++++----------------- builds/crx/script.js | 66 +++++++++++++++----------------- src/Miscellaneous/Banner.coffee | 67 ++++++++++++++++++--------------- 3 files changed, 96 insertions(+), 103 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 3183fe205..bd4ce9185 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -8465,44 +8465,38 @@ }); }, ready: function() { - var banner, btitle, child, children, i, subtitle; + var banner, child, children, i; banner = $(".boardBanner"); - if (Conf['Custom Board Titles']) { - btitle = $(".boardTitle", banner); - subtitle = $(".boardSubtitle", banner); - btitle.title = "Ctrl+click to edit board title"; - subtitle.title = "Ctrl+click to edit board subtitle"; - } children = banner.children; i = 0; while (child = children[i++]) { - if (child.tagName.toLowerCase() === "img") { + if (i === 1) { child.id = "Banner"; child.title = "Click to change"; $.on(child, 'click', Banner.cb.toggle); continue; } if (Conf['Custom Board Titles']) { - Banner.custom(child); + Banner.custom(child).title = "Ctrl+click to edit board " + (i === 3 ? 'sub' : '') + "title"; + Banner.custom(child).spellcheck = false; } } }, - types: { - jpg: 227, - png: 270, - gif: 253 - }, cb: { toggle: function() { - var num, type; - type = ['jpg', 'png', 'gif'][Math.floor(3 * Math.random())]; - num = Math.floor(Banner.types[type] * Math.random()); + var num, type, types; + types = { + jpg: 227, + png: 270, + gif: 253 + }; + type = Object.keys(types)[Math.floor(3 * Math.random())]; + num = Math.floor(types[type] * Math.random()); return this.src = "//static.4chan.org/image/title/" + num + "." + type; }, click: function(e) { if (e.ctrlKey) { this.contentEditable = true; - this.spellcheck = false; return this.focus(); } }, @@ -8514,6 +8508,7 @@ }, focus: function() { var items, string, string2; + this.textContent = this.innerHTML; string = "" + g.BOARD + "." + this.className; string2 = "" + string + ".orig"; items = { @@ -8526,40 +8521,39 @@ return $.set(string2, items.title); } }); - return this.textContent = this.innerHTML; }, blur: function() { - $.set("" + g.BOARD + "." + this.className, this.textContent); this.innerHTML = this.textContent; - return this.contentEditable = false; + this.contentEditable = false; + return $.set("" + g.BOARD + "." + this.className, this.textContent); } }, custom: function(child) { - var cachedTest, string, string2; + var cachedTest, string; cachedTest = child.innerHTML; string = "" + g.BOARD + "." + child.className; - string2 = "" + string + ".orig"; + $.on(child, 'click keydown focus blur', function(e) { + return Banner.cb[e.type].apply(this, [e]); + }); $.get(string, cachedTest, function(item) { - var title; + var string2, title; if (!(title = item[string])) { return; } if (Conf['Persistent Custom Board Titles']) { return child.innerHTML = title; - } else { - return $.get(string2, cachedTest, function(itemb) { - if (cachedTest === itemb[string2]) { - return child.innerHTML = title; - } else { - $.set(string, cachedTest); - return $.set(string2, cachedTest); - } - }); } + string2 = "" + string + ".orig"; + return $.get(string2, cachedTest, function(itemb) { + if (cachedTest === itemb[string2]) { + return child.innerHTML = title; + } else { + $.set(string, cachedTest); + return $.set(string2, cachedTest); + } + }); }); - return $.on(child, 'click keydown focus blur', function(e) { - return Banner.cb[e.type].apply(this, [e]); - }); + return child; } }; diff --git a/builds/crx/script.js b/builds/crx/script.js index 065477c4a..a5aad866e 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -8455,44 +8455,38 @@ }); }, ready: function() { - var banner, btitle, child, children, i, subtitle; + var banner, child, children, i; banner = $(".boardBanner"); - if (Conf['Custom Board Titles']) { - btitle = $(".boardTitle", banner); - subtitle = $(".boardSubtitle", banner); - btitle.title = "Ctrl+click to edit board title"; - subtitle.title = "Ctrl+click to edit board subtitle"; - } children = banner.children; i = 0; while (child = children[i++]) { - if (child.tagName.toLowerCase() === "img") { + if (i === 1) { child.id = "Banner"; child.title = "Click to change"; $.on(child, 'click', Banner.cb.toggle); continue; } if (Conf['Custom Board Titles']) { - Banner.custom(child); + Banner.custom(child).title = "Ctrl+click to edit board " + (i === 3 ? 'sub' : '') + "title"; + Banner.custom(child).spellcheck = false; } } }, - types: { - jpg: 227, - png: 270, - gif: 253 - }, cb: { toggle: function() { - var num, type; - type = ['jpg', 'png', 'gif'][Math.floor(3 * Math.random())]; - num = Math.floor(Banner.types[type] * Math.random()); + var num, type, types; + types = { + jpg: 227, + png: 270, + gif: 253 + }; + type = Object.keys(types)[Math.floor(3 * Math.random())]; + num = Math.floor(types[type] * Math.random()); return this.src = "//static.4chan.org/image/title/" + num + "." + type; }, click: function(e) { if (e.ctrlKey) { this.contentEditable = true; - this.spellcheck = false; return this.focus(); } }, @@ -8504,6 +8498,7 @@ }, focus: function() { var items, string, string2; + this.textContent = this.innerHTML; string = "" + g.BOARD + "." + this.className; string2 = "" + string + ".orig"; items = { @@ -8516,40 +8511,39 @@ return $.set(string2, items.title); } }); - return this.textContent = this.innerHTML; }, blur: function() { - $.set("" + g.BOARD + "." + this.className, this.textContent); this.innerHTML = this.textContent; - return this.contentEditable = false; + this.contentEditable = false; + return $.set("" + g.BOARD + "." + this.className, this.textContent); } }, custom: function(child) { - var cachedTest, string, string2; + var cachedTest, string; cachedTest = child.innerHTML; string = "" + g.BOARD + "." + child.className; - string2 = "" + string + ".orig"; + $.on(child, 'click keydown focus blur', function(e) { + return Banner.cb[e.type].apply(this, [e]); + }); $.get(string, cachedTest, function(item) { - var title; + var string2, title; if (!(title = item[string])) { return; } if (Conf['Persistent Custom Board Titles']) { return child.innerHTML = title; - } else { - return $.get(string2, cachedTest, function(itemb) { - if (cachedTest === itemb[string2]) { - return child.innerHTML = title; - } else { - $.set(string, cachedTest); - return $.set(string2, cachedTest); - } - }); } + string2 = "" + string + ".orig"; + return $.get(string2, cachedTest, function(itemb) { + if (cachedTest === itemb[string2]) { + return child.innerHTML = title; + } else { + $.set(string, cachedTest); + return $.set(string2, cachedTest); + } + }); }); - return $.on(child, 'click keydown focus blur', function(e) { - return Banner.cb[e.type].apply(this, [e]); - }); + return child; } }; diff --git a/src/Miscellaneous/Banner.coffee b/src/Miscellaneous/Banner.coffee index 52658c68f..2bc67ab37 100644 --- a/src/Miscellaneous/Banner.coffee +++ b/src/Miscellaneous/Banner.coffee @@ -5,40 +5,40 @@ Banner = ready: -> banner = $ ".boardBanner" - if Conf['Custom Board Titles'] - btitle = $ ".boardTitle", banner - subtitle = $ ".boardSubtitle", banner - btitle.title = "Ctrl+click to edit board title" - subtitle.title = "Ctrl+click to edit board subtitle" {children} = banner + i = 0 while child = children[i++] - if child.tagName.toLowerCase() is "img" + if i is 1 child.id = "Banner" child.title = "Click to change" $.on child, 'click', Banner.cb.toggle + continue if Conf['Custom Board Titles'] - Banner.custom child + Banner.custom(child).title = "Ctrl+click to edit board #{if i is 3 + 'sub' + else + ''}title" + Banner.custom(child).spellcheck = false return - types: - jpg: 227 - png: 270 - gif: 253 - cb: toggle: -> - type = ['jpg', 'png', 'gif'][Math.floor 3 * Math.random()] - num = Math.floor Banner.types[type] * Math.random() + types = + jpg: 227 + png: 270 + gif: 253 + + type = Object.keys(types)[Math.floor 3 * Math.random()] + num = Math.floor types[type] * Math.random() @src = "//static.4chan.org/image/title/#{num}.#{type}" click: (e) -> if e.ctrlKey @contentEditable = true - @spellcheck = false @focus() keydown: (e) -> @@ -46,38 +46,43 @@ Banner = return @blur() if !e.shiftKey and e.keyCode is 13 focus: -> + @textContent = @innerHTML + string = "#{g.BOARD}.#{@className}" string2 = "#{string}.orig" - items = - title: @innerHTML - items[string] = '' + + items = {title: @innerHTML} + items[string] = '' items[string2] = false $.get items, (items) -> unless items[string2] and items.title is items[string] $.set string2, items.title - @textContent = @innerHTML + + return blur: -> - $.set "#{g.BOARD}.#{@className}", @textContent @innerHTML = @textContent @contentEditable = false + $.set "#{g.BOARD}.#{@className}", @textContent custom: (child) -> cachedTest = child.innerHTML string = "#{g.BOARD}.#{child.className}" - string2 = "#{string}.orig" + + $.on child, 'click keydown focus blur', (e) -> Banner.cb[e.type].apply @, [e] $.get string, cachedTest, (item) -> return unless title = item[string] - if Conf['Persistent Custom Board Titles'] - child.innerHTML = title - else - $.get string2, cachedTest, (itemb) -> - if cachedTest is itemb[string2] - child.innerHTML = title - else - $.set string, cachedTest - $.set string2, cachedTest + return child.innerHTML = title if Conf['Persistent Custom Board Titles'] - $.on child, 'click keydown focus blur', (e) -> Banner.cb[e.type].apply @, [e] \ No newline at end of file + string2 = "#{string}.orig" + + $.get string2, cachedTest, (itemb) -> + if cachedTest is itemb[string2] + child.innerHTML = title + else + $.set string, cachedTest + $.set string2, cachedTest + + child \ No newline at end of file From c655bbcceb3d8f6ab0cd68bfe67f3825acd6aeeb Mon Sep 17 00:00:00 2001 From: Jordan Bates Date: Fri, 16 Aug 2013 16:45:22 -0700 Subject: [PATCH 3/4] Zixaphir is a tough boss --- builds/4chan-X.user.js | 433 +++++++++++++++++++++++++++++++- builds/crx/script.js | 433 +++++++++++++++++++++++++++++++- src/Miscellaneous/Banner.coffee | 11 +- 3 files changed, 858 insertions(+), 19 deletions(-) diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index bd4ce9185..eb8d12057 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -349,6 +349,7 @@ Array.prototype.indexOf = function(object) { var i; + i = this.length; while (i--) { if (this[i] === object) { @@ -367,6 +368,7 @@ $.extend = function(object, properties) { var key, val; + for (key in properties) { val = properties[key]; if (!properties.hasOwnProperty(key)) { @@ -384,6 +386,7 @@ $.ready = function(fc) { var cb; + if (d.readyState !== 'loading') { $.queueTask(fc); return; @@ -397,6 +400,7 @@ $.formData = function(form) { var fd, key, val; + if (form instanceof HTMLFormElement) { return new FormData(form); } @@ -416,6 +420,7 @@ $.extend = function(object, properties) { var key, val; + for (key in properties) { val = properties[key]; object[key] = val; @@ -424,9 +429,11 @@ $.ajax = (function() { var lastModified; + lastModified = {}; return function(url, options, extra) { var form, r, sync, type, upCallbacks, whenModified; + if (extra == null) { extra = {}; } @@ -449,9 +456,11 @@ $.cache = (function() { var reqs; + reqs = {}; return function(url, cb, options) { var err, req, rm; + if (req = reqs[url]) { if (req.readyState === 4) { cb.call(req, req.evt); @@ -471,6 +480,7 @@ } $.on(req, 'load', function(e) { var _i, _len, _ref; + _ref = this.callbacks; for (_i = 0, _len = _ref.length; _i < _len; _i++) { cb = _ref[_i]; @@ -506,6 +516,7 @@ $.addStyle = function(css, id) { var style; + style = $.el('style', { id: id, textContent: css @@ -552,6 +563,7 @@ } else { return function(el) { var _ref; + return (_ref = el.parentNode) != null ? _ref.removeChild(el) : void 0; }; } @@ -559,6 +571,7 @@ $.rmAll = function(root) { var node; + while (node = root.firstChild) { root.removeChild(node); } @@ -574,6 +587,7 @@ $.nodes = function(nodes) { var frag, node, _i, _len; + if (!(nodes instanceof Array)) { return nodes; } @@ -607,6 +621,7 @@ $.el = function(tag, properties) { var el; + el = d.createElement(tag); if (properties) { $.extend(el, properties); @@ -616,6 +631,7 @@ $.on = function(el, events, handler) { var event, _i, _len, _ref; + _ref = events.split(' '); for (_i = 0, _len = _ref.length; _i < _len; _i++) { event = _ref[_i]; @@ -625,6 +641,7 @@ $.off = function(el, events, handler) { var event, _i, _len, _ref; + _ref = events.split(' '); for (_i = 0, _len = _ref.length; _i < _len; _i++) { event = _ref[_i]; @@ -646,6 +663,7 @@ $.debounce = function(wait, fn) { var args, exec, lastCall, that, timeout; + lastCall = 0; timeout = null; that = null; @@ -667,9 +685,11 @@ $.queueTask = (function() { var execTask, taskChannel, taskQueue; + taskQueue = []; execTask = function() { var args, func, task; + task = taskQueue.shift(); func = task[0]; args = Array.prototype.slice.call(task, 1); @@ -692,6 +712,7 @@ $.globalEval = function(code) { var script; + script = $.el('script', { textContent: code }); @@ -701,6 +722,7 @@ $.bytesToString = function(size) { var unit; + unit = 0; while (size >= 1024) { size /= 1024; @@ -716,6 +738,7 @@ $.item = function(key, val) { var item; + item = {}; item[key] = val; return item; @@ -726,6 +749,7 @@ $.sync = (function() { $.on(window, 'storage', function(e) { var cb; + if (cb = $.syncing[e.key]) { return cb(JSON.parse(e.newValue)); } @@ -737,6 +761,7 @@ $["delete"] = function(keys) { var key, _i, _len; + if (!(keys instanceof Array)) { keys = [keys]; } @@ -750,6 +775,7 @@ $.get = function(key, val, cb) { var items; + if (typeof cb === 'function') { items = $.item(key, val); } else { @@ -768,6 +794,7 @@ $.set = (function() { var set; + set = function(key, val) { key = g.NAMESPACE + key; val = JSON.stringify(val); @@ -778,6 +805,7 @@ }; return function(keys, val) { var key; + if (typeof keys === 'string') { set(keys, val); return; @@ -845,6 +873,7 @@ function Post(root, thread, board, that) { var capcode, date, email, flag, info, name, post, subject, tripcode, uniqueID; + this.thread = thread; this.board = board; if (that == null) { @@ -920,6 +949,7 @@ Post.prototype.parseComment = function() { var bq, i, node, nodes, text; + bq = this.nodes.comment.cloneNode(true); nodes = $$('.abbr, .capcodeReplies, .exif, b', bq); i = 0; @@ -937,6 +967,7 @@ Post.prototype.parseQuotes = function() { var quotelink, _i, _len, _ref; + this.quotes = []; _ref = $$('.quotelink', this.nodes.comment); for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -947,6 +978,7 @@ Post.prototype.parseQuote = function(quotelink) { var fullID, match; + if (!(match = quotelink.href.match(/boards\.4chan\.org\/([^\/]+)\/res\/\d+#p(\d+)$/))) { return; } @@ -962,6 +994,7 @@ Post.prototype.parseFile = function(that) { var alt, anchor, fileEl, fileInfo, size, thumb, unit; + if (!((fileEl = $('.file', this.nodes.post)) && (thumb = $('img[data-md5]', fileEl)))) { return; } @@ -992,6 +1025,7 @@ Post.prototype.kill = function(file, now) { var clone, quotelink, strong, _i, _j, _len, _len1, _ref, _ref1; + now || (now = new Date()); if (file) { if (this.file.isDead) { @@ -1040,6 +1074,7 @@ Post.prototype.resurrect = function() { var clone, quotelink, strong, _i, _j, _len, _len1, _ref, _ref1; + delete this.isDead; delete this.timeOfDeath; $.rmClass(this.nodes.root, 'deleted-post'); @@ -1073,6 +1108,7 @@ Post.prototype.rmClone = function(index) { var clone, _i, _len, _ref; + this.clones.splice(index, 1); _ref = this.clones.slice(index); for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -1090,6 +1126,7 @@ function Clone(origin, context) { var file, info, inline, inlined, key, nodes, post, root, val, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3; + this.origin = origin; this.context = context; _ref = ['ID', 'fullID', 'board', 'thread', 'info', 'quotes', 'isReply']; @@ -1177,6 +1214,7 @@ function DataBoard(key, sync, dontClean) { var init, _this = this; + this.key = key; this.data = Conf[key]; $.sync(key, this.onSync.bind(this)); @@ -1199,6 +1237,7 @@ DataBoard.prototype["delete"] = function(_arg) { var boardID, postID, threadID; + boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID; if (postID) { delete this.data.boards[boardID][threadID][postID]; @@ -1219,6 +1258,7 @@ DataBoard.prototype.deleteIfEmpty = function(_arg) { var boardID, threadID; + boardID = _arg.boardID, threadID = _arg.threadID; if (threadID) { if (!Object.keys(this.data.boards[boardID][threadID]).length) { @@ -1234,6 +1274,7 @@ DataBoard.prototype.set = function(_arg) { var boardID, postID, threadID, val, _base, _base1, _base2; + boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID, val = _arg.val; if (postID !== void 0) { ((_base = ((_base1 = this.data.boards)[boardID] || (_base1[boardID] = {})))[threadID] || (_base[threadID] = {}))[postID] = val; @@ -1247,6 +1288,7 @@ DataBoard.prototype.get = function(_arg) { var ID, board, boardID, defaultValue, postID, thread, threadID, val, _i, _len; + boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID, defaultValue = _arg.defaultValue; if (board = this.data.boards[boardID]) { if (!threadID) { @@ -1270,6 +1312,7 @@ DataBoard.prototype.clean = function() { var boardID, now, val, _ref; + _ref = this.data.boards; for (boardID in _ref) { val = _ref[boardID]; @@ -1289,8 +1332,10 @@ DataBoard.prototype.ajaxClean = function(boardID) { var _this = this; + return $.cache("//api.4chan.org/" + boardID + "/threads.json", function(e) { var board, page, thread, threads, _i, _j, _len, _len1, _ref, _ref1; + if (e.target.status === 404) { _this["delete"](boardID); } else if (e.target.status === 200) { @@ -1375,8 +1420,10 @@ init: function() {}, toBlob: function() { var _base; + return (_base = HTMLCanvasElement.prototype).toBlob || (_base.toBlob = function(cb) { var data, i, l, ui8a, _i; + data = atob(this.toDataURL().slice(22)); l = data.length; ui8a = new Uint8Array(l); @@ -1414,6 +1461,7 @@ init: function() { var barFixedToggler, barPositionToggler, customNavToggler, editCustomNav, footerToggler, headerToggler, linkJustifyToggler, menuButton, _this = this; + this.menu = new UI.Menu('header'); menuButton = $.el('span', { className: 'menu-button', @@ -1504,6 +1552,7 @@ }); return $.ready(function() { var a, cs; + _this.footer = $.id('boardNavDesktopFoot'); if (a = $("a[href*='/" + g.BOARD + "/']", $.id('boardNavDesktopFoot'))) { a.className = 'current'; @@ -1537,6 +1586,7 @@ }), setBoardList: function() { var a, boardList, btn, fourchannav, fullBoardList; + fourchannav = $.id('boardNavDesktop'); if (a = $("a[href*='/" + g.BOARD + "/']", fourchannav)) { a.className = 'current'; @@ -1558,6 +1608,7 @@ }, generateBoardList: function(text) { var as, list, nodes; + list = $('#custom-board-list', Header.bar); $.rmAll(list); if (!text) { @@ -1566,6 +1617,7 @@ as = $$('#full-board-list a[title]', Header.bar); nodes = text.match(/[\w@]+((-(all|title|replace|full|index|catalog|url:"[^"]+[^"]"|text:"[^"]+")|\,"[^"]+[^"]"))*|[^\w@]+/g).map(function(t) { var a, board, m, _i, _len; + if (/^[^\w@]/.test(t)) { return $.tn(t); } @@ -1616,6 +1668,7 @@ }, toggleBoardList: function() { var bar, custom, full, showBoardList; + bar = Header.bar; custom = $('#custom-board-list', bar); full = $('#full-board-list', bar); @@ -1651,6 +1704,7 @@ }, toggleLinkJustify: function() { var centered; + $.event('CloseMenu'); centered = this.nodeName === 'INPUT' ? this.checked : void 0; Header.setLinkJustify(centered); @@ -1680,6 +1734,7 @@ }, toggleBarVisibility: function() { var hide, message; + hide = this.nodeName === 'INPUT' ? this.checked : !$.hasClass(Header.bar, 'autohide'); this.checked = hide; $.set('Header auto-hide', Conf['Header auto-hide'] = hide); @@ -1693,6 +1748,7 @@ }, toggleFooterVisibility: function() { var hide, message; + $.event('CloseMenu'); hide = this.nodeName === 'INPUT' ? this.checked : !!Header.footer.hidden; Header.setFooterVisibility(hide); @@ -1702,6 +1758,7 @@ }, setCustomNav: function(show) { var btn, cust, full, _ref; + Header.customNavToggler.checked = show; cust = $('#custom-board-list', Header.bar); full = $('#full-board-list', Header.bar); @@ -1714,12 +1771,14 @@ }, editCustomNav: function() { var settings; + Settings.open('Advanced'); settings = $.id('fourchanx-settings'); return $('input[name=boardnav]', settings).focus(); }, hashScroll: function() { var hash, post; + if (!((hash = this.location.hash.slice(1)) && (post = $.id(hash)))) { return; } @@ -1730,6 +1789,7 @@ }, scrollToPost: function(post) { var headRect, top; + top = post.getBoundingClientRect().top; if (Conf['Fixed Header'] && !Conf['Bottom Header']) { headRect = Header.bar.getBoundingClientRect(); @@ -1739,6 +1799,7 @@ }, addShortcut: function(el) { var shortcut; + shortcut = $.el('span', { className: 'shortcut brackets-wrap' }); @@ -1750,6 +1811,7 @@ }, createNotification: function(e) { var cb, content, lifetime, notif, type, _ref; + _ref = e.detail, type = _ref.type, content = _ref.content, lifetime = _ref.lifetime, cb = _ref.cb; notif = new Notification(type, content, lifetime); if (cb) { @@ -1762,6 +1824,7 @@ spoilerRange: {}, shortFilename: function(filename, isReply) { var threshold; + threshold = isReply ? 30 : 40; if (filename.length - 4 > threshold) { return "" + filename.slice(0, threshold - 5) + "(...)." + filename.slice(-3); @@ -1771,6 +1834,7 @@ }, postFromObject: function(data, boardID) { var o; + o = { postID: data.no, threadID: data.resto || data.no, @@ -1815,6 +1879,7 @@ */ var a, boardID, capcode, capcodeClass, capcodeReplies, capcodeStart, closed, comment, container, date, dateUTC, email, emailEnd, emailStart, ext, file, fileDims, fileHTML, fileInfo, fileSize, fileThumb, filename, flag, flagCode, flagName, href, imgSrc, isClosed, isOP, isSticky, name, postID, quote, shortFilename, spoilerRange, staticPath, sticky, subject, threadID, tripcode, uniqueID, userID, _i, _len, _ref; + postID = o.postID, threadID = o.threadID, boardID = o.boardID, name = o.name, capcode = o.capcode, tripcode = o.tripcode, uniqueID = o.uniqueID, email = o.email, subject = o.subject, flagCode = o.flagCode, flagName = o.flagName, date = o.date, dateUTC = o.dateUTC, isSticky = o.isSticky, isClosed = o.isClosed, comment = o.comment, capcodeReplies = o.capcodeReplies, file = o.file; isOP = postID === threadID; staticPath = '//static.4chan.org/image/'; @@ -1913,6 +1978,7 @@ }, capcodeReplies: function(_arg) { var array, boardID, bq, capcodeReplies, capcodeType, generateCapcodeReplies, html, root, threadID; + boardID = _arg.boardID, threadID = _arg.threadID, bq = _arg.bq, root = _arg.root, capcodeReplies = _arg.capcodeReplies; if (!capcodeReplies) { return; @@ -1949,6 +2015,7 @@ Get = { threadExcerpt: function(thread) { var OP, excerpt, _ref; + OP = thread.OP; excerpt = ((_ref = OP.info.subject) != null ? _ref.trim() : void 0) || OP.info.comment.replace(/\n+/g, ' // ') || Conf['Anonymize'] && 'Anonymous' || $('.nameBlock', OP.nodes.info).textContent.trim(); if (excerpt.length > 70) { @@ -1964,6 +2031,7 @@ }, postFromRoot: function(root) { var boardID, index, link, post, postID; + link = $('a[title="Highlight this post"]', root); boardID = link.pathname.split('/')[1]; postID = link.hash.slice(2); @@ -1983,6 +2051,7 @@ }, postDataFromLink: function(link) { var boardID, path, postID, threadID, _ref; + if (link.hostname === 'boards.4chan.org') { path = link.pathname.split('/'); boardID = path[1]; @@ -2000,6 +2069,7 @@ }, allQuotelinksLinkingTo: function(post) { var ID, quote, quotedPost, quotelinks, quoterPost, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3; + quotelinks = []; _ref = g.posts; for (ID in _ref) { @@ -2028,12 +2098,14 @@ } return quotelinks.filter(function(quotelink) { var boardID, postID, _ref4; + _ref4 = Get.postDataFromLink(quotelink), boardID = _ref4.boardID, postID = _ref4.postID; return boardID === post.board.ID && postID === post.ID; }); }, postClone: function(boardID, threadID, postID, root, context) { var post, url; + if (post = g.posts["" + boardID + "." + postID]) { Get.insert(post, root, context); return; @@ -2056,6 +2128,7 @@ }, insert: function(post, root, context) { var clone, nodes; + if (!root.parentNode) { return; } @@ -2069,6 +2142,7 @@ }, fetchedPost: function(req, boardID, threadID, postID, root, context) { var board, post, posts, status, thread, url, _i, _len; + if (post = g.posts["" + boardID + "." + postID]) { Get.insert(post, root, context); return; @@ -2122,6 +2196,7 @@ }, archivedPost: function(req, boardID, postID, root, context) { var board, bq, comment, data, o, post, thread, threadID, _ref; + if (post = g.posts["" + boardID + "." + postID]) { Get.insert(post, root, context); return; @@ -2216,8 +2291,10 @@ UI = (function() { var Menu, dialog, drag, dragend, dragstart, hover, hoverend, hoverstart, touchend, touchmove; + dialog = function(id, position, html) { var child, el, move, _i, _len, _ref; + el = $.el('div', { className: 'dialog', innerHTML: html, @@ -2257,6 +2334,7 @@ Menu.prototype.makeMenu = function() { var menu; + menu = $.el('div', { className: 'dialog', id: 'menu', @@ -2271,6 +2349,7 @@ Menu.prototype.toggle = function(e, button, data) { var previousButton; + e.preventDefault(); e.stopPropagation(); if (currentMenu) { @@ -2288,6 +2367,7 @@ Menu.prototype.open = function(button, data) { var bLeft, bRect, bTop, bottom, cHeight, cWidth, entry, left, mRect, menu, right, style, top, _i, _len, _ref, _ref1, _ref2; + menu = this.makeMenu(); currentMenu = menu; lastToggledButton = button; @@ -2326,6 +2406,7 @@ Menu.prototype.insertEntry = function(entry, parent, data) { var subEntry, submenu, _i, _len, _ref; + if (typeof entry.open === 'function') { if (!entry.open(data)) { return; @@ -2359,6 +2440,7 @@ Menu.prototype.findNextEntry = function(entry, direction) { var entries; + entries = __slice.call(entry.parentNode.children); entries.sort(function(first, second) { return +(first.style.order || first.style.webkitOrder) - +(second.style.order || second.style.webkitOrder); @@ -2368,6 +2450,7 @@ Menu.prototype.keybinds = function(e) { var entry, next, nextPrev, subEntry, submenu; + entry = $('.focused', currentMenu); while (subEntry = $('.focused', entry)) { entry = subEntry; @@ -2413,6 +2496,7 @@ Menu.prototype.focus = function(entry) { var bottom, cHeight, cWidth, eRect, focused, left, right, sRect, style, submenu, top, _i, _len, _ref, _ref1, _ref2; + while (focused = $.x('parent::*/child::*[contains(@class,"focused")]', entry)) { $.rmClass(focused, 'focused'); } @@ -2440,6 +2524,7 @@ Menu.prototype.addEntry = function(e) { var entry; + entry = e.detail; if (entry.type !== this.type) { return; @@ -2450,6 +2535,7 @@ Menu.prototype.parseEntry = function(entry) { var el, style, subEntries, subEntry, _i, _len; + el = entry.el, subEntries = entry.subEntries; $.addClass(el, 'entry'); $.on(el, 'focus mouseover', (function(e) { @@ -2473,6 +2559,7 @@ })(); dragstart = function(e) { var el, isTouching, o, rect, screenHeight, screenWidth, _ref; + if (e.type === 'mousedown' && e.button !== 0) { return; } @@ -2511,6 +2598,7 @@ }; touchmove = function(e) { var touch, _i, _len, _ref; + _ref = e.changedTouches; for (_i = 0, _len = _ref.length; _i < _len; _i++) { touch = _ref[_i]; @@ -2522,6 +2610,7 @@ }; drag = function(e) { var bottom, clientX, clientY, left, right, style, top; + clientX = e.clientX, clientY = e.clientY; left = clientX - this.dx; left = left < 10 ? 0 : this.width - left < 10 ? null : left / this.screenWidth * 100 + '%'; @@ -2537,6 +2626,7 @@ }; touchend = function(e) { var touch, _i, _len, _ref; + _ref = e.changedTouches; for (_i = 0, _len = _ref.length; _i < _len; _i++) { touch = _ref[_i]; @@ -2558,6 +2648,7 @@ }; hoverstart = function(_arg) { var asapTest, cb, el, endEvents, latestEvent, o, root; + root = _arg.root, el = _arg.el, latestEvent = _arg.latestEvent, endEvents = _arg.endEvents, asapTest = _arg.asapTest, cb = _arg.cb; o = { root: root, @@ -2592,6 +2683,7 @@ }; hover = function(e) { var clientX, clientY, height, left, right, style, top, _ref; + this.latestEvent = e; height = this.el.offsetHeight; clientX = e.clientX, clientY = e.clientY; @@ -2635,6 +2727,7 @@ }, node: function() { var email, name, tripcode, _ref; + if (this.info.capcode || this.isClone) { return; } @@ -2661,6 +2754,7 @@ filters: {}, init: function() { var boards, err, filter, hl, key, op, regexp, stub, top, _i, _len, _ref, _ref1, _ref2, _ref3, _ref4; + if (g.VIEW === 'catalog' || !Conf['Filter']) { return; } @@ -2697,6 +2791,7 @@ op = ((_ref2 = filter.match(/[^t]op:(yes|no|only)/)) != null ? _ref2[1] : void 0) || 'yes'; stub = (function() { var _ref3; + switch ((_ref3 = filter.match(/stub:(yes|no)/)) != null ? _ref3[1] : void 0) { case 'yes': return true; @@ -2727,6 +2822,7 @@ }, createFilter: function(regexp, op, stub, hl, top) { var settings, test; + test = typeof regexp === 'string' ? function(value) { return regexp === value; } : function(value) { @@ -2750,6 +2846,7 @@ }, node: function() { var filter, firstThread, key, result, thisThread, value, _i, _len, _ref; + if (this.isClone) { return; } @@ -2861,6 +2958,7 @@ menu: { init: function() { var div, entry, type, _i, _len, _ref; + if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Filter']) { return; } @@ -2886,6 +2984,7 @@ }, createSubEntry: function(text, type) { var el; + el = $.el('a', { href: 'javascript:;', textContent: text @@ -2896,6 +2995,7 @@ el: el, open: function(post) { var value; + value = Filter[type](post); return value !== false; } @@ -2903,6 +3003,7 @@ }, makeFilter: function() { var re, type, value; + type = this.dataset.type; value = Filter[type](Filter.menu.post); re = ['uniqueID', 'MD5'].contains(type) ? value : value.replace(/\/|\\|\^|\$|\n|\.|\(|\)|\{|\}|\[|\]|\?|\*|\+|\|/g, function(c) { @@ -2917,6 +3018,7 @@ re = ['uniqueID', 'MD5'].contains(type) ? "/" + re + "/" : "/^" + re + "$/"; return $.get(type, Conf[type], function(item) { var save, section, select, ta, tl; + save = item[type]; save = save ? "" + save + "\n" + re : re; $.set(type, save); @@ -2950,6 +3052,7 @@ }, node: function() { var data; + if (!this.isReply || this.isClone) { return; } @@ -2973,6 +3076,7 @@ menu: { init: function() { var apply, div, hideStubLink, makeStub, replies, thisPost; + if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Reply Hiding Link']) { return; } @@ -3043,6 +3147,7 @@ order: 20, open: function(post) { var data; + if (!post.isReply || post.isClone || !post.isHidden) { return false; } @@ -3074,6 +3179,7 @@ order: 15, open: function(post) { var data; + if (!post.isReply || post.isClone || !post.isHidden) { return false; } @@ -3090,6 +3196,7 @@ }, hide: function() { var makeStub, parent, post, replies, thisPost; + parent = this.parentNode; thisPost = $('input[name=thisPost]', parent).checked; replies = $('input[name=replies]', parent).checked; @@ -3108,6 +3215,7 @@ }, show: function() { var data, parent, post, replies, thisPost; + parent = this.parentNode; thisPost = $('input[name=thisPost]', parent).checked; replies = $('input[name=replies]', parent).checked; @@ -3131,6 +3239,7 @@ }, hideStub: function() { var post; + post = PostHiding.menu.post; post.nodes.root.hidden = true; $.event('CloseMenu'); @@ -3138,6 +3247,7 @@ }, makeButton: function(post, type) { var a; + a = $.el('a', { className: "" + type + "-reply-button", innerHTML: " " + (type === 'hide' ? '-' : '+') + " ", @@ -3148,6 +3258,7 @@ }, saveHiddenState: function(post, isHiding, thisPost, makeStub, hideRecursively) { var data; + data = { boardID: post.board.ID, threadID: post.thread.ID, @@ -3166,12 +3277,14 @@ }, toggle: function() { var post; + post = Get.postFromNode(this); PostHiding[(post.isHidden ? 'show' : 'hide')](post); return PostHiding.saveHiddenState(post, post.isHidden); }, hide: function(post, makeStub, hideRecursively) { var a, button, postInfo, quotelink, _i, _len, _ref; + if (makeStub == null) { makeStub = Conf['Stubs']; } @@ -3206,6 +3319,7 @@ }, show: function(post, showRecursively) { var quotelink, _i, _len, _ref; + if (showRecursively == null) { showRecursively = Conf['Recursive Hiding']; } @@ -3241,6 +3355,7 @@ }, node: function() { var i, obj, quote, recursive, _i, _j, _len, _len1, _ref, _ref1; + if (this.isClone) { return; } @@ -3258,6 +3373,7 @@ }, add: function() { var args, obj, post, recursive, _base, _name; + recursive = arguments[0], post = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : []; obj = (_base = Recursive.recursives)[_name = post.fullID] || (_base[_name] = { recursives: [], @@ -3268,6 +3384,7 @@ }, rm: function(recursive, post) { var i, obj, rec, _i, _len, _ref; + if (!(obj = Recursive.recursives[post.fullID])) { return; } @@ -3282,6 +3399,7 @@ }, apply: function() { var ID, args, fullID, post, recursive, _ref; + recursive = arguments[0], post = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : []; fullID = post.fullID; _ref = g.posts; @@ -3308,6 +3426,7 @@ }, node: function() { var data; + if (data = ThreadHiding.db.get({ boardID: this.board.ID, threadID: this.ID @@ -3321,6 +3440,7 @@ }, syncCatalog: function() { var hiddenThreads, hiddenThreadsOnCatalog, threadID; + hiddenThreads = ThreadHiding.db.get({ boardID: g.BOARD.ID, defaultValue: {} @@ -3347,6 +3467,7 @@ cleanCatalog: function(hiddenThreadsOnCatalog) { return $.cache("//api.4chan.org/" + g.BOARD + "/threads.json", function() { var page, thread, threads, _i, _j, _len, _len1, _ref, _ref1; + if (this.status !== 200) { return; } @@ -3372,6 +3493,7 @@ menu: { init: function() { var apply, div, hideStubLink, makeStub; + if (g.VIEW !== 'index' || !Conf['Menu'] || !Conf['Thread Hiding Link']) { return; } @@ -3393,6 +3515,7 @@ order: 20, open: function(_arg) { var isReply, thread; + thread = _arg.thread, isReply = _arg.isReply; if (isReply || thread.isHidden) { return false; @@ -3420,6 +3543,7 @@ order: 20, open: function(_arg) { var isReply, thread; + thread = _arg.thread, isReply = _arg.isReply; if (isReply || !thread.isHidden) { return false; @@ -3439,6 +3563,7 @@ order: 15, open: function(_arg) { var isReply, thread; + thread = _arg.thread, isReply = _arg.isReply; if (isReply || !thread.isHidden) { return false; @@ -3449,6 +3574,7 @@ }, hide: function() { var makeStub, thread; + makeStub = $('input', this.parentNode).checked; thread = ThreadHiding.menu.thread; ThreadHiding.hide(thread, makeStub); @@ -3457,6 +3583,7 @@ }, show: function() { var thread; + thread = ThreadHiding.menu.thread; ThreadHiding.show(thread); ThreadHiding.saveHiddenState(thread); @@ -3464,6 +3591,7 @@ }, hideStub: function() { var thread; + thread = ThreadHiding.menu.thread; ThreadHiding.hide(thread, false); $.event('CloseMenu'); @@ -3471,6 +3599,7 @@ }, makeButton: function(thread, type) { var a; + a = $.el('a', { className: "" + type + "-thread-button", innerHTML: " " + (type === 'hide' ? '-' : '+') + " ", @@ -3482,6 +3611,7 @@ }, saveHiddenState: function(thread, makeStub) { var hiddenThreadsOnCatalog; + hiddenThreadsOnCatalog = JSON.parse(localStorage.getItem("4chan-hide-t-" + g.BOARD)) || {}; if (thread.isHidden) { ThreadHiding.db.set({ @@ -3514,6 +3644,7 @@ }, hide: function(thread, makeStub) { var OP, a, numReplies, opInfo, span, threadRoot; + if (makeStub == null) { makeStub = Conf['Stubs']; } @@ -3537,6 +3668,7 @@ }, show: function(thread) { var threadRoot; + if (thread.stub) { $.rm(thread.stub); delete thread.stub; @@ -3549,6 +3681,7 @@ QuoteBacklink = { init: function() { var format; + if (g.VIEW === 'catalog' || !Conf['Quote Backlinks']) { return; } @@ -3566,6 +3699,7 @@ }, firstNode: function() { var a, clone, container, containers, frag, link, post, quote, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; + if (this.isClone || !this.quotes.length) { return; } @@ -3603,6 +3737,7 @@ }, secondNode: function() { var container; + if (this.isClone && (this.origin.isReply || Conf['OP Backlinks'])) { this.nodes.backlinkContainer = $('.container', this.nodes.info); return; @@ -3616,6 +3751,7 @@ }, getContainer: function(id) { var _base; + return (_base = this.containers)[id] || (_base[id] = $.el('span', { className: 'container' })); @@ -3638,6 +3774,7 @@ }, node: function() { var board, boardID, quotelink, thread, threadID, _i, _len, _ref, _ref1, _ref2; + if (this.isClone && this.thread === this.context.thread) { return; } @@ -3667,6 +3804,7 @@ if (Conf['Quote Hash Navigation']) { this.node = function() { var link, _i, _len, _ref; + _ref = this.nodes.quotelinks.concat(__slice.call(this.nodes.backlinks)); for (_i = 0, _len = _ref.length; _i < _len; _i++) { link = _ref[_i]; @@ -3679,6 +3817,7 @@ } else { this.node = function() { var link, _i, _len, _ref; + _ref = this.nodes.quotelinks.concat(__slice.call(this.nodes.backlinks)); for (_i = 0, _len = _ref.length; _i < _len; _i++) { link = _ref[_i]; @@ -3705,6 +3844,7 @@ }, toggle: function(e) { var boardID, context, postID, threadID, _ref; + if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) { return; } @@ -3730,6 +3870,7 @@ }, add: function(quotelink, boardID, threadID, postID, context) { var inline, isBacklink, post, qroot, root; + isBacklink = $.hasClass(quotelink, 'backlink'); inline = $.el('div', { id: "i" + postID, @@ -3754,6 +3895,7 @@ }, rm: function(quotelink, boardID, threadID, postID, context) { var el, inlined, isBacklink, post, qroot, root, _ref; + isBacklink = $.hasClass(quotelink, 'backlink'); root = QuoteInline.findRoot(quotelink, isBacklink); root = $.x("following-sibling::div[@id='i" + postID + "'][1]", root); @@ -3795,6 +3937,7 @@ }, node: function() { var boardID, fullID, i, postID, quotelink, quotelinks, quotes, _ref; + if (this.isClone && this.thread === this.context.thread) { return; } @@ -3837,6 +3980,7 @@ }, node: function() { var link, _i, _len, _ref; + _ref = this.nodes.quotelinks.concat(__slice.call(this.nodes.backlinks)); for (_i = 0, _len = _ref.length; _i < _len; _i++) { link = _ref[_i]; @@ -3845,6 +3989,7 @@ }, mouseover: function(e) { var boardID, clone, origin, post, postID, posts, qp, quote, quoterID, threadID, _i, _j, _len, _len1, _ref, _ref1; + if ($.hasClass(this, 'inlined')) { return; } @@ -3888,6 +4033,7 @@ }, mouseout: function() { var clone, post, root, _i, _len, _ref; + if (!(root = this.el.firstElementChild)) { return; } @@ -3917,6 +4063,7 @@ }, node: function() { var boardID, postID, quotelink, _i, _len, _ref, _ref1, _ref2; + if (this.isClone) { return; } @@ -3939,6 +4086,7 @@ QuoteThreading = { init: function() { var input; + if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) { return; } @@ -3961,6 +4109,7 @@ }, setup: function() { var ID, post, posts; + $.off(d, '4chanXInitFinished', QuoteThreading.setup); posts = g.posts; for (ID in posts) { @@ -3973,6 +4122,7 @@ }, node: function() { var ID, fullID, keys, len, post, posts, qid, quote, quotes, uniq, _i, _len; + if (this.isClone || !QuoteThreading.enabled || this.thread.OP === this) { return; } @@ -4002,6 +4152,7 @@ }, nodeinsert: function() { var bottom, height, qpost, qroot, threadContainer, top, _ref; + qpost = g.posts[this.threaded]; delete this.threaded; delete this.cb; @@ -4030,6 +4181,7 @@ }, toggle: function() { var container, containers, node, post, replies, reply, thread, _i, _j, _k, _len, _len1, _len2, _ref; + thread = $('.thread'); replies = $$('.thread > .replyContainer, .threadContainer > .replyContainer', thread); QuoteThreading.enabled = this.checked; @@ -4046,6 +4198,7 @@ } else { replies.sort(function(a, b) { var aID, bID; + aID = Number(a.id.slice(2)); bID = Number(b.id.slice(2)); return aID - bID; @@ -4066,6 +4219,7 @@ }, kb: function() { var control; + control = $.id('threadingControl'); return control.click(); } @@ -4092,6 +4246,7 @@ }, node: function() { var quotelink, _i, _len, _ref; + if (this.isClone) { return; } @@ -4114,6 +4269,7 @@ cb: { seek: function(type) { var highlight, post, posts, result, str; + if (!(Conf['Mark Quotes of You'] && Conf['Quick Reply'])) { return; } @@ -4169,6 +4325,7 @@ }, node: function() { var deadlink, _i, _len, _ref; + _ref = $$('.deadlink', this.nodes.comment); for (_i = 0, _len = _ref.length; _i < _len; _i++) { deadlink = _ref[_i]; @@ -4183,6 +4340,7 @@ }, parseDeadlink: function(deadlink) { var a, boardID, m, post, postID, quote, quoteID, redirect, _ref; + if (deadlink.parentNode.className === 'prettyprint') { Quotify.fixDeadlink(deadlink); return; @@ -4275,6 +4433,7 @@ }, node: function() { var data, el, end, endNode, i, index, items, length, link, links, node, range, result, saved, snapshot, space, test, _i, _len, _ref; + if (this.isClone) { if (Conf['Embedding']) { i = 0; @@ -4353,6 +4512,7 @@ }, makeRange: function(startNode, endNode, startOffset, endOffset) { var range; + range = document.createRange(); range.setStart(startNode, startOffset); range.setEnd(endNode, endOffset); @@ -4360,6 +4520,7 @@ }, makeLink: function(range) { var a, char, i, text; + text = range.toString(); i = 0; while (/[(\[{<>]/.test(text.charAt(i))) { @@ -4403,6 +4564,7 @@ }, services: function(link) { var href, key, match, type, _ref; + href = link.href; _ref = Linkify.types; for (key in _ref) { @@ -4415,6 +4577,7 @@ }, embed: function(data) { var embed, href, key, link, name, options, uid, value, _ref; + key = data[0], uid = data[1], options = data[2], link = data[3]; href = link.href; embed = $.el('a', { @@ -4443,6 +4606,7 @@ }, title: function(data) { var embed, err, key, link, options, service, title, titles, uid; + key = data[0], uid = data[1], options = data[2], link = data[3], embed = data[4]; if (!(service = Linkify.types[key].title)) { return; @@ -4479,18 +4643,21 @@ cb: { toggle: function() { var string, _ref; + _ref = $.hasClass(this, "embedded") ? ['unembed', '(embed)'] : ['embed', '(unembed)'], string = _ref[0], this.textContent = _ref[1]; $.replace(this.previousElementSibling, Linkify.cb[string](this)); return $.toggleClass(this, 'embedded'); }, embed: function(a) { var el, style, type; + el = (type = Linkify.types[a.dataset.key]).el(a); el.style.cssText = (style = type.style) ? style : "border: 0; width: 640px; height: 390px"; return el; }, unembed: function(a) { var el; + el = $.el('a', { rel: 'nofollow noreferrer', target: 'blank', @@ -4503,6 +4670,7 @@ }, title: function(response, data) { var embed, key, link, options, service, text, uid; + key = data[0], uid = data[1], options = data[2], link = data[3], embed = data[4]; service = Linkify.types[key].title; switch (response.status) { @@ -4542,6 +4710,7 @@ regExp: /.*(?:gist.github.com.*\/)([^\/][^\/]*)$/, el: function(a) { var div; + return div = $.el('iframe', { src: "http://www.purplegene.com/script?url=https://gist.github.com/" + a.dataset.uid + ".js" }); @@ -4552,6 +4721,7 @@ }, text: function(_arg) { var file, files; + files = _arg.files; for (file in files) { if (files.hasOwnProperty(file)) { @@ -4599,6 +4769,7 @@ regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/, el: function(a) { var div; + return div = $.el('iframe', { src: "http://pastebin.com/embed_iframe.php?i=" + a.dataset.uid }); @@ -4609,6 +4780,7 @@ style: 'height: auto; width: 500px; display: inline-block;', el: function(a) { var div; + div = $.el('div', { className: "soundcloud", name: "soundcloud" @@ -4634,6 +4806,7 @@ style: "border: none; width: 640px; height: 360px;", el: function(a) { var channel, chapter, result, _; + if (result = /(\w+)\/(?:[a-z]\/)?(\d+)/i.exec(a.dataset.uid)) { _ = result[0], channel = result[1], chapter = result[2]; return $.el('object', { @@ -4705,6 +4878,7 @@ QR = { init: function() { var sc; + if (!Conf['Quick Reply']) { return; } @@ -4751,6 +4925,7 @@ }, initReady: function() { var link; + QR.postingIsEnabled = !!$.id('postForm'); if (!QR.postingIsEnabled) { return; @@ -4770,11 +4945,13 @@ $.before($.id('postForm'), link); $.on(d, 'QRGetSelectedPost', function(_arg) { var cb; + cb = _arg.detail; return cb(QR.selected); }); $.on(d, 'QRAddPreSubmitHook', function(_arg) { var cb; + cb = _arg.detail; return QR.preSubmitHooks.push(cb); }); @@ -4803,6 +4980,7 @@ }, open: function() { var err; + if (QR.nodes) { QR.nodes.el.hidden = false; QR.unhide(); @@ -4821,6 +4999,7 @@ }, close: function() { var post, _i, _len, _ref; + if (QR.req) { QR.abort(); return; @@ -4868,6 +5047,7 @@ }, error: function(err) { var el; + QR.open(); if (typeof err === 'string') { el = $.tn(err); @@ -4895,6 +5075,7 @@ notifications: [], cleanNotifications: function() { var notification, _i, _len, _ref; + _ref = QR.notifications; for (_i = 0, _len = _ref.length; _i < _len; _i++) { notification = _ref[_i]; @@ -4904,6 +5085,7 @@ }, status: function() { var disabled, status, thread, value; + if (!QR.nodes) { return; } @@ -4925,6 +5107,7 @@ QR.persona.getPassword(); return $.get('QR.personas', Conf['QR.personas'], function(_arg) { var arr, item, personas, type, types, _i, _len, _ref; + personas = _arg['QR.personas']; types = { name: [], @@ -4944,6 +5127,7 @@ }, parseItem: function(item, types) { var boards, match, type, val, _ref, _ref1; + if (item[0] === '#') { return; } @@ -4972,6 +5156,7 @@ }, loadPersonas: function(type, arr) { var list, val, _i, _len; + list = $("#list-" + type, QR.nodes.el); for (_i = 0, _len = arr.length; _i < _len; _i++) { val = arr[_i]; @@ -4984,6 +5169,7 @@ }, getPassword: function() { var input, m; + if (!QR.persona.pwd) { QR.persona.pwd = (m = d.cookie.match(/4chan_pass=([^;]+)/)) ? decodeURIComponent(m[1]) : (input = $.id('postPassword')) ? input.value : $.id('delPassword').value; } @@ -4992,6 +5178,7 @@ get: function(cb) { return $.get('QR.persona', {}, function(_arg) { var persona; + persona = _arg['QR.persona']; return cb(persona); }); @@ -4999,6 +5186,7 @@ set: function(post) { return $.get('QR.persona', {}, function(_arg) { var persona; + persona = _arg['QR.persona']; persona = { name: post.name, @@ -5012,6 +5200,7 @@ cooldown: { init: function() { var board; + if (!Conf['Cooldown']) { return; } @@ -5053,6 +5242,7 @@ }, sync: function(cooldowns) { var id; + for (id in cooldowns) { QR.cooldown.cooldowns[id] = cooldowns[id]; } @@ -5060,6 +5250,7 @@ }, set: function(data) { var cooldown, delay, hasFile, isReply, isSage, post, req, start, type, upSpd; + if (!Conf['Cooldown']) { return; } @@ -5099,6 +5290,7 @@ }, count: function() { var cooldown, cooldowns, elapsed, hasFile, isReply, isSage, now, post, seconds, start, type, types, upSpd, upSpdAccuracy, update, _ref; + if (!Object.keys(QR.cooldown.cooldowns).length) { $["delete"]("" + g.BOARD + ".cooldown"); delete QR.cooldown.isCounting; @@ -5152,6 +5344,7 @@ }, quote: function(e) { var caretPos, com, index, post, range, s, sel, text, thread, _ref; + if (e != null) { e.preventDefault(); } @@ -5189,6 +5382,7 @@ }, characterCount: function() { var count, counter; + counter = QR.nodes.charCount; count = QR.nodes.com.textLength; counter.textContent = count; @@ -5197,6 +5391,7 @@ }, drag: function(e) { var toggle; + toggle = e.type === 'dragstart' ? $.off : $.on; toggle(d, 'dragover', QR.dragOver); return toggle(d, 'drop', QR.dropFile); @@ -5216,6 +5411,7 @@ }, paste: function(e) { var blob, files, item, _i, _len, _ref; + files = []; _ref = e.clipboardData.items; for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -5243,6 +5439,7 @@ }, fileInput: function(files) { var file, length, max, post, _i, _len; + if (this instanceof Element) { files = __slice.call(this.files); QR.nodes.fileInput.value = null; @@ -5291,6 +5488,7 @@ function _Class(select) { var el, elm, event, prev, _i, _j, _len, _len1, _ref, _ref1, _this = this; + el = $.el('a', { className: 'qr-preview', draggable: true, @@ -5350,6 +5548,7 @@ _Class.prototype.rm = function() { var index; + this["delete"](); index = QR.posts.indexOf(this); if (QR.posts.length === 1) { @@ -5369,6 +5568,7 @@ _Class.prototype.lock = function(lock) { var name, _i, _len, _ref; + if (lock == null) { lock = true; } @@ -5393,6 +5593,7 @@ _Class.prototype.select = function() { var rectEl, rectList; + if (QR.selected) { QR.selected.nodes.el.id = null; QR.selected.forceSave(); @@ -5409,6 +5610,7 @@ _Class.prototype.load = function() { var name, _i, _len, _ref; + _ref = ['thread', 'name', 'email', 'sub', 'com']; for (_i = 0, _len = _ref.length; _i < _len; _i++) { name = _ref[_i]; @@ -5420,6 +5622,7 @@ _Class.prototype.save = function(input) { var name, _ref; + if (input.type === 'checkbox') { this.spoiler = input.checked; return; @@ -5440,6 +5643,7 @@ _Class.prototype.forceSave = function() { var name, _i, _len, _ref; + if (this !== QR.selected) { return; } @@ -5469,9 +5673,11 @@ _Class.prototype.setThumbnail = function() { var fileURL, img, _this = this; + img = $.el('img'); img.onload = function() { var cv, height, s, width; + s = 90 * 2; if (_this.file.type === 'image/gif') { s *= 3; @@ -5529,9 +5735,11 @@ _Class.prototype.pasteText = function(file) { var reader, _this = this; + reader = new FileReader(); reader.onload = function(e) { var text; + text = e.target.result; if (_this.com) { _this.com += "\n" + text; @@ -5569,6 +5777,7 @@ _Class.prototype.drop = function() { var el, index, newIndex, oldIndex, post; + $.rmClass(this, 'over'); if (!this.draggable) { return; @@ -5603,6 +5812,7 @@ ready: function() { var imgContainer, input, setLifetime, _this = this; + setLifetime = function(e) { return _this.lifetime = e.detail; }; @@ -5639,6 +5849,7 @@ }); $.get('captchas', [], function(_arg) { var captchas; + captchas = _arg.captchas; return _this.sync(captchas); }); @@ -5655,6 +5866,7 @@ }, getOne: function() { var captcha, challenge, response; + this.clear(); if (captcha = this.captchas.shift()) { challenge = captcha.challenge, response = captcha.response; @@ -5679,6 +5891,7 @@ }, save: function() { var response; + if (!(response = this.nodes.input.value.trim())) { return; } @@ -5693,6 +5906,7 @@ }, clear: function() { var captcha, i, now, _i, _len, _ref; + now = Date.now(); _ref = this.captchas; for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { @@ -5710,6 +5924,7 @@ }, load: function() { var challenge; + if (!this.nodes.challenge.firstChild) { return; } @@ -5722,6 +5937,7 @@ }, count: function() { var count; + count = this.captchas.length; this.nodes.input.placeholder = (function() { switch (count) { @@ -5754,6 +5970,7 @@ }, dialog: function() { var dialog, elm, i, items, mimeTypes, name, nodes, thread; + dialog = UI.dialog('qr', 'top:0;right:0;', "
×
No selected file×+
"); QR.nodes = nodes = { el: dialog, @@ -5872,6 +6089,7 @@ preSubmitHooks: [], submit: function(e) { var challenge, err, extra, filetag, hook, options, post, postData, response, textOnly, thread, threadID, _i, _len, _ref, _ref1; + if (e != null) { e.preventDefault(); } @@ -5985,6 +6203,7 @@ }, response: function() { var URL, ban, board, err, h1, isReply, m, post, postID, req, resDoc, threadID, _, _ref, _ref1; + req = QR.req; delete QR.req; post = QR.posts[0]; @@ -6082,6 +6301,7 @@ FappeTyme = { init: function() { var el, input; + if (!Conf['Fappe Tyme'] || g.VIEW === 'catalog' || g.BOARD === 'f') { return; } @@ -6133,6 +6353,7 @@ }, node: function() { var thumb, _ref; + if (!((_ref = this.file) != null ? _ref.isImage : void 0)) { return; } @@ -6157,6 +6378,7 @@ }, toggleAll: function() { var ID, file, func, post, _i, _len, _ref, _ref1; + $.event('CloseMenu'); if (ImageExpand.on = $.hasClass(ImageExpand.EAI, 'expand-all-shortcut')) { ImageExpand.EAI.className = 'contract-all-shortcut'; @@ -6190,6 +6412,7 @@ }, toggle: function(post) { var headRect, rect, root, thumb, x, y; + thumb = post.file.thumb; if (!(post.file.isExpanded || $.hasClass(thumb, 'expanding'))) { ImageExpand.expand(post); @@ -6199,6 +6422,7 @@ root = post.nodes.root; rect = (Conf['Advance on contract'] ? (function() { var next; + next = root; while (next = $.x("following::div[contains(@class,'postContainer')][1]", next)) { if ($('.stub', next) || next.offsetHeight === 0) { @@ -6229,6 +6453,7 @@ }, expand: function(post, src) { var img, thumb; + thumb = post.file.thumb; if (post.isHidden || post.file.isExpanded || $.hasClass(thumb, 'expanding')) { return; @@ -6256,6 +6481,7 @@ }, completeExpand: function(post) { var prev, thumb; + thumb = post.file.thumb; if (!$.hasClass(thumb, 'expanding')) { return; @@ -6269,6 +6495,7 @@ prev = post.nodes.root.getBoundingClientRect(); return $.queueTask(function() { var curr; + $.addClass(post.nodes.root, 'expanded-image'); $.rmClass(post.file.thumb, 'expanding'); if (!(prev.top + prev.height <= 0)) { @@ -6280,6 +6507,7 @@ }, error: function() { var URL, post, src, timeoutID; + post = Get.postFromNode(this); $.rm(this); delete post.file.fullImage; @@ -6305,6 +6533,7 @@ return $.ajax("//api.4chan.org/" + post.board + "/res/" + post.thread + ".json", { onload: function() { var postObj, _i, _len, _ref; + if (this.status !== 200) { return; } @@ -6328,6 +6557,7 @@ menu: { init: function() { var conf, createSubEntry, el, name, subEntries, _ref; + if (g.VIEW === 'catalog' || !Conf['Image Expansion']) { return; } @@ -6351,6 +6581,7 @@ }, createSubEntry: function(name, desc) { var input, label; + label = $.el('label', { innerHTML: " " + name, title: desc @@ -6384,6 +6615,7 @@ }, node: function() { var _ref; + if (!((_ref = this.file) != null ? _ref.isImage : void 0)) { return; } @@ -6391,6 +6623,7 @@ }, mouseover: function(e) { var el, post; + post = Get.postFromNode(this); el = $.el('img', { id: 'ihover', @@ -6412,6 +6645,7 @@ error: function() { var URL, post, src, timeoutID, _this = this; + if (!doc.contains(this)) { return; } @@ -6436,6 +6670,7 @@ return $.ajax("//api.4chan.org/" + post.board + "/res/" + post.thread + ".json", { onload: function() { var postObj, _i, _len, _ref; + if (this.status !== 200) { return; } @@ -6461,6 +6696,7 @@ ImageLoader = { init: function() { var prefetch; + if (g.VIEW === 'catalog') { return; } @@ -6487,6 +6723,7 @@ }, node: function() { var URL, img, string, style, thumb, type, _ref, _ref1; + if (this.isClone || this.isHidden || this.thread.isHidden || !((_ref = this.file) != null ? _ref.isImage : void 0)) { return; } @@ -6508,6 +6745,7 @@ }, toggle: function() { var enabled, id, post, _ref; + enabled = Conf['prefetch'] = this.checked; if (enabled) { _ref = g.threads["" + g.BOARD.ID + "." + g.THREADID].posts; @@ -6531,6 +6769,7 @@ }, node: function() { var thumb, _ref; + if (this.isClone || !((_ref = this.file) != null ? _ref.isSpoiler : void 0)) { return; } @@ -6543,6 +6782,7 @@ Sauce = { init: function() { var err, link, links, _i, _len, _ref; + if (g.VIEW === 'catalog' || !Conf['Sauce']) { return; } @@ -6572,6 +6812,7 @@ }, createSauceLink: function(link) { var m, text; + link = link.replace(/%(T?URL|MD5|board)/ig, function(parameter) { switch (parameter) { case '%TURL': @@ -6592,6 +6833,7 @@ }, node: function() { var link, nodes, _i, _len, _ref; + if (this.isClone || !this.file) { return; } @@ -6608,6 +6850,7 @@ ArchiveLink = { init: function() { var div, entry, type, _i, _len, _ref; + if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Archive Link']) { return; } @@ -6620,6 +6863,7 @@ order: 90, open: function(_arg) { var ID, board, thread; + ID = _arg.ID, thread = _arg.thread, board = _arg.board; return !!Redirect.to('thread', { postID: ID, @@ -6638,12 +6882,14 @@ }, createSubEntry: function(text, type) { var el, open; + el = $.el('a', { textContent: text, target: '_blank' }); open = type === 'post' ? function(_arg) { var ID, board, thread; + ID = _arg.ID, thread = _arg.thread, board = _arg.board; el.href = Redirect.to('thread', { postID: ID, @@ -6653,6 +6899,7 @@ return true; } : function(post) { var value; + value = Filter[type](post); if (!value) { return false; @@ -6675,6 +6922,7 @@ DeleteLink = { init: function() { var div, fileEl, fileEntry, postEl, postEntry; + if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Delete Link']) { return; } @@ -6702,6 +6950,7 @@ el: fileEl, open: function(_arg) { var file; + file = _arg.file; if (!file || file.isDead) { return false; @@ -6717,6 +6966,7 @@ order: 40, open: function(post) { var node; + if (post.isDead || post.board.ID === 'q') { return false; } @@ -6731,6 +6981,7 @@ }, "delete": function() { var fileOnly, form, link, post; + post = DeleteLink.post; if (DeleteLink.cooldown.counting === post) { return; @@ -6760,6 +7011,7 @@ }, load: function(link, post, fileOnly, resDoc) { var msg, s; + if (resDoc.title === '4chan - Banned') { s = 'Banned!'; } else if (msg = resDoc.getElementById('errmsg')) { @@ -6780,6 +7032,7 @@ cooldown: { start: function(post, node) { var length, seconds, _ref; + if (!((_ref = QR.db) != null ? _ref.get({ boardID: post.board.ID, threadID: post.thread.ID, @@ -6813,6 +7066,7 @@ DownloadLink = { init: function() { var a; + if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Download Link']) { return; } @@ -6826,6 +7080,7 @@ order: 100, open: function(_arg) { var file; + file = _arg.file; if (!file) { return false; @@ -6858,6 +7113,7 @@ }, makeButton: (function() { var a; + a = $.el('a', { className: 'menu-button brackets-wrap', innerHTML: '', @@ -6865,6 +7121,7 @@ }); return function() { var button; + button = a.cloneNode(true); $.on(button, 'click', Menu.toggle); return button; @@ -6872,6 +7129,7 @@ })(), toggle: function(e) { var post; + post = Get.postFromNode(this); return Menu.menu.toggle(e, this, post); } @@ -6880,6 +7138,7 @@ ReportLink = { init: function() { var a; + if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Report Link']) { return; } @@ -6901,6 +7160,7 @@ }, report: function() { var id, post, set, url; + post = ReportLink.post; url = "//sys.4chan.org/" + post.board + "/imgboard.php?mode=report&no=" + post; id = Date.now(); @@ -6913,6 +7173,7 @@ init: function() { return $.ready(function() { var href; + Favicon.el = $('link[rel="shortcut icon"]', d.head); Favicon.el.type = 'image/x-icon'; href = Favicon.el.href; @@ -6985,6 +7246,7 @@ init: function() { var sc, _this = this; + if (g.VIEW !== 'thread' || !Conf['Thread Stats']) { return; } @@ -7013,6 +7275,7 @@ }, node: function() { var ID, fileCount, post, postCount, _ref; + postCount = 0; fileCount = 0; _ref = this.posts; @@ -7030,6 +7293,7 @@ }, onUpdate: function(e) { var fileCount, postCount, _ref; + if (e.detail[404]) { return; } @@ -7038,6 +7302,7 @@ }, update: function(postCount, fileCount) { var fileCountEl, postCountEl, thread; + thread = ThreadStats.thread, postCountEl = ThreadStats.postCountEl, fileCountEl = ThreadStats.fileCountEl; postCountEl.textContent = postCount; fileCountEl.textContent = fileCount; @@ -7062,6 +7327,7 @@ }, onThreadsLoad: function() { var page, pages, thread, _i, _j, _len, _len1, _ref; + if (!(Conf["Page Count in Stats"] && this.status === 200)) { return; } @@ -7085,6 +7351,7 @@ init: function() { var checked, conf, el, input, name, sc, settings, subEntries, _ref, _this = this; + if (g.VIEW !== 'thread' || !Conf['Thread Updater']) { return; } @@ -7234,6 +7501,7 @@ }, interval: function() { var val; + val = +this.value; if (val < 1) { val = 1; @@ -7243,6 +7511,7 @@ }, load: function() { var klass, req, text, _ref; + req = ThreadUpdater.req; switch (req.status) { case 200: @@ -7275,6 +7544,7 @@ }, getInterval: function() { var i, j; + i = ThreadUpdater.interval; j = Math.min(ThreadUpdater.outdateCount, 10); if (!d.hidden) { @@ -7284,12 +7554,14 @@ }, intervalShortcut: function() { var settings; + Settings.open('Advanced'); settings = $.id('fourchanx-settings'); return $('input[name=Interval]', settings).focus(); }, set: function(name, text, klass) { var el, node; + el = ThreadUpdater[name]; if (node = el.firstChild) { node.data = text; @@ -7302,6 +7574,7 @@ }, timeout: function() { var n; + ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.timeout, 1000); if (!(n = --ThreadUpdater.seconds)) { return ThreadUpdater.update(); @@ -7314,6 +7587,7 @@ }, update: function() { var url; + if (!ThreadUpdater.online) { return; } @@ -7336,6 +7610,7 @@ }, updateThreadStatus: function(title, OP) { var icon, message, root, titleLC; + titleLC = title.toLowerCase(); if (ThreadUpdater.thread["is" + title] === !!OP[titleLC]) { return; @@ -7362,6 +7637,7 @@ }, parse: function(postObjects) { var ID, OP, count, deletedFiles, deletedPosts, files, index, key, node, num, post, postObject, posts, root, scroll, _i, _len, _ref; + OP = postObjects[0]; Build.spoilerRange[ThreadUpdater.thread.board] = OP.custom_spoiler; ThreadUpdater.updateThreadStatus('Sticky', OP); @@ -7447,6 +7723,7 @@ } $.queueTask(function() { var length, threadID; + threadID = ThreadUpdater.thread.ID; length = $$('.thread > .postContainer', ThreadUpdater.root).length; return Fourchan.parseThread(threadID, length - count, length); @@ -7467,6 +7744,7 @@ ThreadWatcher = { init: function() { var now, sc; + if (!Conf['Thread Watcher']) { return; } @@ -7499,6 +7777,7 @@ } $.get('WatchedThreads', null, function(_arg) { var WatchedThreads, boardID, data, threadID, threads, _ref; + WatchedThreads = _arg.WatchedThreads; if (!WatchedThreads) { return; @@ -7524,6 +7803,7 @@ }, node: function() { var toggler; + toggler = $.el('img', { className: 'watch-thread-link' }); @@ -7545,6 +7825,7 @@ } return $.get('AutoWatch', 0, function(_arg) { var AutoWatch, thread; + AutoWatch = _arg.AutoWatch; if (!(thread = g.BOARD.threads[AutoWatch])) { return; @@ -7560,6 +7841,7 @@ cb: { openAll: function() { var a, _i, _len, _ref; + if ($.hasClass(this, 'disabled')) { return; } @@ -7578,6 +7860,7 @@ }, pruneDeads: function() { var boardID, data, threadID, _i, _len, _ref, _ref1; + if ($.hasClass(this, 'disabled')) { return; } @@ -7601,11 +7884,13 @@ }, rm: function() { var boardID, threadID, _ref; + _ref = this.parentNode.dataset.fullID.split('.'), boardID = _ref[0], threadID = _ref[1]; return ThreadWatcher.rm(boardID, +threadID); }, post: function(e) { var board, postID, threadID, _ref; + _ref = e.detail, board = _ref.board, postID = _ref.postID, threadID = _ref.threadID; if (postID === threadID) { if (Conf['Auto Watch']) { @@ -7617,6 +7902,7 @@ }, threadUpdate: function(e) { var thread; + thread = e.detail.thread; if (!(e.detail[404] && ThreadWatcher.db.get({ boardID: thread.board.ID, @@ -7633,6 +7919,7 @@ }, fetchAllStatus: function() { var thread, threads, _i, _len; + if (!(threads = ThreadWatcher.getAll()).length) { return; } @@ -7644,6 +7931,7 @@ }, fetchStatus: function(_arg) { var boardID, data, fetchCount, threadID; + boardID = _arg.boardID, threadID = _arg.threadID, data = _arg.data; if (data.isDead) { return; @@ -7653,6 +7941,7 @@ return $.ajax("//api.4chan.org/" + boardID + "/res/" + threadID + ".json", { onloadend: function() { var status; + fetchCount.fetched++; if (fetchCount.fetched === fetchCount.fetching) { fetchCount.fetched = 0; @@ -7683,6 +7972,7 @@ }, getAll: function() { var all, boardID, data, threadID, threads, _ref; + all = []; _ref = ThreadWatcher.db.data.boards; for (boardID in _ref) { @@ -7703,6 +7993,7 @@ }, makeLine: function(boardID, threadID, data) { var div, fullID, href, link, x; + x = $.el('a', { textContent: '×', href: 'javascript:;' @@ -7733,6 +8024,7 @@ }, refresh: function() { var boardID, data, list, nodes, refresher, thread, threadID, toggler, watched, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3; + nodes = []; _ref = ThreadWatcher.getAll(); for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -7760,6 +8052,7 @@ }, toggle: function(thread) { var boardID, threadID; + boardID = thread.board.ID; threadID = thread.ID; if (ThreadWatcher.db.get({ @@ -7773,6 +8066,7 @@ }, add: function(thread) { var boardID, data, threadID; + data = {}; boardID = thread.board.ID; threadID = thread.ID; @@ -7803,6 +8097,7 @@ }, convert: function(oldFormat) { var boardID, data, newFormat, threadID, threads; + newFormat = {}; for (boardID in oldFormat) { threads = oldFormat[boardID]; @@ -7819,6 +8114,7 @@ refreshers: [], init: function() { var menu; + if (!Conf['Thread Watcher']) { return; } @@ -7831,6 +8127,7 @@ }, addHeaderMenuEntry: function() { var entryEl; + if (g.VIEW !== 'thread') { return; } @@ -7847,6 +8144,7 @@ }); return this.refreshers.push(function() { var addClass, rmClass, text, _ref; + _ref = $('.current', ThreadWatcher.list) ? ['unwatch-thread', 'watch-thread', 'Unwatch thread'] : ['watch-thread', 'unwatch-thread', 'Watch thread'], addClass = _ref[0], rmClass = _ref[1], text = _ref[2]; $.addClass(entryEl, addClass); $.rmClass(entryEl, rmClass); @@ -7855,6 +8153,7 @@ }, addMenuEntries: function() { var cb, conf, entries, entry, name, refresh, subEntries, _i, _len, _ref, _ref1, _results; + entries = []; entries.push({ cb: ThreadWatcher.cb.openAll, @@ -7925,6 +8224,7 @@ }, createSubEntry: function(name, desc) { var entry, input; + entry = { type: 'thread watcher', el: $.el('label', { @@ -7976,6 +8276,7 @@ }, ready: function() { var ID, post, posts, _ref; + $.off(d, '4chanXInitFinished', Unread.ready); posts = []; _ref = Unread.thread.posts; @@ -7992,6 +8293,7 @@ }, scroll: function() { var checkPosition, hash, onload, post, posts, root; + if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) { return; } @@ -8021,6 +8323,7 @@ } checkPosition = function(target) { var height, top, _ref; + _ref = target.getBoundingClientRect(), top = _ref.top, height = _ref.height; return top + height - doc.clientHeight > 0; }; @@ -8028,6 +8331,7 @@ }, sync: function() { var lastReadPost; + lastReadPost = Unread.db.get({ boardID: Unread.thread.board.ID, threadID: Unread.thread.ID, @@ -8044,6 +8348,7 @@ }, addPosts: function(posts) { var ID, data, post, _i, _len; + for (_i = 0, _len = posts.length; _i < _len; _i++) { post = posts[_i]; ID = post.ID; @@ -8071,6 +8376,7 @@ }, addPostQuotingYou: function(post) { var quotelink, _i, _len, _ref; + if (!QR.db) { return; } @@ -8091,6 +8397,7 @@ }, readSinglePost: function(post) { var i; + if ((i = Unread.posts.indexOf(post)) === -1) { return; } @@ -8106,6 +8413,7 @@ }, readArray: function(arr) { var i, post, _i, _len; + for (i = _i = 0, _len = arr.length; _i < _len; i = ++_i) { post = arr[i]; if (post.ID > Unread.lastReadPost) { @@ -8116,6 +8424,7 @@ }, read: $.debounce(50, function(e) { var ID, bottom, height, i, post, posts; + if (d.hidden || !Unread.posts.length) { return; } @@ -8171,6 +8480,7 @@ }), setLine: function(force) { var post, root; + if (!(d.hidden || force === true)) { return; } @@ -8185,6 +8495,7 @@ }, update: function() { var count; + count = Unread.posts.length; if (Conf['Unread Count']) { d.title = "" + (Conf['Quoted Title'] && Unread.postsQuotingYou.length ? '(!) ' : '') + (count || !Conf['Hide Unread Count at (0)'] ? "(" + count + ") " : '') + (g.DEAD ? "/" + g.BOARD + "/ - 404" : "" + Unread.title); @@ -8205,6 +8516,7 @@ }, init: function() { var archive, boardID, boards, data, id, name, type, _i, _len, _ref, _ref1, _ref2; + _ref = Conf['selectedArchives']; for (boardID in _ref) { data = _ref[boardID]; @@ -8336,6 +8648,7 @@ }, to: function(dest, data) { var archive; + archive = (dest === 'search' ? Redirect.data.thread : Redirect.data[dest])[data.boardID]; if (!archive) { return ''; @@ -8344,6 +8657,7 @@ }, protocol: function(archive) { var protocol; + protocol = location.protocol; if (!archive[protocol.slice(0, -1)]) { protocol = protocol === 'https:' ? 'http:' : 'https:'; @@ -8352,6 +8666,7 @@ }, thread: function(archive, _arg) { var boardID, path, postID, threadID; + boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID; path = threadID ? "" + boardID + "/thread/" + threadID : "" + boardID + "/post/" + postID; if (archive.software === 'foolfuuka') { @@ -8364,6 +8679,7 @@ }, post: function(archive, _arg) { var URL, boardID, postID, protocol; + boardID = _arg.boardID, postID = _arg.postID; protocol = Redirect.protocol(archive); if (['Foolz', 'NSFW Foolz'].contains(archive.name)) { @@ -8375,11 +8691,13 @@ }, file: function(archive, _arg) { var boardID, filename; + boardID = _arg.boardID, filename = _arg.filename; return "" + (Redirect.protocol(archive)) + archive.domain + "/" + boardID + "/full_image/" + filename; }, search: function(archive, _arg) { var boardID, path, type, value; + boardID = _arg.boardID, type = _arg.type, value = _arg.value; type = type === 'name' ? 'username' : type === 'MD5' ? 'image' : type; value = encodeURIComponent(value); @@ -8398,6 +8716,7 @@ }, setup: function() { var btn, entry, psa; + $.off(d, '4chanXInitFinished', PSAHiding.setup); if (!(psa = $.id('globalMessage'))) { $.rmClass(doc, 'hide-announcement'); @@ -8426,6 +8745,7 @@ $.on(btn, 'click', PSAHiding.toggle); $.get('hiddenPSA', 0, function(_arg) { var hiddenPSA; + hiddenPSA = _arg.hiddenPSA; PSAHiding.sync(hiddenPSA); $.before(psa, btn); @@ -8435,6 +8755,7 @@ }, toggle: function(e) { var UTC; + if ($.hasClass(this, 'hide-announcement')) { UTC = +$.id('globalMessage').dataset.utc; $.set('hiddenPSA', UTC); @@ -8446,6 +8767,7 @@ }, sync: function(UTC) { var hr, psa; + psa = $.id('globalMessage'); psa.hidden = PSAHiding.btn.hidden = UTC && UTC >= +psa.dataset.utc ? true : false; if ((hr = psa.nextElementSibling) && hr.nodeName === 'HR') { @@ -8466,6 +8788,7 @@ }, ready: function() { var banner, child, children, i; + banner = $(".boardBanner"); children = banner.children; i = 0; @@ -8478,22 +8801,27 @@ } if (Conf['Custom Board Titles']) { Banner.custom(child).title = "Ctrl+click to edit board " + (i === 3 ? 'sub' : '') + "title"; - Banner.custom(child).spellcheck = false; + child.spellcheck = false; } } }, cb: { - toggle: function() { - var num, type, types; + toggle: (function() { + var types; + types = { jpg: 227, png: 270, gif: 253 }; - type = Object.keys(types)[Math.floor(3 * Math.random())]; - num = Math.floor(types[type] * Math.random()); - return this.src = "//static.4chan.org/image/title/" + num + "." + type; - }, + return function() { + var num, type; + + type = Object.keys(types)[Math.floor(3 * Math.random())]; + num = Math.floor(types[type] * Math.random()); + return this.src = "//static.4chan.org/image/title/" + num + "." + type; + }; + })(), click: function(e) { if (e.ctrlKey) { this.contentEditable = true; @@ -8508,6 +8836,7 @@ }, focus: function() { var items, string, string2; + this.textContent = this.innerHTML; string = "" + g.BOARD + "." + this.className; string2 = "" + string + ".orig"; @@ -8530,6 +8859,7 @@ }, custom: function(child) { var cachedTest, string; + cachedTest = child.innerHTML; string = "" + g.BOARD + "." + child.className; $.on(child, 'click keydown focus blur', function(e) { @@ -8537,6 +8867,7 @@ }); $.get(string, cachedTest, function(item) { var string2, title; + if (!(title = item[string])) { return; } @@ -8560,6 +8891,7 @@ CatalogLinks = { init: function() { var el, input; + if (!Conf['Catalog Links']) { return; } @@ -8583,12 +8915,14 @@ }, toggle: function() { var useCatalog; + $.event('CloseMenu'); $.set('Header catalog links', useCatalog = this.checked); return CatalogLinks.set(useCatalog); }, set: function(useCatalog) { var a, board, path, _i, _len, _ref; + path = useCatalog ? 'catalog' : ''; _ref = $$("#board-list a[href*=\"boards.4chan.org\"]:not(.catalog),\n#boardNavDesktopFoot a[href*=\"boards.4chan.org\"]"); for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -8623,6 +8957,7 @@ }, node: function() { var str, uid; + if (this.isClone || !(str = this.info.uniqueID)) { return; } @@ -8634,6 +8969,7 @@ }, compute: function(str) { var hash, rgb; + hash = IDColor.hash(str); rgb = [(hash >> 24) & 0xFF, (hash >> 16) & 0xFF, (hash >> 8) & 0xFF]; rgb[3] = ((rgb[0] * 0.299) + (rgb[1] * 0.587) + (rgb[2] * 0.114)) > 125; @@ -8645,6 +8981,7 @@ }, hash: function(str) { var i, msg; + msg = 0; i = 0; while (i < 8) { @@ -8690,6 +9027,7 @@ }, node: function() { var dicestats, roll, _ref; + if (this.isClone || !(dicestats = (_ref = this.info.email) != null ? _ref.match(/dice[+\s](\d+)d(\d+)/) : void 0)) { return; } @@ -8701,6 +9039,7 @@ Emoji = { init: function() { var css, icon, name, pos, _ref; + if (!Conf['Emoji']) { return; } @@ -8770,6 +9109,7 @@ }, node: function() { var a; + if (a = $('.abbr > a:not([onclick])', this.nodes.comment)) { return $.on(a, 'click', ExpandComment.cb); } @@ -8781,6 +9121,7 @@ }, expand: function(post) { var a; + if (post.nodes.longComment && !post.nodes.longComment.parentNode) { $.replace(post.nodes.shortComment, post.nodes.longComment); post.nodes.comment = post.nodes.longComment; @@ -8796,6 +9137,7 @@ }, contract: function(post) { var a; + if (!post.nodes.shortComment) { return; } @@ -8806,6 +9148,7 @@ }, parse: function(req, a, post) { var callback, clone, comment, href, postObj, posts, quote, spoilerRange, status, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; + status = req.status; if (![200, 304].contains(status)) { a.textContent = "Error " + req.statusText + " (" + status + ")"; @@ -8868,6 +9211,7 @@ }, node: function() { var a, files, posts, span, _ref; + if (!(span = $.x('following-sibling::span[contains(@class,"summary")][1]', this.OP.nodes.root))) { return; } @@ -8888,6 +9232,7 @@ }, toggle: function(thread) { var a, files, filesCount, inlined, num, post, posts, postsCount, reply, threadRoot, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _ref4; + threadRoot = thread.OP.nodes.root.parentNode; a = $('.summary', threadRoot); switch (thread.isExpanded) { @@ -8965,6 +9310,7 @@ }, parse: function(req, thread, a) { var filesCount, link, post, posts, postsCount, postsObj, postsRoot, reply, root, spoilerRange, _i, _len; + if (a.textContent[0] === '+') { return; } @@ -9028,6 +9374,7 @@ }, createFunc: function(format) { var code; + code = format.replace(/%(.)/g, function(s, c) { if (c in FileInfo.formatters) { return "' + FileInfo.formatters." + c + ".call(post) + '"; @@ -9039,6 +9386,7 @@ }, convertUnit: function(size, unit) { var i; + if (unit === 'B') { return "" + (size.toFixed()) + " Bytes"; } @@ -9069,6 +9417,7 @@ }, n: function() { var fullname, shortname; + fullname = this.file.name; shortname = Build.shortFilename(this.file.name, this.isReply); if (fullname === shortname) { @@ -9112,6 +9461,7 @@ Fourchan = { init: function() { var board; + if (g.VIEW === 'catalog') { return; } @@ -9133,6 +9483,7 @@ }, code: function() { var pre, _i, _len, _ref; + if (this.isClone) { return; } @@ -9162,11 +9513,13 @@ Keybinds = { init: function() { var init; + if (g.VIEW === 'catalog' || !Conf['Keybinds']) { return; } init = function() { var node, _i, _len, _ref; + $.off(d, '4chanXInitFinished', init); $.on(d, 'keydown', Keybinds.keydown); _ref = $$('[accesskey]'); @@ -9179,6 +9532,7 @@ }, keydown: function(e) { var form, key, notification, notifications, op, target, thread, threadRoot, _i, _len; + if (!(key = Keybinds.keyCode(e))) { return; } @@ -9356,6 +9710,7 @@ }, keyCode: function(e) { var kc, key; + key = (function() { switch (kc = e.keyCode) { case 8: @@ -9411,6 +9766,7 @@ }, tags: function(tag, ta) { var range, selEnd, selStart, value; + value = ta.value; selStart = ta.selectionStart; selEnd = ta.selectionEnd; @@ -9421,11 +9777,13 @@ }, sage: function() { var isSage; + isSage = /sage/i.test(QR.nodes.email.value); return QR.nodes.email.value = isSage ? "" : "sage"; }, img: function(thread, all) { var post; + if (all) { return ImageExpand.cb.toggleAll(); } else { @@ -9435,6 +9793,7 @@ }, open: function(thread, tab) { var url; + if (g.VIEW !== 'index') { return; } @@ -9447,6 +9806,7 @@ }, hl: function(delta, thread) { var axe, headRect, next, postEl, rect, replies, reply, root, topMargin, _i, _len; + if (!delta) { if (postEl = $('.reply.highlight', thread)) { $.rmClass(postEl, 'highlight'); @@ -9506,6 +9866,7 @@ Nav = { init: function() { var append, next, prev, span; + switch (g.VIEW) { case 'index': if (!Conf['Index Navigation']) { @@ -9556,6 +9917,7 @@ }, getThread: function(full) { var headRect, i, rect, thread, threads, topMargin, _i, _len; + if (Conf['Bottom header'] || !Conf['Fixed Header']) { topMargin = 0; } else { @@ -9581,6 +9943,7 @@ }, scroll: function(delta) { var i, rect, thread, threads, top, topMargin, _ref, _ref1; + _ref = Nav.getThread(true), threads = _ref[0], thread = _ref[1], i = _ref[2], rect = _ref[3], topMargin = _ref[4]; top = rect.top - topMargin; if ((delta === -1 && top > -5) || (delta === +1 && top < 5)) { @@ -9605,6 +9968,7 @@ }, node: function() { var dateEl; + if (this.isClone) { return; } @@ -9614,6 +9978,7 @@ }, relative: function(diff, now, date) { var days, months, number, rounded, unit, years; + unit = (number = diff / $.DAY) >= 1 ? (years = now.getYear() - date.getYear(), months = now.getMonth() - date.getMonth(), days = now.getDate() - date.getDate(), years > 1 ? (number = years - (months < 0 || months === 0 && days < 0), 'year') : years === 1 && (months > 0 || months === 0 && days >= 0) ? (number = years, 'year') : (months = (months + 12) % 12) > 1 ? (number = months - (days < 0), 'month') : months === 1 && days >= 0 ? (number = months, 'month') : 'day') : (number = diff / $.HOUR) >= 1 ? 'hour' : (number = diff / $.MINUTE) >= 1 ? 'minute' : (number = Math.max(0, diff) / $.SECOND, 'second'); rounded = Math.round(number); if (rounded !== 1) { @@ -9624,6 +9989,7 @@ stale: [], flush: function() { var now, update, _i, _len, _ref; + if (d.hidden) { return; } @@ -9639,13 +10005,16 @@ }, setUpdate: function(post) { var markStale, setOwnTimeout, update; + setOwnTimeout = function(diff) { var delay; + delay = diff < $.MINUTE ? $.SECOND - (diff + $.SECOND / 2) % $.SECOND : diff < $.HOUR ? $.MINUTE - (diff + $.MINUTE / 2) % $.MINUTE : diff < $.DAY ? $.HOUR - (diff + $.HOUR / 2) % $.HOUR : $.DAY - (diff + $.DAY / 2) % $.DAY; return setTimeout(markStale, delay); }; update = function(now) { var date, diff, relative, singlePost, _i, _len, _ref; + date = post.info.date; diff = now - date; relative = RelativeDates.relative(diff, now, date); @@ -9686,6 +10055,7 @@ }, node: function(post) { var spoiler, spoilers, _i, _len; + spoilers = $$('s', this.nodes.comment); for (_i = 0, _len = spoilers.length; _i < _len; _i++) { spoiler = spoilers[_i]; @@ -9705,6 +10075,7 @@ }, ready: function() { var field; + field = $.id('recaptcha_response_field'); $.on(field, 'keydown', function(e) { if (e.keyCode === 8 && !field.value) { @@ -9713,6 +10084,7 @@ }); return $.on($('form'), 'submit', function(e) { var response; + e.preventDefault(); response = field.value.trim(); if (!/\s/.test(response)) { @@ -9742,6 +10114,7 @@ }, createFunc: function(format) { var code; + code = format.replace(/%([A-Za-z])/g, function(s, c) { if (c in Time.formatters) { return "' + Time.formatters." + c + ".call(date) + '"; @@ -9826,6 +10199,7 @@ Settings = { init: function() { var link, settings; + link = $.el('a', { className: 'settings-link', textContent: 'Settings', @@ -9835,6 +10209,7 @@ Header.addShortcut(link); $.get('previousversion', null, function(item) { var changelog, el, previous; + if (previous = item['previousversion']) { if (previous === g.VERSION) { return; @@ -9869,6 +10244,7 @@ }, open: function(openSection) { var dialog, html, link, links, overlay, section, sectionToOpen, _i, _len, _ref; + $.off(d, '4chanXInitFinished', Settings.open); if (Settings.dialog) { return; @@ -9921,6 +10297,7 @@ sections: [], addSection: function(title, open) { var hyphenatedTitle, _ref; + if (typeof title !== 'string') { _ref = title.detail, title = _ref.title, open = _ref.open; } @@ -9933,6 +10310,7 @@ }, openSection: function() { var section, selected; + if (selected = $('.tab-selected', Settings.dialog)) { $.rmClass(selected, 'tab-selected'); } @@ -9946,6 +10324,7 @@ }, main: function(section) { var arr, button, description, div, fs, hiddenNum, input, inputs, items, key, obj, _ref; + items = {}; inputs = {}; _ref = Config.main; @@ -9970,6 +10349,7 @@ } $.get(items, function(items) { var val; + for (key in items) { val = items[key]; inputs[key].checked = val; @@ -9984,6 +10364,7 @@ boards: {} }, function(item) { var ID, board, thread, _ref1; + _ref1 = item.hiddenThreads.boards; for (ID in _ref1) { board = _ref1[ID]; @@ -9998,6 +10379,7 @@ boards: {} }, function(item) { var ID, board, post, thread, _ref1; + _ref1 = item.hiddenPosts.boards; for (ID in _ref1) { board = _ref1[ID]; @@ -10017,6 +10399,7 @@ boards: {} }, function(item) { var boardID; + for (boardID in item.hiddenThreads.boards) { localStorage.removeItem("4chan-hide-t-" + boardID); } @@ -10027,6 +10410,7 @@ }, "export": function(now, data) { var a, db, p, _i, _len; + if (typeof now !== 'number') { now = Date.now(); data = { @@ -10062,6 +10446,7 @@ }, onImport: function() { var file, output, reader; + if (!(file = this.files[0])) { return; } @@ -10073,6 +10458,7 @@ reader = new FileReader(); reader.onload = function(e) { var data, err; + try { data = JSON.parse(e.target.result); Settings.loadSettings(data); @@ -10089,6 +10475,7 @@ }, loadSettings: function(data) { var key, val, version, _ref; + version = data.version.split('.'); if (version[0] === '2') { data = Settings.convertSettings(data, { @@ -10176,6 +10563,7 @@ }, convertSettings: function(data, map) { var newKey, prevKey; + for (prevKey in map) { newKey = map[prevKey]; if (newKey) { @@ -10187,6 +10575,7 @@ }, filter: function(section) { var select; + section.innerHTML = "
"; select = $('select', section); $.on(select, 'change', Settings.selectFilter); @@ -10194,6 +10583,7 @@ }, selectFilter: function() { var div, name, ta; + div = this.nextElementSibling; if ((name = this.value) !== 'guide') { $.rmAll(div); @@ -10213,6 +10603,7 @@ }, sauce: function(section) { var ta; + section.innerHTML = "
Sauce is disabled.
Lines starting with a # will be ignored.
You can specify a display text by appending ;text:[text] to the URL.
    These parameters will be replaced by their corresponding values:\n
  • %TURL: Thumbnail URL.
  • %URL: Full image URL.
  • %MD5: MD5 hash.
  • %board: Current board.
"; ta = $('textarea', section); $.get('sauces', Conf['sauces'], function(item) { @@ -10222,6 +10613,7 @@ }, advanced: function(section) { var archive, boardID, boardOptions, boardSelect, boards, data, event, input, inputs, item, items, name, row, rows, ta, table, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3, _ref4; + section.innerHTML = "
Archiver
404 Redirect is disabled.
Thread redirectionPost fetchingFile redirection
Disabled selections indicate that only one archive is available for that board and redirection type.
Custom Board Navigation
New lines will be converted into spaces.

In the following examples for /g/, g can be changed to a different board ID (a, b, etc...), the current board (current), or the Status/Twitter link (status, @).
Board link: g
Title link: g-title
Board link (Replace with title when on that board): g-replace
Full text link: g-full
Custom text link: g-text:\"Install Gentoo\"
Index-only link: g-index
Catalog-only link: g-catalog
External link: external-text:\"Google\",\"http://www.google.com\"
Combinations are possible: g-index-text:\"Technology Index\"
Full board list toggle: toggle-all

[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"]
\n will give you
[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
\n if you are on /g/.\n
Time Formatting is disabled.
:
Supported format specifiers:
Day: %a, %A, %d, %e
Month: %m, %b, %B
Year: %y, %Y
Hour: %k, %H, %l, %I, %p, %P
Minute: %M
Second: %S
Quote Backlinks formatting is disabled.
:
File Info Formatting is disabled.
:
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
Spoiler indicator: %p
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
Resolution: %r (Displays 'PDF' for PDF files)
Quick Reply Personas is disabled.

\n One item per line.
\n Items will be added in the relevant input's auto-completion list.
\n Password items will always be used, since there is no password input.
\n Lines starting with a # will be ignored.\n

    You can use these settings with each item, separate them with semicolons:\n
  • Possible items are: name, email, subject and password.
  • Wrap values of items with quotes, like this: email:\"sage\".
  • Force values as defaults with the always keyword, for example: email:\"sage\";always.
  • Select specific boards for an item, separated with commas, for example: email:\"sage\";boards:jp;always.
Unread Favicon is disabled.
Emoji is disabled.
\n Sage Icon:
\n Position:
Thread Updater is disabled.
\n Interval:
"; items = {}; inputs = {}; @@ -10241,6 +10633,7 @@ $.on(ta, 'change', $.cb.value); $.get(items, function(items) { var key, val; + for (key in items) { val = items[key]; if (['emojiPos'].contains(key)) { @@ -10311,6 +10704,7 @@ }); $.get('selectedArchives', Conf['selectedArchives'], function(_arg) { var option, selectedArchives, type; + selectedArchives = _arg.selectedArchives; for (boardID in selectedArchives) { data = selectedArchives[boardID]; @@ -10325,6 +10719,7 @@ }, addArchiveCell: function(boardID, data, type) { var archive, i, length, options, select, td; + length = data[type].length; td = $.el('td', { className: 'archive-cell' @@ -10354,8 +10749,10 @@ }, saveSelectedArchive: function() { var _this = this; + return $.get('selectedArchives', Conf['selectedArchives'], function(_arg) { var selectedArchives, _name; + selectedArchives = _arg.selectedArchives; (selectedArchives[_name = _this.dataset.boardid] || (selectedArchives[_name] = {}))[_this.dataset.type] = _this.value; return $.set('selectedArchives', selectedArchives); @@ -10366,6 +10763,7 @@ }, time: function() { var funk; + funk = Time.createFunc(this.value); return this.nextElementSibling.textContent = funk(Time, new Date()); }, @@ -10374,6 +10772,7 @@ }, fileInfo: function() { var data, funk; + data = { isReply: true, file: { @@ -10412,6 +10811,7 @@ }, keybinds: function(section) { var arr, input, inputs, items, key, tbody, tr, _ref; + section.innerHTML = "
Keybinds are disabled.
Allowed keys: a-z, 0-9, Ctrl, Shift, Alt, Meta, Enter, Esc, Up, Down, Right, Left.
Press Backspace to disable a keybind.
ActionsKeybinds
"; tbody = $('tbody', section); items = {}; @@ -10432,6 +10832,7 @@ } return $.get(items, function(items) { var val; + for (key in items) { val = items[key]; inputs[key].value = val; @@ -10440,6 +10841,7 @@ }, keybind: function(e) { var key; + if (e.keyCode === 9) { return; } @@ -10456,8 +10858,10 @@ Main = { init: function() { var db, flatten, _i, _len; + flatten = function(parent, obj) { var key, val; + if (obj instanceof Array) { Conf[parent] = obj[0]; } else if (typeof obj === 'object') { @@ -10489,6 +10893,7 @@ }, initFeatures: function() { var init, pathname, _ref; + pathname = location.pathname.split('/'); g.BOARD = new Board(pathname[1]); if ((_ref = g.BOARD.ID) === 'z' || _ref === 'fk') { @@ -10516,6 +10921,7 @@ case 'images.4chan.org': $.ready(function() { var URL; + if (Conf['404 Redirect'] && ['4chan - Temporarily Offline', '4chan - 404 Not Found'].contains(d.title)) { Redirect.init(); pathname = location.pathname.split('/'); @@ -10532,6 +10938,7 @@ } init = function(features) { var err, module, name; + for (name in features) { module = features[name]; try { @@ -10610,6 +11017,7 @@ }, initStyle: function() { var mainStyleSheet, setStyle, style, styleSheets, _ref; + $.off(d, '4chanMainInit', Main.initStyle); if (!Main.isThisPageLegit() || $.hasClass(doc, 'fourchan-x')) { return; @@ -10631,6 +11039,7 @@ styleSheets = $$('link[rel="alternate stylesheet"]', d.head); setStyle = function() { var styleSheet, _i, _len; + $.rmClass(doc, style); for (_i = 0, _len = styleSheets.length; _i < _len; _i++) { styleSheet = styleSheets[_i]; @@ -10652,6 +11061,7 @@ }, initReady: function() { var board, err, errors, href, passLink, postRoot, posts, styleSelector, thread, threadRoot, threads, _i, _j, _len, _len1, _ref, _ref1; + if (['4chan - Temporarily Offline', '4chan - 404 Not Found'].contains(d.title)) { if (Conf['404 Redirect'] && g.VIEW === 'thread') { href = Redirect.to('thread', { @@ -10718,6 +11128,7 @@ }, callbackNodes: function(klass, nodes) { var callback, err, errors, i, len, node, _i, _len, _ref; + len = nodes.length; _ref = klass.prototype.callbacks; for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -10745,9 +11156,11 @@ }, callbackNodesDB: function(klass, nodes, cb) { var errors, func, i, len, node, queue, softTask; + queue = []; softTask = function() { var args, func, task; + task = queue.shift(); func = task[0]; args = Array.prototype.slice.call(task, 1); @@ -10766,6 +11179,7 @@ errors = null; func = function(node, i) { var callback, err, _i, _len, _ref; + _ref = klass.prototype.callbacks; for (_i = 0, _len = _ref.length; _i < _len; _i++) { callback = _ref[_i]; @@ -10799,6 +11213,7 @@ }, addCallback: function(e) { var Klass, obj; + obj = e.detail; if (typeof obj.callback.name !== 'string') { throw new Error("Invalid callback name: " + obj.callback.name); @@ -10818,6 +11233,7 @@ }, handleErrors: function(errors) { var div, error, logs, _i, _len; + if (!(errors instanceof Array)) { error = errors; } else if (errors.length === 1) { @@ -10832,6 +11248,7 @@ }); $.on(div.lastElementChild, 'click', function() { var _ref; + return _ref = this.textContent === 'show' ? ['hide', false] : ['show', true], this.textContent = _ref[0], logs.hidden = _ref[1], _ref; }); logs = $.el('div', { @@ -10845,6 +11262,7 @@ }, parseError: function(data) { var error, message; + Main.logError(data); message = $.el('div', { textContent: data.message @@ -10861,6 +11279,7 @@ }, isThisPageLegit: function() { var _ref; + if (!('thisPageIsLegit' in Main)) { Main.thisPageIsLegit = location.hostname === 'boards.4chan.org' && !$('link[href*="favicon-status.ico"]', d.head) && ((_ref = d.title) !== '4chan - Temporarily Offline' && _ref !== '4chan - Error' && _ref !== '504 Gateway Time-out'); } diff --git a/builds/crx/script.js b/builds/crx/script.js index a5aad866e..1725f97c0 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -331,6 +331,7 @@ Array.prototype.indexOf = function(object) { var i; + i = this.length; while (i--) { if (this[i] === object) { @@ -349,6 +350,7 @@ $.extend = function(object, properties) { var key, val; + for (key in properties) { val = properties[key]; if (!properties.hasOwnProperty(key)) { @@ -366,6 +368,7 @@ $.ready = function(fc) { var cb; + if (d.readyState !== 'loading') { $.queueTask(fc); return; @@ -379,6 +382,7 @@ $.formData = function(form) { var fd, key, val; + if (form instanceof HTMLFormElement) { return new FormData(form); } @@ -398,6 +402,7 @@ $.extend = function(object, properties) { var key, val; + for (key in properties) { val = properties[key]; object[key] = val; @@ -406,9 +411,11 @@ $.ajax = (function() { var lastModified; + lastModified = {}; return function(url, options, extra) { var form, r, sync, type, upCallbacks, whenModified; + if (extra == null) { extra = {}; } @@ -431,9 +438,11 @@ $.cache = (function() { var reqs; + reqs = {}; return function(url, cb, options) { var err, req, rm; + if (req = reqs[url]) { if (req.readyState === 4) { cb.call(req, req.evt); @@ -453,6 +462,7 @@ } $.on(req, 'load', function(e) { var _i, _len, _ref; + _ref = this.callbacks; for (_i = 0, _len = _ref.length; _i < _len; _i++) { cb = _ref[_i]; @@ -488,6 +498,7 @@ $.addStyle = function(css, id) { var style; + style = $.el('style', { id: id, textContent: css @@ -534,6 +545,7 @@ } else { return function(el) { var _ref; + return (_ref = el.parentNode) != null ? _ref.removeChild(el) : void 0; }; } @@ -541,6 +553,7 @@ $.rmAll = function(root) { var node; + while (node = root.firstChild) { root.removeChild(node); } @@ -556,6 +569,7 @@ $.nodes = function(nodes) { var frag, node, _i, _len; + if (!(nodes instanceof Array)) { return nodes; } @@ -589,6 +603,7 @@ $.el = function(tag, properties) { var el; + el = d.createElement(tag); if (properties) { $.extend(el, properties); @@ -598,6 +613,7 @@ $.on = function(el, events, handler) { var event, _i, _len, _ref; + _ref = events.split(' '); for (_i = 0, _len = _ref.length; _i < _len; _i++) { event = _ref[_i]; @@ -607,6 +623,7 @@ $.off = function(el, events, handler) { var event, _i, _len, _ref; + _ref = events.split(' '); for (_i = 0, _len = _ref.length; _i < _len; _i++) { event = _ref[_i]; @@ -630,6 +647,7 @@ $.debounce = function(wait, fn) { var args, exec, lastCall, that, timeout; + lastCall = 0; timeout = null; that = null; @@ -651,9 +669,11 @@ $.queueTask = (function() { var execTask, taskChannel, taskQueue; + taskQueue = []; execTask = function() { var args, func, task; + task = taskQueue.shift(); func = task[0]; args = Array.prototype.slice.call(task, 1); @@ -676,6 +696,7 @@ $.globalEval = function(code) { var script; + script = $.el('script', { textContent: code }); @@ -685,6 +706,7 @@ $.bytesToString = function(size) { var unit; + unit = 0; while (size >= 1024) { size /= 1024; @@ -700,6 +722,7 @@ $.item = function(key, val) { var item; + item = {}; item[key] = val; return item; @@ -710,6 +733,7 @@ $.sync = (function() { chrome.storage.onChanged.addListener(function(changes) { var cb, key; + for (key in changes) { if (cb = $.syncing[key]) { cb(changes[key].newValue); @@ -729,6 +753,7 @@ $.get = function(key, val, cb) { var count, done, items, localItems, syncItems; + if (typeof cb === 'function') { items = $.item(key, val); } else { @@ -748,6 +773,7 @@ count = 0; done = function(item) { var lastError; + lastError = chrome.runtime.lastError; if (lastError) { c.error(lastError, lastError.message || 'No message.'); @@ -769,10 +795,12 @@ $.set = (function() { var items, localItems, set; + items = {}; localItems = {}; set = $.debounce($.SECOND, function() { var err, key, _i, _len, _ref; + _ref = $.localKeys; for (_i = 0, _len = _ref.length; _i < _len; _i++) { key = _ref[_i]; @@ -857,6 +885,7 @@ function Post(root, thread, board, that) { var capcode, date, email, flag, info, name, post, subject, tripcode, uniqueID; + this.thread = thread; this.board = board; if (that == null) { @@ -932,6 +961,7 @@ Post.prototype.parseComment = function() { var bq, i, node, nodes, text; + bq = this.nodes.comment.cloneNode(true); nodes = $$('.abbr, .capcodeReplies, .exif, b', bq); i = 0; @@ -949,6 +979,7 @@ Post.prototype.parseQuotes = function() { var quotelink, _i, _len, _ref; + this.quotes = []; _ref = $$('.quotelink', this.nodes.comment); for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -959,6 +990,7 @@ Post.prototype.parseQuote = function(quotelink) { var fullID, match; + if (!(match = quotelink.href.match(/boards\.4chan\.org\/([^\/]+)\/res\/\d+#p(\d+)$/))) { return; } @@ -974,6 +1006,7 @@ Post.prototype.parseFile = function(that) { var alt, anchor, fileEl, fileInfo, size, thumb, unit; + if (!((fileEl = $('.file', this.nodes.post)) && (thumb = $('img[data-md5]', fileEl)))) { return; } @@ -1005,6 +1038,7 @@ Post.prototype.kill = function(file, now) { var clone, quotelink, strong, _i, _j, _len, _len1, _ref, _ref1; + now || (now = new Date()); if (file) { if (this.file.isDead) { @@ -1053,6 +1087,7 @@ Post.prototype.resurrect = function() { var clone, quotelink, strong, _i, _j, _len, _len1, _ref, _ref1; + delete this.isDead; delete this.timeOfDeath; $.rmClass(this.nodes.root, 'deleted-post'); @@ -1086,6 +1121,7 @@ Post.prototype.rmClone = function(index) { var clone, _i, _len, _ref; + this.clones.splice(index, 1); _ref = this.clones.slice(index); for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -1103,6 +1139,7 @@ function Clone(origin, context) { var file, info, inline, inlined, key, nodes, post, root, val, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3; + this.origin = origin; this.context = context; _ref = ['ID', 'fullID', 'board', 'thread', 'info', 'quotes', 'isReply']; @@ -1190,6 +1227,7 @@ function DataBoard(key, sync, dontClean) { var init, _this = this; + this.key = key; this.data = Conf[key]; $.sync(key, this.onSync.bind(this)); @@ -1212,6 +1250,7 @@ DataBoard.prototype["delete"] = function(_arg) { var boardID, postID, threadID; + boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID; if (postID) { delete this.data.boards[boardID][threadID][postID]; @@ -1232,6 +1271,7 @@ DataBoard.prototype.deleteIfEmpty = function(_arg) { var boardID, threadID; + boardID = _arg.boardID, threadID = _arg.threadID; if (threadID) { if (!Object.keys(this.data.boards[boardID][threadID]).length) { @@ -1247,6 +1287,7 @@ DataBoard.prototype.set = function(_arg) { var boardID, postID, threadID, val, _base, _base1, _base2; + boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID, val = _arg.val; if (postID !== void 0) { ((_base = ((_base1 = this.data.boards)[boardID] || (_base1[boardID] = {})))[threadID] || (_base[threadID] = {}))[postID] = val; @@ -1260,6 +1301,7 @@ DataBoard.prototype.get = function(_arg) { var ID, board, boardID, defaultValue, postID, thread, threadID, val, _i, _len; + boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID, defaultValue = _arg.defaultValue; if (board = this.data.boards[boardID]) { if (!threadID) { @@ -1283,6 +1325,7 @@ DataBoard.prototype.clean = function() { var boardID, now, val, _ref; + _ref = this.data.boards; for (boardID in _ref) { val = _ref[boardID]; @@ -1302,8 +1345,10 @@ DataBoard.prototype.ajaxClean = function(boardID) { var _this = this; + return $.cache("//api.4chan.org/" + boardID + "/threads.json", function(e) { var board, page, thread, threads, _i, _j, _len, _len1, _ref, _ref1; + if (e.target.status === 404) { _this["delete"](boardID); } else if (e.target.status === 200) { @@ -1391,8 +1436,10 @@ }, toBlob: function() { var _base; + return (_base = HTMLCanvasElement.prototype).toBlob || (_base.toBlob = function(cb) { var data, i, l, ui8a, _i; + data = atob(this.toDataURL().slice(22)); l = data.length; ui8a = new Uint8Array(l); @@ -1430,6 +1477,7 @@ init: function() { var barFixedToggler, barPositionToggler, customNavToggler, editCustomNav, footerToggler, headerToggler, linkJustifyToggler, menuButton, _this = this; + this.menu = new UI.Menu('header'); menuButton = $.el('span', { className: 'menu-button', @@ -1520,6 +1568,7 @@ }); return $.ready(function() { var a, cs; + _this.footer = $.id('boardNavDesktopFoot'); if (a = $("a[href*='/" + g.BOARD + "/']", $.id('boardNavDesktopFoot'))) { a.className = 'current'; @@ -1553,6 +1602,7 @@ }), setBoardList: function() { var a, boardList, btn, fourchannav, fullBoardList; + fourchannav = $.id('boardNavDesktop'); if (a = $("a[href*='/" + g.BOARD + "/']", fourchannav)) { a.className = 'current'; @@ -1574,6 +1624,7 @@ }, generateBoardList: function(text) { var as, list, nodes; + list = $('#custom-board-list', Header.bar); $.rmAll(list); if (!text) { @@ -1582,6 +1633,7 @@ as = $$('#full-board-list a[title]', Header.bar); nodes = text.match(/[\w@]+((-(all|title|replace|full|index|catalog|url:"[^"]+[^"]"|text:"[^"]+")|\,"[^"]+[^"]"))*|[^\w@]+/g).map(function(t) { var a, board, m, _i, _len; + if (/^[^\w@]/.test(t)) { return $.tn(t); } @@ -1632,6 +1684,7 @@ }, toggleBoardList: function() { var bar, custom, full, showBoardList; + bar = Header.bar; custom = $('#custom-board-list', bar); full = $('#full-board-list', bar); @@ -1667,6 +1720,7 @@ }, toggleLinkJustify: function() { var centered; + $.event('CloseMenu'); centered = this.nodeName === 'INPUT' ? this.checked : void 0; Header.setLinkJustify(centered); @@ -1696,6 +1750,7 @@ }, toggleBarVisibility: function() { var hide, message; + hide = this.nodeName === 'INPUT' ? this.checked : !$.hasClass(Header.bar, 'autohide'); this.checked = hide; $.set('Header auto-hide', Conf['Header auto-hide'] = hide); @@ -1709,6 +1764,7 @@ }, toggleFooterVisibility: function() { var hide, message; + $.event('CloseMenu'); hide = this.nodeName === 'INPUT' ? this.checked : !!Header.footer.hidden; Header.setFooterVisibility(hide); @@ -1718,6 +1774,7 @@ }, setCustomNav: function(show) { var btn, cust, full, _ref; + Header.customNavToggler.checked = show; cust = $('#custom-board-list', Header.bar); full = $('#full-board-list', Header.bar); @@ -1730,12 +1787,14 @@ }, editCustomNav: function() { var settings; + Settings.open('Advanced'); settings = $.id('fourchanx-settings'); return $('input[name=boardnav]', settings).focus(); }, hashScroll: function() { var hash, post; + if (!((hash = this.location.hash.slice(1)) && (post = $.id(hash)))) { return; } @@ -1746,6 +1805,7 @@ }, scrollToPost: function(post) { var headRect, top; + top = post.getBoundingClientRect().top; if (Conf['Fixed Header'] && !Conf['Bottom Header']) { headRect = Header.bar.getBoundingClientRect(); @@ -1755,6 +1815,7 @@ }, addShortcut: function(el) { var shortcut; + shortcut = $.el('span', { className: 'shortcut brackets-wrap' }); @@ -1766,6 +1827,7 @@ }, createNotification: function(e) { var cb, content, lifetime, notif, type, _ref; + _ref = e.detail, type = _ref.type, content = _ref.content, lifetime = _ref.lifetime, cb = _ref.cb; notif = new Notification(type, content, lifetime); if (cb) { @@ -1778,6 +1840,7 @@ spoilerRange: {}, shortFilename: function(filename, isReply) { var threshold; + threshold = isReply ? 30 : 40; if (filename.length - 4 > threshold) { return "" + filename.slice(0, threshold - 5) + "(...)." + filename.slice(-3); @@ -1787,6 +1850,7 @@ }, postFromObject: function(data, boardID) { var o; + o = { postID: data.no, threadID: data.resto || data.no, @@ -1831,6 +1895,7 @@ */ var a, boardID, capcode, capcodeClass, capcodeReplies, capcodeStart, closed, comment, container, date, dateUTC, email, emailEnd, emailStart, ext, file, fileDims, fileHTML, fileInfo, fileSize, fileThumb, filename, flag, flagCode, flagName, href, imgSrc, isClosed, isOP, isSticky, name, postID, quote, shortFilename, spoilerRange, staticPath, sticky, subject, threadID, tripcode, uniqueID, userID, _i, _len, _ref; + postID = o.postID, threadID = o.threadID, boardID = o.boardID, name = o.name, capcode = o.capcode, tripcode = o.tripcode, uniqueID = o.uniqueID, email = o.email, subject = o.subject, flagCode = o.flagCode, flagName = o.flagName, date = o.date, dateUTC = o.dateUTC, isSticky = o.isSticky, isClosed = o.isClosed, comment = o.comment, capcodeReplies = o.capcodeReplies, file = o.file; isOP = postID === threadID; staticPath = '//static.4chan.org/image/'; @@ -1929,6 +1994,7 @@ }, capcodeReplies: function(_arg) { var array, boardID, bq, capcodeReplies, capcodeType, generateCapcodeReplies, html, root, threadID; + boardID = _arg.boardID, threadID = _arg.threadID, bq = _arg.bq, root = _arg.root, capcodeReplies = _arg.capcodeReplies; if (!capcodeReplies) { return; @@ -1965,6 +2031,7 @@ Get = { threadExcerpt: function(thread) { var OP, excerpt, _ref; + OP = thread.OP; excerpt = ((_ref = OP.info.subject) != null ? _ref.trim() : void 0) || OP.info.comment.replace(/\n+/g, ' // ') || Conf['Anonymize'] && 'Anonymous' || $('.nameBlock', OP.nodes.info).textContent.trim(); if (excerpt.length > 70) { @@ -1980,6 +2047,7 @@ }, postFromRoot: function(root) { var boardID, index, link, post, postID; + link = $('a[title="Highlight this post"]', root); boardID = link.pathname.split('/')[1]; postID = link.hash.slice(2); @@ -1999,6 +2067,7 @@ }, postDataFromLink: function(link) { var boardID, path, postID, threadID, _ref; + if (link.hostname === 'boards.4chan.org') { path = link.pathname.split('/'); boardID = path[1]; @@ -2016,6 +2085,7 @@ }, allQuotelinksLinkingTo: function(post) { var ID, quote, quotedPost, quotelinks, quoterPost, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3; + quotelinks = []; _ref = g.posts; for (ID in _ref) { @@ -2044,12 +2114,14 @@ } return quotelinks.filter(function(quotelink) { var boardID, postID, _ref4; + _ref4 = Get.postDataFromLink(quotelink), boardID = _ref4.boardID, postID = _ref4.postID; return boardID === post.board.ID && postID === post.ID; }); }, postClone: function(boardID, threadID, postID, root, context) { var post, url; + if (post = g.posts["" + boardID + "." + postID]) { Get.insert(post, root, context); return; @@ -2072,6 +2144,7 @@ }, insert: function(post, root, context) { var clone, nodes; + if (!root.parentNode) { return; } @@ -2085,6 +2158,7 @@ }, fetchedPost: function(req, boardID, threadID, postID, root, context) { var board, post, posts, status, thread, url, _i, _len; + if (post = g.posts["" + boardID + "." + postID]) { Get.insert(post, root, context); return; @@ -2138,6 +2212,7 @@ }, archivedPost: function(req, boardID, postID, root, context) { var board, bq, comment, data, o, post, thread, threadID, _ref; + if (post = g.posts["" + boardID + "." + postID]) { Get.insert(post, root, context); return; @@ -2232,8 +2307,10 @@ UI = (function() { var Menu, dialog, drag, dragend, dragstart, hover, hoverend, hoverstart, touchend, touchmove; + dialog = function(id, position, html) { var child, el, move, _i, _len, _ref; + el = $.el('div', { className: 'dialog', innerHTML: html, @@ -2273,6 +2350,7 @@ Menu.prototype.makeMenu = function() { var menu; + menu = $.el('div', { className: 'dialog', id: 'menu', @@ -2287,6 +2365,7 @@ Menu.prototype.toggle = function(e, button, data) { var previousButton; + e.preventDefault(); e.stopPropagation(); if (currentMenu) { @@ -2304,6 +2383,7 @@ Menu.prototype.open = function(button, data) { var bLeft, bRect, bTop, bottom, cHeight, cWidth, entry, left, mRect, menu, right, style, top, _i, _len, _ref, _ref1, _ref2; + menu = this.makeMenu(); currentMenu = menu; lastToggledButton = button; @@ -2342,6 +2422,7 @@ Menu.prototype.insertEntry = function(entry, parent, data) { var subEntry, submenu, _i, _len, _ref; + if (typeof entry.open === 'function') { if (!entry.open(data)) { return; @@ -2375,6 +2456,7 @@ Menu.prototype.findNextEntry = function(entry, direction) { var entries; + entries = __slice.call(entry.parentNode.children); entries.sort(function(first, second) { return +(first.style.order || first.style.webkitOrder) - +(second.style.order || second.style.webkitOrder); @@ -2384,6 +2466,7 @@ Menu.prototype.keybinds = function(e) { var entry, next, nextPrev, subEntry, submenu; + entry = $('.focused', currentMenu); while (subEntry = $('.focused', entry)) { entry = subEntry; @@ -2429,6 +2512,7 @@ Menu.prototype.focus = function(entry) { var bottom, cHeight, cWidth, eRect, focused, left, right, sRect, style, submenu, top, _i, _len, _ref, _ref1, _ref2; + while (focused = $.x('parent::*/child::*[contains(@class,"focused")]', entry)) { $.rmClass(focused, 'focused'); } @@ -2456,6 +2540,7 @@ Menu.prototype.addEntry = function(e) { var entry; + entry = e.detail; if (entry.type !== this.type) { return; @@ -2466,6 +2551,7 @@ Menu.prototype.parseEntry = function(entry) { var el, style, subEntries, subEntry, _i, _len; + el = entry.el, subEntries = entry.subEntries; $.addClass(el, 'entry'); $.on(el, 'focus mouseover', (function(e) { @@ -2489,6 +2575,7 @@ })(); dragstart = function(e) { var el, isTouching, o, rect, screenHeight, screenWidth, _ref; + if (e.type === 'mousedown' && e.button !== 0) { return; } @@ -2527,6 +2614,7 @@ }; touchmove = function(e) { var touch, _i, _len, _ref; + _ref = e.changedTouches; for (_i = 0, _len = _ref.length; _i < _len; _i++) { touch = _ref[_i]; @@ -2538,6 +2626,7 @@ }; drag = function(e) { var bottom, clientX, clientY, left, right, style, top; + clientX = e.clientX, clientY = e.clientY; left = clientX - this.dx; left = left < 10 ? 0 : this.width - left < 10 ? null : left / this.screenWidth * 100 + '%'; @@ -2553,6 +2642,7 @@ }; touchend = function(e) { var touch, _i, _len, _ref; + _ref = e.changedTouches; for (_i = 0, _len = _ref.length; _i < _len; _i++) { touch = _ref[_i]; @@ -2574,6 +2664,7 @@ }; hoverstart = function(_arg) { var asapTest, cb, el, endEvents, latestEvent, o, root; + root = _arg.root, el = _arg.el, latestEvent = _arg.latestEvent, endEvents = _arg.endEvents, asapTest = _arg.asapTest, cb = _arg.cb; o = { root: root, @@ -2602,6 +2693,7 @@ }; hover = function(e) { var clientX, clientY, height, left, right, style, top, _ref; + this.latestEvent = e; height = this.el.offsetHeight; clientX = e.clientX, clientY = e.clientY; @@ -2644,6 +2736,7 @@ }, node: function() { var email, name, tripcode, _ref; + if (this.info.capcode || this.isClone) { return; } @@ -2670,6 +2763,7 @@ filters: {}, init: function() { var boards, err, filter, hl, key, op, regexp, stub, top, _i, _len, _ref, _ref1, _ref2, _ref3, _ref4; + if (g.VIEW === 'catalog' || !Conf['Filter']) { return; } @@ -2706,6 +2800,7 @@ op = ((_ref2 = filter.match(/[^t]op:(yes|no|only)/)) != null ? _ref2[1] : void 0) || 'yes'; stub = (function() { var _ref3; + switch ((_ref3 = filter.match(/stub:(yes|no)/)) != null ? _ref3[1] : void 0) { case 'yes': return true; @@ -2736,6 +2831,7 @@ }, createFilter: function(regexp, op, stub, hl, top) { var settings, test; + test = typeof regexp === 'string' ? function(value) { return regexp === value; } : function(value) { @@ -2759,6 +2855,7 @@ }, node: function() { var filter, firstThread, key, result, thisThread, value, _i, _len, _ref; + if (this.isClone) { return; } @@ -2870,6 +2967,7 @@ menu: { init: function() { var div, entry, type, _i, _len, _ref; + if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Filter']) { return; } @@ -2895,6 +2993,7 @@ }, createSubEntry: function(text, type) { var el; + el = $.el('a', { href: 'javascript:;', textContent: text @@ -2905,6 +3004,7 @@ el: el, open: function(post) { var value; + value = Filter[type](post); return value !== false; } @@ -2912,6 +3012,7 @@ }, makeFilter: function() { var re, type, value; + type = this.dataset.type; value = Filter[type](Filter.menu.post); re = ['uniqueID', 'MD5'].contains(type) ? value : value.replace(/\/|\\|\^|\$|\n|\.|\(|\)|\{|\}|\[|\]|\?|\*|\+|\|/g, function(c) { @@ -2926,6 +3027,7 @@ re = ['uniqueID', 'MD5'].contains(type) ? "/" + re + "/" : "/^" + re + "$/"; return $.get(type, Conf[type], function(item) { var save, section, select, ta, tl; + save = item[type]; save = save ? "" + save + "\n" + re : re; $.set(type, save); @@ -2959,6 +3061,7 @@ }, node: function() { var data; + if (!this.isReply || this.isClone) { return; } @@ -2982,6 +3085,7 @@ menu: { init: function() { var apply, div, hideStubLink, makeStub, replies, thisPost; + if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Reply Hiding Link']) { return; } @@ -3052,6 +3156,7 @@ order: 20, open: function(post) { var data; + if (!post.isReply || post.isClone || !post.isHidden) { return false; } @@ -3083,6 +3188,7 @@ order: 15, open: function(post) { var data; + if (!post.isReply || post.isClone || !post.isHidden) { return false; } @@ -3099,6 +3205,7 @@ }, hide: function() { var makeStub, parent, post, replies, thisPost; + parent = this.parentNode; thisPost = $('input[name=thisPost]', parent).checked; replies = $('input[name=replies]', parent).checked; @@ -3117,6 +3224,7 @@ }, show: function() { var data, parent, post, replies, thisPost; + parent = this.parentNode; thisPost = $('input[name=thisPost]', parent).checked; replies = $('input[name=replies]', parent).checked; @@ -3140,6 +3248,7 @@ }, hideStub: function() { var post; + post = PostHiding.menu.post; post.nodes.root.hidden = true; $.event('CloseMenu'); @@ -3147,6 +3256,7 @@ }, makeButton: function(post, type) { var a; + a = $.el('a', { className: "" + type + "-reply-button", innerHTML: " " + (type === 'hide' ? '-' : '+') + " ", @@ -3157,6 +3267,7 @@ }, saveHiddenState: function(post, isHiding, thisPost, makeStub, hideRecursively) { var data; + data = { boardID: post.board.ID, threadID: post.thread.ID, @@ -3175,12 +3286,14 @@ }, toggle: function() { var post; + post = Get.postFromNode(this); PostHiding[(post.isHidden ? 'show' : 'hide')](post); return PostHiding.saveHiddenState(post, post.isHidden); }, hide: function(post, makeStub, hideRecursively) { var a, button, postInfo, quotelink, _i, _len, _ref; + if (makeStub == null) { makeStub = Conf['Stubs']; } @@ -3215,6 +3328,7 @@ }, show: function(post, showRecursively) { var quotelink, _i, _len, _ref; + if (showRecursively == null) { showRecursively = Conf['Recursive Hiding']; } @@ -3250,6 +3364,7 @@ }, node: function() { var i, obj, quote, recursive, _i, _j, _len, _len1, _ref, _ref1; + if (this.isClone) { return; } @@ -3267,6 +3382,7 @@ }, add: function() { var args, obj, post, recursive, _base, _name; + recursive = arguments[0], post = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : []; obj = (_base = Recursive.recursives)[_name = post.fullID] || (_base[_name] = { recursives: [], @@ -3277,6 +3393,7 @@ }, rm: function(recursive, post) { var i, obj, rec, _i, _len, _ref; + if (!(obj = Recursive.recursives[post.fullID])) { return; } @@ -3291,6 +3408,7 @@ }, apply: function() { var ID, args, fullID, post, recursive, _ref; + recursive = arguments[0], post = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : []; fullID = post.fullID; _ref = g.posts; @@ -3317,6 +3435,7 @@ }, node: function() { var data; + if (data = ThreadHiding.db.get({ boardID: this.board.ID, threadID: this.ID @@ -3330,6 +3449,7 @@ }, syncCatalog: function() { var hiddenThreads, hiddenThreadsOnCatalog, threadID; + hiddenThreads = ThreadHiding.db.get({ boardID: g.BOARD.ID, defaultValue: {} @@ -3356,6 +3476,7 @@ cleanCatalog: function(hiddenThreadsOnCatalog) { return $.cache("//api.4chan.org/" + g.BOARD + "/threads.json", function() { var page, thread, threads, _i, _j, _len, _len1, _ref, _ref1; + if (this.status !== 200) { return; } @@ -3381,6 +3502,7 @@ menu: { init: function() { var apply, div, hideStubLink, makeStub; + if (g.VIEW !== 'index' || !Conf['Menu'] || !Conf['Thread Hiding Link']) { return; } @@ -3402,6 +3524,7 @@ order: 20, open: function(_arg) { var isReply, thread; + thread = _arg.thread, isReply = _arg.isReply; if (isReply || thread.isHidden) { return false; @@ -3429,6 +3552,7 @@ order: 20, open: function(_arg) { var isReply, thread; + thread = _arg.thread, isReply = _arg.isReply; if (isReply || !thread.isHidden) { return false; @@ -3448,6 +3572,7 @@ order: 15, open: function(_arg) { var isReply, thread; + thread = _arg.thread, isReply = _arg.isReply; if (isReply || !thread.isHidden) { return false; @@ -3458,6 +3583,7 @@ }, hide: function() { var makeStub, thread; + makeStub = $('input', this.parentNode).checked; thread = ThreadHiding.menu.thread; ThreadHiding.hide(thread, makeStub); @@ -3466,6 +3592,7 @@ }, show: function() { var thread; + thread = ThreadHiding.menu.thread; ThreadHiding.show(thread); ThreadHiding.saveHiddenState(thread); @@ -3473,6 +3600,7 @@ }, hideStub: function() { var thread; + thread = ThreadHiding.menu.thread; ThreadHiding.hide(thread, false); $.event('CloseMenu'); @@ -3480,6 +3608,7 @@ }, makeButton: function(thread, type) { var a; + a = $.el('a', { className: "" + type + "-thread-button", innerHTML: " " + (type === 'hide' ? '-' : '+') + " ", @@ -3491,6 +3620,7 @@ }, saveHiddenState: function(thread, makeStub) { var hiddenThreadsOnCatalog; + hiddenThreadsOnCatalog = JSON.parse(localStorage.getItem("4chan-hide-t-" + g.BOARD)) || {}; if (thread.isHidden) { ThreadHiding.db.set({ @@ -3523,6 +3653,7 @@ }, hide: function(thread, makeStub) { var OP, a, numReplies, opInfo, span, threadRoot; + if (makeStub == null) { makeStub = Conf['Stubs']; } @@ -3546,6 +3677,7 @@ }, show: function(thread) { var threadRoot; + if (thread.stub) { $.rm(thread.stub); delete thread.stub; @@ -3558,6 +3690,7 @@ QuoteBacklink = { init: function() { var format; + if (g.VIEW === 'catalog' || !Conf['Quote Backlinks']) { return; } @@ -3575,6 +3708,7 @@ }, firstNode: function() { var a, clone, container, containers, frag, link, post, quote, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; + if (this.isClone || !this.quotes.length) { return; } @@ -3612,6 +3746,7 @@ }, secondNode: function() { var container; + if (this.isClone && (this.origin.isReply || Conf['OP Backlinks'])) { this.nodes.backlinkContainer = $('.container', this.nodes.info); return; @@ -3625,6 +3760,7 @@ }, getContainer: function(id) { var _base; + return (_base = this.containers)[id] || (_base[id] = $.el('span', { className: 'container' })); @@ -3647,6 +3783,7 @@ }, node: function() { var board, boardID, quotelink, thread, threadID, _i, _len, _ref, _ref1, _ref2; + if (this.isClone && this.thread === this.context.thread) { return; } @@ -3676,6 +3813,7 @@ if (Conf['Quote Hash Navigation']) { this.node = function() { var link, _i, _len, _ref; + _ref = this.nodes.quotelinks.concat(__slice.call(this.nodes.backlinks)); for (_i = 0, _len = _ref.length; _i < _len; _i++) { link = _ref[_i]; @@ -3688,6 +3826,7 @@ } else { this.node = function() { var link, _i, _len, _ref; + _ref = this.nodes.quotelinks.concat(__slice.call(this.nodes.backlinks)); for (_i = 0, _len = _ref.length; _i < _len; _i++) { link = _ref[_i]; @@ -3714,6 +3853,7 @@ }, toggle: function(e) { var boardID, context, postID, threadID, _ref; + if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) { return; } @@ -3739,6 +3879,7 @@ }, add: function(quotelink, boardID, threadID, postID, context) { var inline, isBacklink, post, qroot, root; + isBacklink = $.hasClass(quotelink, 'backlink'); inline = $.el('div', { id: "i" + postID, @@ -3763,6 +3904,7 @@ }, rm: function(quotelink, boardID, threadID, postID, context) { var el, inlined, isBacklink, post, qroot, root, _ref; + isBacklink = $.hasClass(quotelink, 'backlink'); root = QuoteInline.findRoot(quotelink, isBacklink); root = $.x("following-sibling::div[@id='i" + postID + "'][1]", root); @@ -3804,6 +3946,7 @@ }, node: function() { var boardID, fullID, i, postID, quotelink, quotelinks, quotes, _ref; + if (this.isClone && this.thread === this.context.thread) { return; } @@ -3846,6 +3989,7 @@ }, node: function() { var link, _i, _len, _ref; + _ref = this.nodes.quotelinks.concat(__slice.call(this.nodes.backlinks)); for (_i = 0, _len = _ref.length; _i < _len; _i++) { link = _ref[_i]; @@ -3854,6 +3998,7 @@ }, mouseover: function(e) { var boardID, clone, origin, post, postID, posts, qp, quote, quoterID, threadID, _i, _j, _len, _len1, _ref, _ref1; + if ($.hasClass(this, 'inlined')) { return; } @@ -3897,6 +4042,7 @@ }, mouseout: function() { var clone, post, root, _i, _len, _ref; + if (!(root = this.el.firstElementChild)) { return; } @@ -3926,6 +4072,7 @@ }, node: function() { var boardID, postID, quotelink, _i, _len, _ref, _ref1, _ref2; + if (this.isClone) { return; } @@ -3948,6 +4095,7 @@ QuoteThreading = { init: function() { var input; + if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) { return; } @@ -3970,6 +4118,7 @@ }, setup: function() { var ID, post, posts; + $.off(d, '4chanXInitFinished', QuoteThreading.setup); posts = g.posts; for (ID in posts) { @@ -3982,6 +4131,7 @@ }, node: function() { var ID, fullID, keys, len, post, posts, qid, quote, quotes, uniq, _i, _len; + if (this.isClone || !QuoteThreading.enabled || this.thread.OP === this) { return; } @@ -4011,6 +4161,7 @@ }, nodeinsert: function() { var bottom, height, qpost, qroot, threadContainer, top, _ref; + qpost = g.posts[this.threaded]; delete this.threaded; delete this.cb; @@ -4039,6 +4190,7 @@ }, toggle: function() { var container, containers, node, post, replies, reply, thread, _i, _j, _k, _len, _len1, _len2, _ref; + thread = $('.thread'); replies = $$('.thread > .replyContainer, .threadContainer > .replyContainer', thread); QuoteThreading.enabled = this.checked; @@ -4055,6 +4207,7 @@ } else { replies.sort(function(a, b) { var aID, bID; + aID = Number(a.id.slice(2)); bID = Number(b.id.slice(2)); return aID - bID; @@ -4075,6 +4228,7 @@ }, kb: function() { var control; + control = $.id('threadingControl'); return control.click(); } @@ -4101,6 +4255,7 @@ }, node: function() { var quotelink, _i, _len, _ref; + if (this.isClone) { return; } @@ -4123,6 +4278,7 @@ cb: { seek: function(type) { var highlight, post, posts, result, str; + if (!(Conf['Mark Quotes of You'] && Conf['Quick Reply'])) { return; } @@ -4178,6 +4334,7 @@ }, node: function() { var deadlink, _i, _len, _ref; + _ref = $$('.deadlink', this.nodes.comment); for (_i = 0, _len = _ref.length; _i < _len; _i++) { deadlink = _ref[_i]; @@ -4192,6 +4349,7 @@ }, parseDeadlink: function(deadlink) { var a, boardID, m, post, postID, quote, quoteID, redirect, _ref; + if (deadlink.parentNode.className === 'prettyprint') { Quotify.fixDeadlink(deadlink); return; @@ -4284,6 +4442,7 @@ }, node: function() { var data, el, end, endNode, i, index, items, length, link, links, node, range, result, saved, snapshot, space, test, _i, _len, _ref; + if (this.isClone) { if (Conf['Embedding']) { i = 0; @@ -4362,6 +4521,7 @@ }, makeRange: function(startNode, endNode, startOffset, endOffset) { var range; + range = document.createRange(); range.setStart(startNode, startOffset); range.setEnd(endNode, endOffset); @@ -4369,6 +4529,7 @@ }, makeLink: function(range) { var a, char, i, text; + text = range.toString(); i = 0; while (/[(\[{<>]/.test(text.charAt(i))) { @@ -4412,6 +4573,7 @@ }, services: function(link) { var href, key, match, type, _ref; + href = link.href; _ref = Linkify.types; for (key in _ref) { @@ -4424,6 +4586,7 @@ }, embed: function(data) { var embed, href, key, link, name, options, uid, value, _ref; + key = data[0], uid = data[1], options = data[2], link = data[3]; href = link.href; embed = $.el('a', { @@ -4452,6 +4615,7 @@ }, title: function(data) { var embed, err, key, link, options, service, title, titles, uid; + key = data[0], uid = data[1], options = data[2], link = data[3], embed = data[4]; if (!(service = Linkify.types[key].title)) { return; @@ -4488,18 +4652,21 @@ cb: { toggle: function() { var string, _ref; + _ref = $.hasClass(this, "embedded") ? ['unembed', '(embed)'] : ['embed', '(unembed)'], string = _ref[0], this.textContent = _ref[1]; $.replace(this.previousElementSibling, Linkify.cb[string](this)); return $.toggleClass(this, 'embedded'); }, embed: function(a) { var el, style, type; + el = (type = Linkify.types[a.dataset.key]).el(a); el.style.cssText = (style = type.style) ? style : "border: 0; width: 640px; height: 390px"; return el; }, unembed: function(a) { var el; + el = $.el('a', { rel: 'nofollow noreferrer', target: 'blank', @@ -4512,6 +4679,7 @@ }, title: function(response, data) { var embed, key, link, options, service, text, uid; + key = data[0], uid = data[1], options = data[2], link = data[3], embed = data[4]; service = Linkify.types[key].title; switch (response.status) { @@ -4551,6 +4719,7 @@ regExp: /.*(?:gist.github.com.*\/)([^\/][^\/]*)$/, el: function(a) { var div; + return div = $.el('iframe', { src: "http://www.purplegene.com/script?url=https://gist.github.com/" + a.dataset.uid + ".js" }); @@ -4561,6 +4730,7 @@ }, text: function(_arg) { var file, files; + files = _arg.files; for (file in files) { if (files.hasOwnProperty(file)) { @@ -4608,6 +4778,7 @@ regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/, el: function(a) { var div; + return div = $.el('iframe', { src: "http://pastebin.com/embed_iframe.php?i=" + a.dataset.uid }); @@ -4618,6 +4789,7 @@ style: 'height: auto; width: 500px; display: inline-block;', el: function(a) { var div; + div = $.el('div', { className: "soundcloud", name: "soundcloud" @@ -4643,6 +4815,7 @@ style: "border: none; width: 640px; height: 360px;", el: function(a) { var channel, chapter, result, _; + if (result = /(\w+)\/(?:[a-z]\/)?(\d+)/i.exec(a.dataset.uid)) { _ = result[0], channel = result[1], chapter = result[2]; return $.el('object', { @@ -4714,6 +4887,7 @@ QR = { init: function() { var sc; + if (!Conf['Quick Reply']) { return; } @@ -4760,6 +4934,7 @@ }, initReady: function() { var link; + QR.postingIsEnabled = !!$.id('postForm'); if (!QR.postingIsEnabled) { return; @@ -4779,11 +4954,13 @@ $.before($.id('postForm'), link); $.on(d, 'QRGetSelectedPost', function(_arg) { var cb; + cb = _arg.detail; return cb(QR.selected); }); $.on(d, 'QRAddPreSubmitHook', function(_arg) { var cb; + cb = _arg.detail; return QR.preSubmitHooks.push(cb); }); @@ -4813,6 +4990,7 @@ }, open: function() { var err; + if (QR.nodes) { QR.nodes.el.hidden = false; QR.unhide(); @@ -4831,6 +5009,7 @@ }, close: function() { var post, _i, _len, _ref; + if (QR.req) { QR.abort(); return; @@ -4878,6 +5057,7 @@ }, error: function(err) { var el; + QR.open(); if (typeof err === 'string') { el = $.tn(err); @@ -4905,6 +5085,7 @@ notifications: [], cleanNotifications: function() { var notification, _i, _len, _ref; + _ref = QR.notifications; for (_i = 0, _len = _ref.length; _i < _len; _i++) { notification = _ref[_i]; @@ -4914,6 +5095,7 @@ }, status: function() { var disabled, status, thread, value; + if (!QR.nodes) { return; } @@ -4935,6 +5117,7 @@ QR.persona.getPassword(); return $.get('QR.personas', Conf['QR.personas'], function(_arg) { var arr, item, personas, type, types, _i, _len, _ref; + personas = _arg['QR.personas']; types = { name: [], @@ -4954,6 +5137,7 @@ }, parseItem: function(item, types) { var boards, match, type, val, _ref, _ref1; + if (item[0] === '#') { return; } @@ -4982,6 +5166,7 @@ }, loadPersonas: function(type, arr) { var list, val, _i, _len; + list = $("#list-" + type, QR.nodes.el); for (_i = 0, _len = arr.length; _i < _len; _i++) { val = arr[_i]; @@ -4994,6 +5179,7 @@ }, getPassword: function() { var input, m; + if (!QR.persona.pwd) { QR.persona.pwd = (m = d.cookie.match(/4chan_pass=([^;]+)/)) ? decodeURIComponent(m[1]) : (input = $.id('postPassword')) ? input.value : $.id('delPassword').value; } @@ -5002,6 +5188,7 @@ get: function(cb) { return $.get('QR.persona', {}, function(_arg) { var persona; + persona = _arg['QR.persona']; return cb(persona); }); @@ -5009,6 +5196,7 @@ set: function(post) { return $.get('QR.persona', {}, function(_arg) { var persona; + persona = _arg['QR.persona']; persona = { name: post.name, @@ -5022,6 +5210,7 @@ cooldown: { init: function() { var board; + if (!Conf['Cooldown']) { return; } @@ -5063,6 +5252,7 @@ }, sync: function(cooldowns) { var id; + for (id in cooldowns) { QR.cooldown.cooldowns[id] = cooldowns[id]; } @@ -5070,6 +5260,7 @@ }, set: function(data) { var cooldown, delay, hasFile, isReply, isSage, post, req, start, type, upSpd; + if (!Conf['Cooldown']) { return; } @@ -5109,6 +5300,7 @@ }, count: function() { var cooldown, cooldowns, elapsed, hasFile, isReply, isSage, now, post, seconds, start, type, types, upSpd, upSpdAccuracy, update, _ref; + if (!Object.keys(QR.cooldown.cooldowns).length) { $["delete"]("" + g.BOARD + ".cooldown"); delete QR.cooldown.isCounting; @@ -5162,6 +5354,7 @@ }, quote: function(e) { var caretPos, com, index, post, range, s, sel, text, thread, _ref; + if (e != null) { e.preventDefault(); } @@ -5199,6 +5392,7 @@ }, characterCount: function() { var count, counter; + counter = QR.nodes.charCount; count = QR.nodes.com.textLength; counter.textContent = count; @@ -5207,6 +5401,7 @@ }, drag: function(e) { var toggle; + toggle = e.type === 'dragstart' ? $.off : $.on; toggle(d, 'dragover', QR.dragOver); return toggle(d, 'drop', QR.dropFile); @@ -5226,6 +5421,7 @@ }, paste: function(e) { var blob, files, item, _i, _len, _ref; + files = []; _ref = e.clipboardData.items; for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -5253,6 +5449,7 @@ }, fileInput: function(files) { var file, length, max, post, _i, _len; + if (this instanceof Element) { files = __slice.call(this.files); QR.nodes.fileInput.value = null; @@ -5301,6 +5498,7 @@ function _Class(select) { var el, event, prev, _i, _len, _ref, _this = this; + el = $.el('a', { className: 'qr-preview', draggable: true, @@ -5354,6 +5552,7 @@ _Class.prototype.rm = function() { var index; + this["delete"](); index = QR.posts.indexOf(this); if (QR.posts.length === 1) { @@ -5373,6 +5572,7 @@ _Class.prototype.lock = function(lock) { var name, _i, _len, _ref; + if (lock == null) { lock = true; } @@ -5397,6 +5597,7 @@ _Class.prototype.select = function() { var rectEl, rectList; + if (QR.selected) { QR.selected.nodes.el.id = null; QR.selected.forceSave(); @@ -5413,6 +5614,7 @@ _Class.prototype.load = function() { var name, _i, _len, _ref; + _ref = ['thread', 'name', 'email', 'sub', 'com']; for (_i = 0, _len = _ref.length; _i < _len; _i++) { name = _ref[_i]; @@ -5424,6 +5626,7 @@ _Class.prototype.save = function(input) { var name, _ref; + if (input.type === 'checkbox') { this.spoiler = input.checked; return; @@ -5444,6 +5647,7 @@ _Class.prototype.forceSave = function() { var name, _i, _len, _ref; + if (this !== QR.selected) { return; } @@ -5473,9 +5677,11 @@ _Class.prototype.setThumbnail = function() { var fileURL, img, _this = this; + img = $.el('img'); img.onload = function() { var cv, height, s, width; + s = 90 * 2; if (_this.file.type === 'image/gif') { s *= 3; @@ -5533,9 +5739,11 @@ _Class.prototype.pasteText = function(file) { var reader, _this = this; + reader = new FileReader(); reader.onload = function(e) { var text; + text = e.target.result; if (_this.com) { _this.com += "\n" + text; @@ -5573,6 +5781,7 @@ _Class.prototype.drop = function() { var el, index, newIndex, oldIndex, post; + $.rmClass(this, 'over'); if (!this.draggable) { return; @@ -5607,6 +5816,7 @@ ready: function() { var imgContainer, input, setLifetime, _this = this; + setLifetime = function(e) { return _this.lifetime = e.detail; }; @@ -5643,6 +5853,7 @@ }); $.get('captchas', [], function(_arg) { var captchas; + captchas = _arg.captchas; return _this.sync(captchas); }); @@ -5657,6 +5868,7 @@ }, getOne: function() { var captcha, challenge, response; + this.clear(); if (captcha = this.captchas.shift()) { challenge = captcha.challenge, response = captcha.response; @@ -5681,6 +5893,7 @@ }, save: function() { var response; + if (!(response = this.nodes.input.value.trim())) { return; } @@ -5695,6 +5908,7 @@ }, clear: function() { var captcha, i, now, _i, _len, _ref; + now = Date.now(); _ref = this.captchas; for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) { @@ -5712,6 +5926,7 @@ }, load: function() { var challenge; + if (!this.nodes.challenge.firstChild) { return; } @@ -5724,6 +5939,7 @@ }, count: function() { var count; + count = this.captchas.length; this.nodes.input.placeholder = (function() { switch (count) { @@ -5756,6 +5972,7 @@ }, dialog: function() { var dialog, i, items, mimeTypes, name, nodes, thread; + dialog = UI.dialog('qr', 'top:0;right:0;', "
×
No selected file×+
"); QR.nodes = nodes = { el: dialog, @@ -5857,6 +6074,7 @@ preSubmitHooks: [], submit: function(e) { var challenge, err, extra, filetag, hook, options, post, postData, response, textOnly, thread, threadID, _i, _len, _ref, _ref1; + if (e != null) { e.preventDefault(); } @@ -5970,6 +6188,7 @@ }, response: function() { var URL, ban, board, err, h1, isReply, m, post, postID, req, resDoc, threadID, _, _ref, _ref1; + req = QR.req; delete QR.req; post = QR.posts[0]; @@ -6067,6 +6286,7 @@ FappeTyme = { init: function() { var el, input; + if (!Conf['Fappe Tyme'] || g.VIEW === 'catalog' || g.BOARD === 'f') { return; } @@ -6118,6 +6338,7 @@ }, node: function() { var thumb, _ref; + if (!((_ref = this.file) != null ? _ref.isImage : void 0)) { return; } @@ -6142,6 +6363,7 @@ }, toggleAll: function() { var ID, file, func, post, _i, _len, _ref, _ref1; + $.event('CloseMenu'); if (ImageExpand.on = $.hasClass(ImageExpand.EAI, 'expand-all-shortcut')) { ImageExpand.EAI.className = 'contract-all-shortcut'; @@ -6175,6 +6397,7 @@ }, toggle: function(post) { var headRect, rect, root, thumb, x, y; + thumb = post.file.thumb; if (!(post.file.isExpanded || $.hasClass(thumb, 'expanding'))) { ImageExpand.expand(post); @@ -6184,6 +6407,7 @@ root = post.nodes.root; rect = (Conf['Advance on contract'] ? (function() { var next; + next = root; while (next = $.x("following::div[contains(@class,'postContainer')][1]", next)) { if ($('.stub', next) || next.offsetHeight === 0) { @@ -6214,6 +6438,7 @@ }, expand: function(post, src) { var img, thumb; + thumb = post.file.thumb; if (post.isHidden || post.file.isExpanded || $.hasClass(thumb, 'expanding')) { return; @@ -6241,6 +6466,7 @@ }, completeExpand: function(post) { var prev, thumb; + thumb = post.file.thumb; if (!$.hasClass(thumb, 'expanding')) { return; @@ -6254,6 +6480,7 @@ prev = post.nodes.root.getBoundingClientRect(); return $.queueTask(function() { var curr; + $.addClass(post.nodes.root, 'expanded-image'); $.rmClass(post.file.thumb, 'expanding'); if (!(prev.top + prev.height <= 0)) { @@ -6265,6 +6492,7 @@ }, error: function() { var URL, post, src, timeoutID; + post = Get.postFromNode(this); $.rm(this); delete post.file.fullImage; @@ -6290,6 +6518,7 @@ return $.ajax("//api.4chan.org/" + post.board + "/res/" + post.thread + ".json", { onload: function() { var postObj, _i, _len, _ref; + if (this.status !== 200) { return; } @@ -6313,6 +6542,7 @@ menu: { init: function() { var conf, createSubEntry, el, name, subEntries, _ref; + if (g.VIEW === 'catalog' || !Conf['Image Expansion']) { return; } @@ -6336,6 +6566,7 @@ }, createSubEntry: function(name, desc) { var input, label; + label = $.el('label', { innerHTML: " " + name, title: desc @@ -6369,6 +6600,7 @@ }, node: function() { var _ref; + if (!((_ref = this.file) != null ? _ref.isImage : void 0)) { return; } @@ -6376,6 +6608,7 @@ }, mouseover: function(e) { var el, post; + post = Get.postFromNode(this); el = $.el('img', { id: 'ihover', @@ -6397,6 +6630,7 @@ error: function() { var URL, post, src, timeoutID, _this = this; + if (!doc.contains(this)) { return; } @@ -6421,6 +6655,7 @@ return $.ajax("//api.4chan.org/" + post.board + "/res/" + post.thread + ".json", { onload: function() { var postObj, _i, _len, _ref; + if (this.status !== 200) { return; } @@ -6446,6 +6681,7 @@ ImageLoader = { init: function() { var prefetch; + if (g.VIEW === 'catalog') { return; } @@ -6472,6 +6708,7 @@ }, node: function() { var URL, img, string, style, thumb, type, _ref, _ref1; + if (this.isClone || this.isHidden || this.thread.isHidden || !((_ref = this.file) != null ? _ref.isImage : void 0)) { return; } @@ -6493,6 +6730,7 @@ }, toggle: function() { var enabled, id, post, _ref; + enabled = Conf['prefetch'] = this.checked; if (enabled) { _ref = g.threads["" + g.BOARD.ID + "." + g.THREADID].posts; @@ -6516,6 +6754,7 @@ }, node: function() { var thumb, _ref; + if (this.isClone || !((_ref = this.file) != null ? _ref.isSpoiler : void 0)) { return; } @@ -6528,6 +6767,7 @@ Sauce = { init: function() { var err, link, links, _i, _len, _ref; + if (g.VIEW === 'catalog' || !Conf['Sauce']) { return; } @@ -6557,6 +6797,7 @@ }, createSauceLink: function(link) { var m, text; + link = link.replace(/%(T?URL|MD5|board)/ig, function(parameter) { switch (parameter) { case '%TURL': @@ -6577,6 +6818,7 @@ }, node: function() { var link, nodes, _i, _len, _ref; + if (this.isClone || !this.file) { return; } @@ -6593,6 +6835,7 @@ ArchiveLink = { init: function() { var div, entry, type, _i, _len, _ref; + if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Archive Link']) { return; } @@ -6605,6 +6848,7 @@ order: 90, open: function(_arg) { var ID, board, thread; + ID = _arg.ID, thread = _arg.thread, board = _arg.board; return !!Redirect.to('thread', { postID: ID, @@ -6623,12 +6867,14 @@ }, createSubEntry: function(text, type) { var el, open; + el = $.el('a', { textContent: text, target: '_blank' }); open = type === 'post' ? function(_arg) { var ID, board, thread; + ID = _arg.ID, thread = _arg.thread, board = _arg.board; el.href = Redirect.to('thread', { postID: ID, @@ -6638,6 +6884,7 @@ return true; } : function(post) { var value; + value = Filter[type](post); if (!value) { return false; @@ -6660,6 +6907,7 @@ DeleteLink = { init: function() { var div, fileEl, fileEntry, postEl, postEntry; + if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Delete Link']) { return; } @@ -6687,6 +6935,7 @@ el: fileEl, open: function(_arg) { var file; + file = _arg.file; if (!file || file.isDead) { return false; @@ -6702,6 +6951,7 @@ order: 40, open: function(post) { var node; + if (post.isDead || post.board.ID === 'q') { return false; } @@ -6716,6 +6966,7 @@ }, "delete": function() { var fileOnly, form, link, post; + post = DeleteLink.post; if (DeleteLink.cooldown.counting === post) { return; @@ -6745,6 +6996,7 @@ }, load: function(link, post, fileOnly, resDoc) { var msg, s; + if (resDoc.title === '4chan - Banned') { s = 'Banned!'; } else if (msg = resDoc.getElementById('errmsg')) { @@ -6765,6 +7017,7 @@ cooldown: { start: function(post, node) { var length, seconds, _ref; + if (!((_ref = QR.db) != null ? _ref.get({ boardID: post.board.ID, threadID: post.thread.ID, @@ -6798,6 +7051,7 @@ DownloadLink = { init: function() { var a; + if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Download Link']) { return; } @@ -6811,6 +7065,7 @@ order: 100, open: function(_arg) { var file; + file = _arg.file; if (!file) { return false; @@ -6843,6 +7098,7 @@ }, makeButton: (function() { var a; + a = $.el('a', { className: 'menu-button brackets-wrap', innerHTML: '', @@ -6850,6 +7106,7 @@ }); return function() { var button; + button = a.cloneNode(true); $.on(button, 'click', Menu.toggle); return button; @@ -6857,6 +7114,7 @@ })(), toggle: function(e) { var post; + post = Get.postFromNode(this); return Menu.menu.toggle(e, this, post); } @@ -6865,6 +7123,7 @@ ReportLink = { init: function() { var a; + if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Report Link']) { return; } @@ -6886,6 +7145,7 @@ }, report: function() { var id, post, set, url; + post = ReportLink.post; url = "//sys.4chan.org/" + post.board + "/imgboard.php?mode=report&no=" + post; id = Date.now(); @@ -6898,6 +7158,7 @@ init: function() { return $.ready(function() { var href; + Favicon.el = $('link[rel="shortcut icon"]', d.head); Favicon.el.type = 'image/x-icon'; href = Favicon.el.href; @@ -6970,6 +7231,7 @@ init: function() { var sc, _this = this; + if (g.VIEW !== 'thread' || !Conf['Thread Stats']) { return; } @@ -6998,6 +7260,7 @@ }, node: function() { var ID, fileCount, post, postCount, _ref; + postCount = 0; fileCount = 0; _ref = this.posts; @@ -7015,6 +7278,7 @@ }, onUpdate: function(e) { var fileCount, postCount, _ref; + if (e.detail[404]) { return; } @@ -7023,6 +7287,7 @@ }, update: function(postCount, fileCount) { var fileCountEl, postCountEl, thread; + thread = ThreadStats.thread, postCountEl = ThreadStats.postCountEl, fileCountEl = ThreadStats.fileCountEl; postCountEl.textContent = postCount; fileCountEl.textContent = fileCount; @@ -7047,6 +7312,7 @@ }, onThreadsLoad: function() { var page, pages, thread, _i, _j, _len, _len1, _ref; + if (!(Conf["Page Count in Stats"] && this.status === 200)) { return; } @@ -7070,6 +7336,7 @@ init: function() { var checked, conf, el, input, name, sc, settings, subEntries, _ref, _this = this; + if (g.VIEW !== 'thread' || !Conf['Thread Updater']) { return; } @@ -7219,6 +7486,7 @@ }, interval: function() { var val; + val = +this.value; if (val < 1) { val = 1; @@ -7228,6 +7496,7 @@ }, load: function() { var klass, req, text, _ref; + req = ThreadUpdater.req; switch (req.status) { case 200: @@ -7260,6 +7529,7 @@ }, getInterval: function() { var i, j; + i = ThreadUpdater.interval; j = Math.min(ThreadUpdater.outdateCount, 10); if (!d.hidden) { @@ -7269,12 +7539,14 @@ }, intervalShortcut: function() { var settings; + Settings.open('Advanced'); settings = $.id('fourchanx-settings'); return $('input[name=Interval]', settings).focus(); }, set: function(name, text, klass) { var el, node; + el = ThreadUpdater[name]; if (node = el.firstChild) { node.data = text; @@ -7287,6 +7559,7 @@ }, timeout: function() { var n; + ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.timeout, 1000); if (!(n = --ThreadUpdater.seconds)) { return ThreadUpdater.update(); @@ -7299,6 +7572,7 @@ }, update: function() { var url; + if (!ThreadUpdater.online) { return; } @@ -7321,6 +7595,7 @@ }, updateThreadStatus: function(title, OP) { var icon, message, root, titleLC; + titleLC = title.toLowerCase(); if (ThreadUpdater.thread["is" + title] === !!OP[titleLC]) { return; @@ -7347,6 +7622,7 @@ }, parse: function(postObjects) { var ID, OP, count, deletedFiles, deletedPosts, files, index, key, node, num, post, postObject, posts, root, scroll, _i, _len, _ref; + OP = postObjects[0]; Build.spoilerRange[ThreadUpdater.thread.board] = OP.custom_spoiler; ThreadUpdater.updateThreadStatus('Sticky', OP); @@ -7432,6 +7708,7 @@ } $.queueTask(function() { var length, threadID; + threadID = ThreadUpdater.thread.ID; length = $$('.thread > .postContainer', ThreadUpdater.root).length; return Fourchan.parseThread(threadID, length - count, length); @@ -7452,6 +7729,7 @@ ThreadWatcher = { init: function() { var now, sc; + if (!Conf['Thread Watcher']) { return; } @@ -7484,6 +7762,7 @@ } $.get('WatchedThreads', null, function(_arg) { var WatchedThreads, boardID, data, threadID, threads, _ref; + WatchedThreads = _arg.WatchedThreads; if (!WatchedThreads) { return; @@ -7509,6 +7788,7 @@ }, node: function() { var toggler; + toggler = $.el('img', { className: 'watch-thread-link' }); @@ -7530,6 +7810,7 @@ } return $.get('AutoWatch', 0, function(_arg) { var AutoWatch, thread; + AutoWatch = _arg.AutoWatch; if (!(thread = g.BOARD.threads[AutoWatch])) { return; @@ -7545,6 +7826,7 @@ cb: { openAll: function() { var a, _i, _len, _ref; + if ($.hasClass(this, 'disabled')) { return; } @@ -7563,6 +7845,7 @@ }, pruneDeads: function() { var boardID, data, threadID, _i, _len, _ref, _ref1; + if ($.hasClass(this, 'disabled')) { return; } @@ -7586,11 +7869,13 @@ }, rm: function() { var boardID, threadID, _ref; + _ref = this.parentNode.dataset.fullID.split('.'), boardID = _ref[0], threadID = _ref[1]; return ThreadWatcher.rm(boardID, +threadID); }, post: function(e) { var board, postID, threadID, _ref; + _ref = e.detail, board = _ref.board, postID = _ref.postID, threadID = _ref.threadID; if (postID === threadID) { if (Conf['Auto Watch']) { @@ -7602,6 +7887,7 @@ }, threadUpdate: function(e) { var thread; + thread = e.detail.thread; if (!(e.detail[404] && ThreadWatcher.db.get({ boardID: thread.board.ID, @@ -7618,6 +7904,7 @@ }, fetchAllStatus: function() { var thread, threads, _i, _len; + if (!(threads = ThreadWatcher.getAll()).length) { return; } @@ -7629,6 +7916,7 @@ }, fetchStatus: function(_arg) { var boardID, data, fetchCount, threadID; + boardID = _arg.boardID, threadID = _arg.threadID, data = _arg.data; if (data.isDead) { return; @@ -7638,6 +7926,7 @@ return $.ajax("//api.4chan.org/" + boardID + "/res/" + threadID + ".json", { onloadend: function() { var status; + fetchCount.fetched++; if (fetchCount.fetched === fetchCount.fetching) { fetchCount.fetched = 0; @@ -7668,6 +7957,7 @@ }, getAll: function() { var all, boardID, data, threadID, threads, _ref; + all = []; _ref = ThreadWatcher.db.data.boards; for (boardID in _ref) { @@ -7688,6 +7978,7 @@ }, makeLine: function(boardID, threadID, data) { var div, fullID, href, link, x; + x = $.el('a', { textContent: '×', href: 'javascript:;' @@ -7718,6 +8009,7 @@ }, refresh: function() { var boardID, data, list, nodes, refresher, thread, threadID, toggler, watched, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3; + nodes = []; _ref = ThreadWatcher.getAll(); for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -7745,6 +8037,7 @@ }, toggle: function(thread) { var boardID, threadID; + boardID = thread.board.ID; threadID = thread.ID; if (ThreadWatcher.db.get({ @@ -7758,6 +8051,7 @@ }, add: function(thread) { var boardID, data, threadID; + data = {}; boardID = thread.board.ID; threadID = thread.ID; @@ -7788,6 +8082,7 @@ }, convert: function(oldFormat) { var boardID, data, newFormat, threadID, threads; + newFormat = {}; for (boardID in oldFormat) { threads = oldFormat[boardID]; @@ -7804,6 +8099,7 @@ refreshers: [], init: function() { var menu; + if (!Conf['Thread Watcher']) { return; } @@ -7816,6 +8112,7 @@ }, addHeaderMenuEntry: function() { var entryEl; + if (g.VIEW !== 'thread') { return; } @@ -7832,6 +8129,7 @@ }); return this.refreshers.push(function() { var addClass, rmClass, text, _ref; + _ref = $('.current', ThreadWatcher.list) ? ['unwatch-thread', 'watch-thread', 'Unwatch thread'] : ['watch-thread', 'unwatch-thread', 'Watch thread'], addClass = _ref[0], rmClass = _ref[1], text = _ref[2]; $.addClass(entryEl, addClass); $.rmClass(entryEl, rmClass); @@ -7840,6 +8138,7 @@ }, addMenuEntries: function() { var cb, conf, entries, entry, name, refresh, subEntries, _i, _len, _ref, _ref1, _results; + entries = []; entries.push({ cb: ThreadWatcher.cb.openAll, @@ -7910,6 +8209,7 @@ }, createSubEntry: function(name, desc) { var entry, input; + entry = { type: 'thread watcher', el: $.el('label', { @@ -7961,6 +8261,7 @@ }, ready: function() { var ID, post, posts, _ref; + $.off(d, '4chanXInitFinished', Unread.ready); posts = []; _ref = Unread.thread.posts; @@ -7977,6 +8278,7 @@ }, scroll: function() { var checkPosition, hash, onload, post, posts, root; + if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) { return; } @@ -8006,6 +8308,7 @@ } checkPosition = function(target) { var height, top, _ref; + _ref = target.getBoundingClientRect(), top = _ref.top, height = _ref.height; return top + height - doc.clientHeight > 0; }; @@ -8013,6 +8316,7 @@ }, sync: function() { var lastReadPost; + lastReadPost = Unread.db.get({ boardID: Unread.thread.board.ID, threadID: Unread.thread.ID, @@ -8029,6 +8333,7 @@ }, addPosts: function(posts) { var ID, data, post, _i, _len; + for (_i = 0, _len = posts.length; _i < _len; _i++) { post = posts[_i]; ID = post.ID; @@ -8056,6 +8361,7 @@ }, addPostQuotingYou: function(post) { var quotelink, _i, _len, _ref; + if (!QR.db) { return; } @@ -8076,6 +8382,7 @@ }, readSinglePost: function(post) { var i; + if ((i = Unread.posts.indexOf(post)) === -1) { return; } @@ -8091,6 +8398,7 @@ }, readArray: function(arr) { var i, post, _i, _len; + for (i = _i = 0, _len = arr.length; _i < _len; i = ++_i) { post = arr[i]; if (post.ID > Unread.lastReadPost) { @@ -8101,6 +8409,7 @@ }, read: $.debounce(50, function(e) { var ID, bottom, height, i, post, posts; + if (d.hidden || !Unread.posts.length) { return; } @@ -8156,6 +8465,7 @@ }), setLine: function(force) { var post, root; + if (!(d.hidden || force === true)) { return; } @@ -8170,6 +8480,7 @@ }, update: function(dontrepeat) { var count; + count = Unread.posts.length; if (Conf['Unread Count']) { d.title = "" + (Conf['Quoted Title'] && Unread.postsQuotingYou.length ? '(!) ' : '') + (count || !Conf['Hide Unread Count at (0)'] ? "(" + count + ") " : '') + (g.DEAD ? "/" + g.BOARD + "/ - 404" : "" + Unread.title); @@ -8195,6 +8506,7 @@ }, init: function() { var archive, boardID, boards, data, id, name, type, _i, _len, _ref, _ref1, _ref2; + _ref = Conf['selectedArchives']; for (boardID in _ref) { data = _ref[boardID]; @@ -8326,6 +8638,7 @@ }, to: function(dest, data) { var archive; + archive = (dest === 'search' ? Redirect.data.thread : Redirect.data[dest])[data.boardID]; if (!archive) { return ''; @@ -8334,6 +8647,7 @@ }, protocol: function(archive) { var protocol; + protocol = location.protocol; if (!archive[protocol.slice(0, -1)]) { protocol = protocol === 'https:' ? 'http:' : 'https:'; @@ -8342,6 +8656,7 @@ }, thread: function(archive, _arg) { var boardID, path, postID, threadID; + boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID; path = threadID ? "" + boardID + "/thread/" + threadID : "" + boardID + "/post/" + postID; if (archive.software === 'foolfuuka') { @@ -8354,6 +8669,7 @@ }, post: function(archive, _arg) { var URL, boardID, postID, protocol; + boardID = _arg.boardID, postID = _arg.postID; protocol = Redirect.protocol(archive); if (['Foolz', 'NSFW Foolz'].contains(archive.name)) { @@ -8365,11 +8681,13 @@ }, file: function(archive, _arg) { var boardID, filename; + boardID = _arg.boardID, filename = _arg.filename; return "" + (Redirect.protocol(archive)) + archive.domain + "/" + boardID + "/full_image/" + filename; }, search: function(archive, _arg) { var boardID, path, type, value; + boardID = _arg.boardID, type = _arg.type, value = _arg.value; type = type === 'name' ? 'username' : type === 'MD5' ? 'image' : type; value = encodeURIComponent(value); @@ -8388,6 +8706,7 @@ }, setup: function() { var btn, entry, psa; + $.off(d, '4chanXInitFinished', PSAHiding.setup); if (!(psa = $.id('globalMessage'))) { $.rmClass(doc, 'hide-announcement'); @@ -8416,6 +8735,7 @@ $.on(btn, 'click', PSAHiding.toggle); $.get('hiddenPSA', 0, function(_arg) { var hiddenPSA; + hiddenPSA = _arg.hiddenPSA; PSAHiding.sync(hiddenPSA); $.before(psa, btn); @@ -8425,6 +8745,7 @@ }, toggle: function(e) { var UTC; + if ($.hasClass(this, 'hide-announcement')) { UTC = +$.id('globalMessage').dataset.utc; $.set('hiddenPSA', UTC); @@ -8436,6 +8757,7 @@ }, sync: function(UTC) { var hr, psa; + psa = $.id('globalMessage'); psa.hidden = PSAHiding.btn.hidden = UTC && UTC >= +psa.dataset.utc ? true : false; if ((hr = psa.nextElementSibling) && hr.nodeName === 'HR') { @@ -8456,6 +8778,7 @@ }, ready: function() { var banner, child, children, i; + banner = $(".boardBanner"); children = banner.children; i = 0; @@ -8468,22 +8791,27 @@ } if (Conf['Custom Board Titles']) { Banner.custom(child).title = "Ctrl+click to edit board " + (i === 3 ? 'sub' : '') + "title"; - Banner.custom(child).spellcheck = false; + child.spellcheck = false; } } }, cb: { - toggle: function() { - var num, type, types; + toggle: (function() { + var types; + types = { jpg: 227, png: 270, gif: 253 }; - type = Object.keys(types)[Math.floor(3 * Math.random())]; - num = Math.floor(types[type] * Math.random()); - return this.src = "//static.4chan.org/image/title/" + num + "." + type; - }, + return function() { + var num, type; + + type = Object.keys(types)[Math.floor(3 * Math.random())]; + num = Math.floor(types[type] * Math.random()); + return this.src = "//static.4chan.org/image/title/" + num + "." + type; + }; + })(), click: function(e) { if (e.ctrlKey) { this.contentEditable = true; @@ -8498,6 +8826,7 @@ }, focus: function() { var items, string, string2; + this.textContent = this.innerHTML; string = "" + g.BOARD + "." + this.className; string2 = "" + string + ".orig"; @@ -8520,6 +8849,7 @@ }, custom: function(child) { var cachedTest, string; + cachedTest = child.innerHTML; string = "" + g.BOARD + "." + child.className; $.on(child, 'click keydown focus blur', function(e) { @@ -8527,6 +8857,7 @@ }); $.get(string, cachedTest, function(item) { var string2, title; + if (!(title = item[string])) { return; } @@ -8550,6 +8881,7 @@ CatalogLinks = { init: function() { var el, input; + if (!Conf['Catalog Links']) { return; } @@ -8573,12 +8905,14 @@ }, toggle: function() { var useCatalog; + $.event('CloseMenu'); $.set('Header catalog links', useCatalog = this.checked); return CatalogLinks.set(useCatalog); }, set: function(useCatalog) { var a, board, path, _i, _len, _ref; + path = useCatalog ? 'catalog' : ''; _ref = $$("#board-list a[href*=\"boards.4chan.org\"]:not(.catalog),\n#boardNavDesktopFoot a[href*=\"boards.4chan.org\"]"); for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -8613,6 +8947,7 @@ }, node: function() { var str, uid; + if (this.isClone || !(str = this.info.uniqueID)) { return; } @@ -8624,6 +8959,7 @@ }, compute: function(str) { var hash, rgb; + hash = IDColor.hash(str); rgb = [(hash >> 24) & 0xFF, (hash >> 16) & 0xFF, (hash >> 8) & 0xFF]; rgb[3] = ((rgb[0] * 0.299) + (rgb[1] * 0.587) + (rgb[2] * 0.114)) > 125; @@ -8635,6 +8971,7 @@ }, hash: function(str) { var i, msg; + msg = 0; i = 0; while (i < 8) { @@ -8680,6 +9017,7 @@ }, node: function() { var dicestats, roll, _ref; + if (this.isClone || !(dicestats = (_ref = this.info.email) != null ? _ref.match(/dice[+\s](\d+)d(\d+)/) : void 0)) { return; } @@ -8691,6 +9029,7 @@ Emoji = { init: function() { var css, icon, name, pos, _ref; + if (!Conf['Emoji']) { return; } @@ -8760,6 +9099,7 @@ }, node: function() { var a; + if (a = $('.abbr > a:not([onclick])', this.nodes.comment)) { return $.on(a, 'click', ExpandComment.cb); } @@ -8771,6 +9111,7 @@ }, expand: function(post) { var a; + if (post.nodes.longComment && !post.nodes.longComment.parentNode) { $.replace(post.nodes.shortComment, post.nodes.longComment); post.nodes.comment = post.nodes.longComment; @@ -8786,6 +9127,7 @@ }, contract: function(post) { var a; + if (!post.nodes.shortComment) { return; } @@ -8796,6 +9138,7 @@ }, parse: function(req, a, post) { var callback, clone, comment, href, postObj, posts, quote, spoilerRange, status, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; + status = req.status; if (![200, 304].contains(status)) { a.textContent = "Error " + req.statusText + " (" + status + ")"; @@ -8858,6 +9201,7 @@ }, node: function() { var a, files, posts, span, _ref; + if (!(span = $.x('following-sibling::span[contains(@class,"summary")][1]', this.OP.nodes.root))) { return; } @@ -8878,6 +9222,7 @@ }, toggle: function(thread) { var a, files, filesCount, inlined, num, post, posts, postsCount, reply, threadRoot, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _ref4; + threadRoot = thread.OP.nodes.root.parentNode; a = $('.summary', threadRoot); switch (thread.isExpanded) { @@ -8955,6 +9300,7 @@ }, parse: function(req, thread, a) { var filesCount, link, post, posts, postsCount, postsObj, postsRoot, reply, root, spoilerRange, _i, _len; + if (a.textContent[0] === '+') { return; } @@ -9018,6 +9364,7 @@ }, createFunc: function(format) { var code; + code = format.replace(/%(.)/g, function(s, c) { if (c in FileInfo.formatters) { return "' + FileInfo.formatters." + c + ".call(post) + '"; @@ -9029,6 +9376,7 @@ }, convertUnit: function(size, unit) { var i; + if (unit === 'B') { return "" + (size.toFixed()) + " Bytes"; } @@ -9059,6 +9407,7 @@ }, n: function() { var fullname, shortname; + fullname = this.file.name; shortname = Build.shortFilename(this.file.name, this.isReply); if (fullname === shortname) { @@ -9102,6 +9451,7 @@ Fourchan = { init: function() { var board; + if (g.VIEW === 'catalog') { return; } @@ -9123,6 +9473,7 @@ }, code: function() { var pre, _i, _len, _ref; + if (this.isClone) { return; } @@ -9152,11 +9503,13 @@ Keybinds = { init: function() { var init; + if (g.VIEW === 'catalog' || !Conf['Keybinds']) { return; } init = function() { var node, _i, _len, _ref; + $.off(d, '4chanXInitFinished', init); $.on(d, 'keydown', Keybinds.keydown); _ref = $$('[accesskey]'); @@ -9169,6 +9522,7 @@ }, keydown: function(e) { var form, key, notification, notifications, op, target, thread, threadRoot, _i, _len; + if (!(key = Keybinds.keyCode(e))) { return; } @@ -9346,6 +9700,7 @@ }, keyCode: function(e) { var kc, key; + key = (function() { switch (kc = e.keyCode) { case 8: @@ -9401,6 +9756,7 @@ }, tags: function(tag, ta) { var range, selEnd, selStart, value; + value = ta.value; selStart = ta.selectionStart; selEnd = ta.selectionEnd; @@ -9411,11 +9767,13 @@ }, sage: function() { var isSage; + isSage = /sage/i.test(QR.nodes.email.value); return QR.nodes.email.value = isSage ? "" : "sage"; }, img: function(thread, all) { var post; + if (all) { return ImageExpand.cb.toggleAll(); } else { @@ -9425,6 +9783,7 @@ }, open: function(thread, tab) { var url; + if (g.VIEW !== 'index') { return; } @@ -9437,6 +9796,7 @@ }, hl: function(delta, thread) { var axe, headRect, next, postEl, rect, replies, reply, root, topMargin, _i, _len; + if (!delta) { if (postEl = $('.reply.highlight', thread)) { $.rmClass(postEl, 'highlight'); @@ -9496,6 +9856,7 @@ Nav = { init: function() { var append, next, prev, span; + switch (g.VIEW) { case 'index': if (!Conf['Index Navigation']) { @@ -9546,6 +9907,7 @@ }, getThread: function(full) { var headRect, i, rect, thread, threads, topMargin, _i, _len; + if (Conf['Bottom header'] || !Conf['Fixed Header']) { topMargin = 0; } else { @@ -9571,6 +9933,7 @@ }, scroll: function(delta) { var i, rect, thread, threads, top, topMargin, _ref, _ref1; + _ref = Nav.getThread(true), threads = _ref[0], thread = _ref[1], i = _ref[2], rect = _ref[3], topMargin = _ref[4]; top = rect.top - topMargin; if ((delta === -1 && top > -5) || (delta === +1 && top < 5)) { @@ -9595,6 +9958,7 @@ }, node: function() { var dateEl; + if (this.isClone) { return; } @@ -9604,6 +9968,7 @@ }, relative: function(diff, now, date) { var days, months, number, rounded, unit, years; + unit = (number = diff / $.DAY) >= 1 ? (years = now.getYear() - date.getYear(), months = now.getMonth() - date.getMonth(), days = now.getDate() - date.getDate(), years > 1 ? (number = years - (months < 0 || months === 0 && days < 0), 'year') : years === 1 && (months > 0 || months === 0 && days >= 0) ? (number = years, 'year') : (months = (months + 12) % 12) > 1 ? (number = months - (days < 0), 'month') : months === 1 && days >= 0 ? (number = months, 'month') : 'day') : (number = diff / $.HOUR) >= 1 ? 'hour' : (number = diff / $.MINUTE) >= 1 ? 'minute' : (number = Math.max(0, diff) / $.SECOND, 'second'); rounded = Math.round(number); if (rounded !== 1) { @@ -9614,6 +9979,7 @@ stale: [], flush: function() { var now, update, _i, _len, _ref; + if (d.hidden) { return; } @@ -9629,13 +9995,16 @@ }, setUpdate: function(post) { var markStale, setOwnTimeout, update; + setOwnTimeout = function(diff) { var delay; + delay = diff < $.MINUTE ? $.SECOND - (diff + $.SECOND / 2) % $.SECOND : diff < $.HOUR ? $.MINUTE - (diff + $.MINUTE / 2) % $.MINUTE : diff < $.DAY ? $.HOUR - (diff + $.HOUR / 2) % $.HOUR : $.DAY - (diff + $.DAY / 2) % $.DAY; return setTimeout(markStale, delay); }; update = function(now) { var date, diff, relative, singlePost, _i, _len, _ref; + date = post.info.date; diff = now - date; relative = RelativeDates.relative(diff, now, date); @@ -9676,6 +10045,7 @@ }, node: function(post) { var spoiler, spoilers, _i, _len; + spoilers = $$('s', this.nodes.comment); for (_i = 0, _len = spoilers.length; _i < _len; _i++) { spoiler = spoilers[_i]; @@ -9695,6 +10065,7 @@ }, ready: function() { var field; + field = $.id('recaptcha_response_field'); $.on(field, 'keydown', function(e) { if (e.keyCode === 8 && !field.value) { @@ -9703,6 +10074,7 @@ }); return $.on($('form'), 'submit', function(e) { var response; + e.preventDefault(); response = field.value.trim(); if (!/\s/.test(response)) { @@ -9732,6 +10104,7 @@ }, createFunc: function(format) { var code; + code = format.replace(/%([A-Za-z])/g, function(s, c) { if (c in Time.formatters) { return "' + Time.formatters." + c + ".call(date) + '"; @@ -9816,6 +10189,7 @@ Settings = { init: function() { var link, settings; + link = $.el('a', { className: 'settings-link', textContent: 'Settings', @@ -9825,6 +10199,7 @@ Header.addShortcut(link); $.get('previousversion', null, function(item) { var changelog, el, previous; + if (previous = item['previousversion']) { if (previous === g.VERSION) { return; @@ -9859,6 +10234,7 @@ }, open: function(openSection) { var dialog, html, link, links, overlay, section, sectionToOpen, _i, _len, _ref; + $.off(d, '4chanXInitFinished', Settings.open); if (Settings.dialog) { return; @@ -9911,6 +10287,7 @@ sections: [], addSection: function(title, open) { var hyphenatedTitle, _ref; + if (typeof title !== 'string') { _ref = title.detail, title = _ref.title, open = _ref.open; } @@ -9923,6 +10300,7 @@ }, openSection: function() { var section, selected; + if (selected = $('.tab-selected', Settings.dialog)) { $.rmClass(selected, 'tab-selected'); } @@ -9936,6 +10314,7 @@ }, main: function(section) { var arr, button, description, div, fs, hiddenNum, input, inputs, items, key, obj, _ref; + items = {}; inputs = {}; _ref = Config.main; @@ -9960,6 +10339,7 @@ } $.get(items, function(items) { var val; + for (key in items) { val = items[key]; inputs[key].checked = val; @@ -9974,6 +10354,7 @@ boards: {} }, function(item) { var ID, board, thread, _ref1; + _ref1 = item.hiddenThreads.boards; for (ID in _ref1) { board = _ref1[ID]; @@ -9988,6 +10369,7 @@ boards: {} }, function(item) { var ID, board, post, thread, _ref1; + _ref1 = item.hiddenPosts.boards; for (ID in _ref1) { board = _ref1[ID]; @@ -10007,6 +10389,7 @@ boards: {} }, function(item) { var boardID; + for (boardID in item.hiddenThreads.boards) { localStorage.removeItem("4chan-hide-t-" + boardID); } @@ -10017,6 +10400,7 @@ }, "export": function(now, data) { var a, db, _i, _len; + if (typeof now !== 'number') { now = Date.now(); data = { @@ -10050,6 +10434,7 @@ }, onImport: function() { var file, output, reader; + if (!(file = this.files[0])) { return; } @@ -10061,6 +10446,7 @@ reader = new FileReader(); reader.onload = function(e) { var data, err; + try { data = JSON.parse(e.target.result); Settings.loadSettings(data); @@ -10077,6 +10463,7 @@ }, loadSettings: function(data) { var key, val, version, _ref; + version = data.version.split('.'); if (version[0] === '2') { data = Settings.convertSettings(data, { @@ -10164,6 +10551,7 @@ }, convertSettings: function(data, map) { var newKey, prevKey; + for (prevKey in map) { newKey = map[prevKey]; if (newKey) { @@ -10175,6 +10563,7 @@ }, filter: function(section) { var select; + section.innerHTML = "
"; select = $('select', section); $.on(select, 'change', Settings.selectFilter); @@ -10182,6 +10571,7 @@ }, selectFilter: function() { var div, name, ta; + div = this.nextElementSibling; if ((name = this.value) !== 'guide') { $.rmAll(div); @@ -10201,6 +10591,7 @@ }, sauce: function(section) { var ta; + section.innerHTML = "
Sauce is disabled.
Lines starting with a # will be ignored.
You can specify a display text by appending ;text:[text] to the URL.
    These parameters will be replaced by their corresponding values:\n
  • %TURL: Thumbnail URL.
  • %URL: Full image URL.
  • %MD5: MD5 hash.
  • %board: Current board.
"; ta = $('textarea', section); $.get('sauces', Conf['sauces'], function(item) { @@ -10210,6 +10601,7 @@ }, advanced: function(section) { var archive, boardID, boardOptions, boardSelect, boards, data, event, input, inputs, item, items, name, row, rows, ta, table, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3, _ref4; + section.innerHTML = "
Archiver
404 Redirect is disabled.
Thread redirectionPost fetchingFile redirection
Disabled selections indicate that only one archive is available for that board and redirection type.
Custom Board Navigation
New lines will be converted into spaces.

In the following examples for /g/, g can be changed to a different board ID (a, b, etc...), the current board (current), or the Status/Twitter link (status, @).
Board link: g
Title link: g-title
Board link (Replace with title when on that board): g-replace
Full text link: g-full
Custom text link: g-text:\"Install Gentoo\"
Index-only link: g-index
Catalog-only link: g-catalog
External link: external-text:\"Google\",\"http://www.google.com\"
Combinations are possible: g-index-text:\"Technology Index\"
Full board list toggle: toggle-all

[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"]
\n will give you
[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
\n if you are on /g/.\n
Time Formatting is disabled.
:
Supported format specifiers:
Day: %a, %A, %d, %e
Month: %m, %b, %B
Year: %y, %Y
Hour: %k, %H, %l, %I, %p, %P
Minute: %M
Second: %S
Quote Backlinks formatting is disabled.
:
File Info Formatting is disabled.
:
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
Spoiler indicator: %p
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
Resolution: %r (Displays 'PDF' for PDF files)
Quick Reply Personas is disabled.

\n One item per line.
\n Items will be added in the relevant input's auto-completion list.
\n Password items will always be used, since there is no password input.
\n Lines starting with a # will be ignored.\n

    You can use these settings with each item, separate them with semicolons:\n
  • Possible items are: name, email, subject and password.
  • Wrap values of items with quotes, like this: email:\"sage\".
  • Force values as defaults with the always keyword, for example: email:\"sage\";always.
  • Select specific boards for an item, separated with commas, for example: email:\"sage\";boards:jp;always.
Unread Favicon is disabled.
Emoji is disabled.
\n Sage Icon:
\n Position:
Thread Updater is disabled.
\n Interval:
"; items = {}; inputs = {}; @@ -10229,6 +10621,7 @@ $.on(ta, 'change', $.cb.value); $.get(items, function(items) { var key, val; + for (key in items) { val = items[key]; if (['emojiPos'].contains(key)) { @@ -10299,6 +10692,7 @@ }); $.get('selectedArchives', Conf['selectedArchives'], function(_arg) { var option, selectedArchives, type; + selectedArchives = _arg.selectedArchives; for (boardID in selectedArchives) { data = selectedArchives[boardID]; @@ -10313,6 +10707,7 @@ }, addArchiveCell: function(boardID, data, type) { var archive, i, length, options, select, td; + length = data[type].length; td = $.el('td', { className: 'archive-cell' @@ -10342,8 +10737,10 @@ }, saveSelectedArchive: function() { var _this = this; + return $.get('selectedArchives', Conf['selectedArchives'], function(_arg) { var selectedArchives, _name; + selectedArchives = _arg.selectedArchives; (selectedArchives[_name = _this.dataset.boardid] || (selectedArchives[_name] = {}))[_this.dataset.type] = _this.value; return $.set('selectedArchives', selectedArchives); @@ -10354,6 +10751,7 @@ }, time: function() { var funk; + funk = Time.createFunc(this.value); return this.nextElementSibling.textContent = funk(Time, new Date()); }, @@ -10362,6 +10760,7 @@ }, fileInfo: function() { var data, funk; + data = { isReply: true, file: { @@ -10400,6 +10799,7 @@ }, keybinds: function(section) { var arr, input, inputs, items, key, tbody, tr, _ref; + section.innerHTML = "
Keybinds are disabled.
Allowed keys: a-z, 0-9, Ctrl, Shift, Alt, Meta, Enter, Esc, Up, Down, Right, Left.
Press Backspace to disable a keybind.
ActionsKeybinds
"; tbody = $('tbody', section); items = {}; @@ -10420,6 +10820,7 @@ } return $.get(items, function(items) { var val; + for (key in items) { val = items[key]; inputs[key].value = val; @@ -10428,6 +10829,7 @@ }, keybind: function(e) { var key; + if (e.keyCode === 9) { return; } @@ -10444,8 +10846,10 @@ Main = { init: function() { var db, flatten, _i, _len; + flatten = function(parent, obj) { var key, val; + if (obj instanceof Array) { Conf[parent] = obj[0]; } else if (typeof obj === 'object') { @@ -10486,6 +10890,7 @@ }, initFeatures: function() { var init, pathname, _ref; + pathname = location.pathname.split('/'); g.BOARD = new Board(pathname[1]); if ((_ref = g.BOARD.ID) === 'z' || _ref === 'fk') { @@ -10513,6 +10918,7 @@ case 'images.4chan.org': $.ready(function() { var URL; + if (Conf['404 Redirect'] && ['4chan - Temporarily Offline', '4chan - 404 Not Found'].contains(d.title)) { Redirect.init(); pathname = location.pathname.split('/'); @@ -10529,6 +10935,7 @@ } init = function(features) { var err, module, name; + for (name in features) { module = features[name]; try { @@ -10607,6 +11014,7 @@ }, initStyle: function() { var mainStyleSheet, setStyle, style, styleSheets, _ref; + $.off(d, '4chanMainInit', Main.initStyle); if (!Main.isThisPageLegit() || $.hasClass(doc, 'fourchan-x')) { return; @@ -10628,6 +11036,7 @@ styleSheets = $$('link[rel="alternate stylesheet"]', d.head); setStyle = function() { var styleSheet, _i, _len; + $.rmClass(doc, style); for (_i = 0, _len = styleSheets.length; _i < _len; _i++) { styleSheet = styleSheets[_i]; @@ -10649,6 +11058,7 @@ }, initReady: function() { var board, err, errors, href, passLink, postRoot, posts, styleSelector, thread, threadRoot, threads, _i, _j, _len, _len1, _ref, _ref1; + if (['4chan - Temporarily Offline', '4chan - 404 Not Found'].contains(d.title)) { if (Conf['404 Redirect'] && g.VIEW === 'thread') { href = Redirect.to('thread', { @@ -10715,6 +11125,7 @@ }, callbackNodes: function(klass, nodes) { var callback, err, errors, i, len, node, _i, _len, _ref; + len = nodes.length; _ref = klass.prototype.callbacks; for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -10742,9 +11153,11 @@ }, callbackNodesDB: function(klass, nodes, cb) { var errors, func, i, len, node, queue, softTask; + queue = []; softTask = function() { var args, func, task; + task = queue.shift(); func = task[0]; args = Array.prototype.slice.call(task, 1); @@ -10763,6 +11176,7 @@ errors = null; func = function(node, i) { var callback, err, _i, _len, _ref; + _ref = klass.prototype.callbacks; for (_i = 0, _len = _ref.length; _i < _len; _i++) { callback = _ref[_i]; @@ -10796,6 +11210,7 @@ }, addCallback: function(e) { var Klass, obj; + obj = e.detail; if (typeof obj.callback.name !== 'string') { throw new Error("Invalid callback name: " + obj.callback.name); @@ -10815,6 +11230,7 @@ }, handleErrors: function(errors) { var div, error, logs, _i, _len; + if (!(errors instanceof Array)) { error = errors; } else if (errors.length === 1) { @@ -10829,6 +11245,7 @@ }); $.on(div.lastElementChild, 'click', function() { var _ref; + return _ref = this.textContent === 'show' ? ['hide', false] : ['show', true], this.textContent = _ref[0], logs.hidden = _ref[1], _ref; }); logs = $.el('div', { @@ -10842,6 +11259,7 @@ }, parseError: function(data) { var error, message; + Main.logError(data); message = $.el('div', { textContent: data.message @@ -10858,6 +11276,7 @@ }, isThisPageLegit: function() { var _ref; + if (!('thisPageIsLegit' in Main)) { Main.thisPageIsLegit = location.hostname === 'boards.4chan.org' && !$('link[href*="favicon-status.ico"]', d.head) && ((_ref = d.title) !== '4chan - Temporarily Offline' && _ref !== '4chan - Error' && _ref !== '504 Gateway Time-out'); } diff --git a/src/Miscellaneous/Banner.coffee b/src/Miscellaneous/Banner.coffee index 2bc67ab37..95f64c9b6 100644 --- a/src/Miscellaneous/Banner.coffee +++ b/src/Miscellaneous/Banner.coffee @@ -21,20 +21,21 @@ Banner = 'sub' else ''}title" - Banner.custom(child).spellcheck = false + child.spellcheck = false return cb: - toggle: -> + toggle: do -> types = jpg: 227 png: 270 gif: 253 - type = Object.keys(types)[Math.floor 3 * Math.random()] - num = Math.floor types[type] * Math.random() - @src = "//static.4chan.org/image/title/#{num}.#{type}" + -> + type = Object.keys(types)[Math.floor 3 * Math.random()] + num = Math.floor types[type] * Math.random() + @src = "//static.4chan.org/image/title/#{num}.#{type}" click: (e) -> if e.ctrlKey From 36b2c782811139bad3e360f771b4f2b6d7bbaf4c Mon Sep 17 00:00:00 2001 From: Jordan Bates Date: Fri, 16 Aug 2013 16:48:20 -0700 Subject: [PATCH 4/4] Release 4chan X v1.2.32. --- CHANGELOG.md | 6 ++++++ LICENSE | 2 +- builds/4chan-X.meta.js | 2 +- builds/4chan-X.user.js | 6 +++--- builds/crx/manifest.json | 2 +- builds/crx/script.js | 4 ++-- latest.js | 2 +- package.json | 2 +- 8 files changed, 16 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea3f49ba3..2be7f4b51 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +### v1.2.32 +*2013-08-16* + +**seaweedchan**: +- Optimizations for the banner and board title code, including a fix for boards without subtitles throwing an error + ### v1.2.31 *2013-08-16* diff --git a/LICENSE b/LICENSE index 8dee57dec..cb24d7f28 100755 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ /* -* 4chan X - Version 1.2.31 - 2013-08-16 +* 4chan X - Version 1.2.32 - 2013-08-16 * * Licensed under the MIT license. * https://github.com/seaweedchan/4chan-x/blob/master/LICENSE diff --git a/builds/4chan-X.meta.js b/builds/4chan-X.meta.js index fb1001bc2..31c6eae7e 100755 --- a/builds/4chan-X.meta.js +++ b/builds/4chan-X.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.2.31 +// @version 1.2.32 // @namespace 4chan-X // @description Cross-browser userscript for maximum lurking on 4chan. // @license MIT; https://github.com/seaweedchan/4chan-x/blob/master/LICENSE diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index eb8d12057..8cb9d7227 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -1,7 +1,7 @@ // Generated by CoffeeScript // ==UserScript== // @name 4chan X -// @version 1.2.31 +// @version 1.2.32 // @namespace 4chan-X // @description Cross-browser userscript for maximum lurking on 4chan. // @license MIT; https://github.com/seaweedchan/4chan-x/blob/master/LICENSE @@ -19,7 +19,7 @@ // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAgMAAAAqbBEUAAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAHFJREFUKFOt0LENACEIBdBv4Qju4wgWanEj3D6OcIVMKaitYHEU/jwTCQj8W75kiVCSBvdQ5/AvfVHBin11BgdRq3ysBgfwBDRrj3MCIA+oAQaku/Q1cNctrAmyDl577tOThYt/Y1RBM4DgOHzM0HFTAyLukH/cmRnqAAAAAElFTkSuQmCC // ==/UserScript== /* -* 4chan X - Version 1.2.31 - 2013-08-16 +* 4chan X - Version 1.2.32 - 2013-08-16 * * Licensed under the MIT license. * https://github.com/seaweedchan/4chan-x/blob/master/LICENSE @@ -328,7 +328,7 @@ doc = d.documentElement; g = { - VERSION: '1.2.31', + VERSION: '1.2.32', NAMESPACE: '4chan X.', boards: {}, threads: {}, diff --git a/builds/crx/manifest.json b/builds/crx/manifest.json index 056a5fbab..391d553c9 100755 --- a/builds/crx/manifest.json +++ b/builds/crx/manifest.json @@ -1,6 +1,6 @@ { "name": "4chan X", - "version": "1.2.31", + "version": "1.2.32", "manifest_version": 2, "description": "Cross-browser userscript for maximum lurking on 4chan.", "icons": { diff --git a/builds/crx/script.js b/builds/crx/script.js index 1725f97c0..c0f0f3dd5 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript /* -* 4chan X - Version 1.2.31 - 2013-08-16 +* 4chan X - Version 1.2.32 - 2013-08-16 * * Licensed under the MIT license. * https://github.com/seaweedchan/4chan-x/blob/master/LICENSE @@ -310,7 +310,7 @@ doc = d.documentElement; g = { - VERSION: '1.2.31', + VERSION: '1.2.32', NAMESPACE: '4chan X.', boards: {}, threads: {}, diff --git a/latest.js b/latest.js index 4ebaadb4f..83a7452a2 100755 --- a/latest.js +++ b/latest.js @@ -1 +1 @@ -postMessage({version:'1.2.31'},'*') +postMessage({version:'1.2.32'},'*') diff --git a/package.json b/package.json index f97571aed..dcc0e8885 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "4chan-X", - "version": "1.2.31", + "version": "1.2.32", "description": "Cross-browser userscript for maximum lurking on 4chan.", "meta": {