From 0a41f0ae6cd29e3ce7186545132e97253f9664f4 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Mon, 18 Mar 2013 01:43:50 +0100 Subject: [PATCH 1/3] Make Chrome ext/userscript/userjs builds. --- .gitignore | 1 + 4chan_x.meta.js | 6 +++--- 4chan_x.user.js | 10 +++++----- CONTRIBUTING.md | 2 -- Gruntfile.js | 41 ++++++++++++++++++++++++++++++++++------- lib/$.coffee | 2 +- package.json | 10 ++++++---- src/manifest.json | 14 ++++++++++++++ src/metadata.js | 13 +++++++------ 9 files changed, 71 insertions(+), 28 deletions(-) create mode 100644 src/manifest.json diff --git a/.gitignore b/.gitignore index 92b2c45a1..b79a916f9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +builds/ node_modules/ tmp/ diff --git a/4chan_x.meta.js b/4chan_x.meta.js index e0f534ab9..bb417e306 100644 --- a/4chan_x.meta.js +++ b/4chan_x.meta.js @@ -6,16 +6,16 @@ // @copyright 2009-2011 James Campos // @copyright 2012-2013 Nicolas Stepien // @license MIT; http://en.wikipedia.org/wiki/Mit_license +// @match *://api.4chan.org/* // @match *://boards.4chan.org/* // @match *://images.4chan.org/* // @match *://sys.4chan.org/* -// @match *://api.4chan.org/* // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_openInTab // @run-at document-start -// @updateURL https://github.com/MayhemYDG/4chan-x/raw/v3/4chan_x.meta.js -// @downloadURL https://github.com/MayhemYDG/4chan-x/raw/v3/4chan_x.user.js +// @updateURL https://github.com/MayhemYDG/4chan-x/raw/v3/4chan-X.meta.js +// @downloadURL https://github.com/MayhemYDG/4chan-x/raw/v3/4chan-X.user.js // @icon data:image/gif;base64,R0lGODlhEAAQAKECAAAAAGbMM////////yH5BAEKAAIALAAAAAAQABAAAAIxlI+pq+D9DAgUoFkPDlbs7lGiI2bSVnKglnJMOL6omczxVZK3dH/41AG6Lh7i6qUoAAA7 // ==/UserScript== diff --git a/4chan_x.user.js b/4chan_x.user.js index 1601cf1df..473ecd092 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -6,21 +6,21 @@ // @copyright 2009-2011 James Campos // @copyright 2012-2013 Nicolas Stepien // @license MIT; http://en.wikipedia.org/wiki/Mit_license +// @match *://api.4chan.org/* // @match *://boards.4chan.org/* // @match *://images.4chan.org/* // @match *://sys.4chan.org/* -// @match *://api.4chan.org/* // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_openInTab // @run-at document-start -// @updateURL https://github.com/MayhemYDG/4chan-x/raw/v3/4chan_x.meta.js -// @downloadURL https://github.com/MayhemYDG/4chan-x/raw/v3/4chan_x.user.js +// @updateURL https://github.com/MayhemYDG/4chan-x/raw/v3/4chan-X.meta.js +// @downloadURL https://github.com/MayhemYDG/4chan-x/raw/v3/4chan-X.user.js // @icon data:image/gif;base64,R0lGODlhEAAQAKECAAAAAGbMM////////yH5BAEKAAIALAAAAAAQABAAAAIxlI+pq+D9DAgUoFkPDlbs7lGiI2bSVnKglnJMOL6omczxVZK3dH/41AG6Lh7i6qUoAAA7 // ==/UserScript== -/* 4chan X Beta - Version 3.0.0 - 2013-03-15 +/* 4chan X Beta - Version 3.0.0 - 2013-03-18 * http://mayhemydg.github.com/4chan-x/ * * Copyright (c) 2009-2011 James Campos @@ -918,7 +918,7 @@ $.add(d.head, script); return $.rm(script); }, - unsafeWindow: window.opera ? window : unsafeWindow !== window ? unsafeWindow : (function() { + unsafeWindow: window.opera ? window : typeof unsafeWindow !== "undefined" && unsafeWindow !== null ? unsafeWindow : (function() { var p; p = d.createElement('p'); p.setAttribute('onclick', 'return window'); diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8bcc068df..42fa67ad2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -38,7 +38,5 @@ Note: this is only used to release new 4chan X versions, and is **not** needed o ### Contribute - Edit the CoffeeScript sources. -- Build the JavaScript. - If the edits affect regular users, edit the changelog. -- Fork the repository. - Open a pull request. diff --git a/Gruntfile.js b/Gruntfile.js index ce7ec379c..f9b12b6e1 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -21,19 +21,37 @@ module.exports = function(grunt) { ], dest: 'tmp/script.coffee' }, - script: { + manifest: { + options: { process: { data: pkg } }, + src: 'src/manifest.json', + dest: 'builds/crx/manifest.json' + }, + crx: { + options: { process: { data: pkg } }, + src: [ + 'src/banner.js', + 'tmp/script.js' + ], + dest: 'builds/crx/script.js' + }, + metadata: { + options: { process: { data: pkg } }, + src: 'src/metadata.js', + dest: 'builds/<%= pkg.name %>.meta.js' + }, + userscript: { options: { process: { data: pkg } }, src: [ 'src/metadata.js', 'src/banner.js', 'tmp/script.js' ], - dest: '<%= pkg.meta.files.userjs %>' + dest: 'builds/<%= pkg.name %>.user.js' }, - metadata: { - options: { process: { data: pkg } }, - src: 'src/metadata.js', - dest: '<%= pkg.meta.files.metajs %>' + userjs: { + // Lazily copy the userscript + src: 'builds/<%= pkg.name %>.user.js', + dest: 'builds/<%= pkg.name %>.js' } }, coffee: { @@ -89,7 +107,16 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-exec'); - grunt.registerTask('default', ['concat:coffee', 'coffee:script', 'concat:script', 'concat:metadata', 'clean']); + grunt.registerTask('default', [ + 'concat:coffee', + 'coffee:script', + 'concat:manifest', + 'concat:crx', + 'concat:userscript', + 'concat:userjs', + 'concat:metadata', + 'clean' + ]); grunt.registerTask('release', ['default', 'exec:commit', 'exec:push']); grunt.registerTask('patch', ['bump', 'updcl:3']); grunt.registerTask('minor', ['bump:minor', 'updcl:2']); diff --git a/lib/$.coffee b/lib/$.coffee index 8220b4d4e..f238701f6 100644 --- a/lib/$.coffee +++ b/lib/$.coffee @@ -189,7 +189,7 @@ $.extend $, unsafeWindow: if window.opera # Opera window - else if unsafeWindow isnt window # Firefox + else if unsafeWindow? # Firefox unsafeWindow else # Chrome do -> diff --git a/package.json b/package.json index 23a7825b2..ad5deea45 100644 --- a/package.json +++ b/package.json @@ -7,10 +7,12 @@ "repo": "https://github.com/MayhemYDG/4chan-x/", "page": "http://mayhemydg.github.com/4chan-x/", "mainBranch": "v3", - "files": { - "metajs": "4chan_x.meta.js", - "userjs": "4chan_x.user.js" - } + "matches": [ + "*://api.4chan.org/*", + "*://boards.4chan.org/*", + "*://images.4chan.org/*", + "*://sys.4chan.org/*" + ] }, "devDependencies": { "grunt": "~0.4.0", diff --git a/src/manifest.json b/src/manifest.json new file mode 100644 index 000000000..f125f6cb5 --- /dev/null +++ b/src/manifest.json @@ -0,0 +1,14 @@ +{ + "name": "<%= meta.name %>", + "version": "<%= version %>", + "manifest_version": 2, + "description": "<%= description %>", + "content_scripts": [{ + "js": ["script.js"], + "matches": <%= JSON.stringify(meta.matches) %>, + "run_at": "document_start" + }], + "homepage_url": "<%= meta.page %>", + "incognito": "spanning", + "minimum_chrome_version": "25" +} diff --git a/src/metadata.js b/src/metadata.js index 5f190df0f..415133169 100644 --- a/src/metadata.js +++ b/src/metadata.js @@ -6,16 +6,17 @@ // @copyright 2009-2011 James Campos // @copyright 2012-<%= grunt.template.today('yyyy') %> Nicolas Stepien // @license MIT; http://en.wikipedia.org/wiki/Mit_license -// @match *://boards.4chan.org/* -// @match *://images.4chan.org/* -// @match *://sys.4chan.org/* -// @match *://api.4chan.org/* +<%= + meta.matches.map(function(match) { + return '// @match ' + match; + }).join('\n') +%> // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_openInTab // @run-at document-start -// @updateURL <%= meta.repo %>raw/<%= meta.mainBranch %>/<%= meta.files.metajs %> -// @downloadURL <%= meta.repo %>raw/<%= meta.mainBranch %>/<%= meta.files.userjs %> +// @updateURL <%= meta.repo %>raw/<%= meta.mainBranch %>/<%= name %>.meta.js +// @downloadURL <%= meta.repo %>raw/<%= meta.mainBranch %>/<%= name %>.user.js // @icon data:image/gif;base64,<%= grunt.file.read('img/icon.gif', {encoding: 'base64'}) %> // ==/UserScript== From 597f962e9f13251e6160bd16b79ef2721c61c618 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Mon, 18 Mar 2013 16:33:51 +0100 Subject: [PATCH 2/3] " -> ' --- src/globals.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/globals.coffee b/src/globals.coffee index 827975066..21586a376 100644 --- a/src/globals.coffee +++ b/src/globals.coffee @@ -8,7 +8,7 @@ d = document doc = d.documentElement g = VERSION: '<%= version %>' - NAMESPACE: "<%= meta.name %>." + NAMESPACE: '<%= meta.name %>.' boards: {} threads: {} posts: {} From a76e6ea1f4354dbcdd4bd86d06a27ade190903f1 Mon Sep 17 00:00:00 2001 From: Nicolas Stepien Date: Mon, 18 Mar 2013 17:57:05 +0100 Subject: [PATCH 3/3] Coffee update. --- 4chan_x.user.js | 320 +++++++++++++++++++++++++++++++++++++++++++++--- package.json | 2 +- 2 files changed, 305 insertions(+), 17 deletions(-) diff --git a/4chan_x.user.js b/4chan_x.user.js index 473ecd092..9b2df81a9 100644 --- a/4chan_x.user.js +++ b/4chan_x.user.js @@ -204,7 +204,7 @@ g = { VERSION: '3.0.0', - NAMESPACE: "4chan X Beta.", + NAMESPACE: '4chan X Beta.', boards: {}, threads: {}, posts: {} @@ -212,8 +212,10 @@ UI = (function() { var Menu, dialog, drag, dragend, dragstart, hover, hoverend, hoverstart, touchend, touchmove; + dialog = function(id, position, html) { var el, move; + el = d.createElement('div'); el.className = 'dialog'; el.innerHTML = html; @@ -240,6 +242,7 @@ Menu.prototype.makeMenu = function() { var menu; + menu = $.el('div', { className: 'dialog', id: 'menu', @@ -254,6 +257,7 @@ Menu.prototype.toggle = function(e, button, data) { var previousButton; + e.preventDefault(); e.stopPropagation(); if (currentMenu) { @@ -271,6 +275,7 @@ Menu.prototype.open = function(button, data) { var bLeft, bRect, bTop, bottom, cHeight, cWidth, entry, left, mRect, menu, prevEntry, right, style, top, _i, _len, _ref, _ref1, _ref2; + menu = this.makeMenu(); currentMenu = menu; lastToggledButton = button; @@ -305,6 +310,7 @@ Menu.prototype.insertEntry = function(entry, parent, data) { var subEntry, submenu, _i, _len, _ref; + if (typeof entry.open === 'function') { if (!entry.open(data)) { return; @@ -338,6 +344,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); @@ -347,6 +354,7 @@ Menu.prototype.keybinds = function(e) { var entry, next, nextPrev, subEntry, submenu; + entry = $('.focused', currentMenu); while (subEntry = $('.focused', entry)) { entry = subEntry; @@ -392,6 +400,7 @@ Menu.prototype.focus = function(entry) { var bottom, cHeight, cWidth, eRect, focused, left, right, sRect, style, submenu, top, _i, _len, _ref; + while (focused = $.x('parent::*/child::*[contains(@class,"focused")]', entry)) { $.rmClass(focused, 'focused'); } @@ -431,6 +440,7 @@ Menu.prototype.addEntry = function(e) { var entry; + entry = e.detail; if (entry.type !== this.type) { return; @@ -441,6 +451,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) { @@ -464,6 +475,7 @@ })(); dragstart = function(e) { var el, isTouching, o, rect, screenHeight, screenWidth; + if (e.type === 'mousedown' && e.button !== 0) { return; } @@ -502,6 +514,7 @@ }; touchmove = function(e) { var touch, _i, _len, _ref; + _ref = e.changedTouches; for (_i = 0, _len = _ref.length; _i < _len; _i++) { touch = _ref[_i]; @@ -513,6 +526,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 + '%'; @@ -528,6 +542,7 @@ }; touchend = function(e) { var touch, _i, _len, _ref; + _ref = e.changedTouches; for (_i = 0, _len = _ref.length; _i < _len; _i++) { touch = _ref[_i]; @@ -550,6 +565,7 @@ }; hoverstart = function(_arg) { var asap, asapTest, cb, el, endEvents, event, latestEvent, o, root, _i, _len, _ref; + root = _arg.root, el = _arg.el, latestEvent = _arg.latestEvent, endEvents = _arg.endEvents, asapTest = _arg.asapTest, cb = _arg.cb; o = { root: root, @@ -580,6 +596,7 @@ }; hover = function(e) { var clientX, clientY, height, left, right, style, top; + this.latestEvent = e; height = this.el.offsetHeight; clientX = e.clientX, clientY = e.clientY; @@ -599,6 +616,7 @@ }; hoverend = function() { var event, _i, _len, _ref; + this.el.parentNode.removeChild(this.el); _ref = this.endEvents; for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -634,6 +652,7 @@ $.extend = function(object, properties) { var key, val; + for (key in properties) { val = properties[key]; object[key] = val; @@ -651,6 +670,7 @@ }, ready: function(fc) { var cb, _ref; + if ((_ref = d.readyState) === 'interactive' || _ref === 'complete') { $.queueTask(fc); return; @@ -671,6 +691,7 @@ }, formData: function(form) { var fd, key, val; + if (form instanceof HTMLFormElement) { return new FormData(form); } @@ -690,6 +711,7 @@ }, ajax: function(url, callbacks, opts) { var form, headers, key, r, type, upCallbacks, val; + if (opts == null) { opts = {}; } @@ -709,9 +731,11 @@ }, cache: (function() { var reqs; + reqs = {}; return function(url, cb) { var req; + if (req = reqs[url]) { if (req.readyState === 4) { cb.call(req); @@ -723,6 +747,7 @@ req = $.ajax(url, { onload: function() { var _i, _len, _ref; + _ref = this.callbacks; for (_i = 0, _len = _ref.length; _i < _len; _i++) { cb = _ref[_i]; @@ -760,6 +785,7 @@ }, addStyle: function(css) { var style; + style = $.el('style', { textContent: css }); @@ -793,6 +819,7 @@ }, nodes: function(nodes) { var frag, node, _i, _len; + if (!(nodes instanceof Array)) { return nodes; } @@ -820,6 +847,7 @@ }, el: function(tag, properties) { var el; + el = d.createElement(tag); if (properties) { $.extend(el, properties); @@ -828,6 +856,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]; @@ -836,6 +865,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]; @@ -855,6 +885,7 @@ if (typeof GM_openInTab !== "undefined" && GM_openInTab !== null) { return function(URL) { var a; + a = $.el('a', { href: URL }); @@ -868,6 +899,7 @@ })(), debounce: function(wait, fn) { var args, exec, that, timeout; + timeout = null; that = null; args = null; @@ -888,9 +920,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); @@ -912,6 +946,7 @@ })(), globalEval: function(code) { var script; + script = $.el('script', { textContent: code }); @@ -920,12 +955,14 @@ }, unsafeWindow: window.opera ? window : typeof unsafeWindow !== "undefined" && unsafeWindow !== null ? unsafeWindow : (function() { var p; + p = d.createElement('p'); p.setAttribute('onclick', 'return window'); return p.onclick(); })(), bytesToString: function(size) { var unit; + unit = 0; while (size >= 1024) { size /= 1024; @@ -942,6 +979,7 @@ }; $.get = function(name, defaultValue) { var value; + if (value = GM_getValue(g.NAMESPACE + name)) { return JSON.parse(value); } else { @@ -957,12 +995,14 @@ } else if (window.opera) { (function() { var scriptStorage; + scriptStorage = opera.scriptStorage; $["delete"] = function(name) { return delete scriptStorage[g.NAMESPACE + name]; }; $.get = function(name, defaultValue) { var value; + if (value = scriptStorage[g.NAMESPACE + name]) { return JSON.parse(value); } else { @@ -982,6 +1022,7 @@ }; $.get = function(name, defaultValue) { var value; + if (value = localStorage.getItem(g.NAMESPACE + name)) { return JSON.parse(value); } else { @@ -999,6 +1040,7 @@ }, visibility: function() { var event, prefix, property; + if ('visibilityState' in document) { return; } @@ -1024,6 +1066,7 @@ Header = { init: function() { var catalogToggler, headerEl; + headerEl = $.el('div', { id: 'header', innerHTML: "
\n \n \n \n \n \n \n
\n
\n
".replace(/>\s+<') @@ -1058,6 +1101,7 @@ }, setBoardList: function() { var a, btn, fullBoardList, nav; + nav = $.id('boardNavDesktop'); if (a = $("a[href*='/" + g.BOARD + "/']", nav)) { a.className = 'current'; @@ -1081,6 +1125,7 @@ }, generateBoardList: function(text) { var as, list, nodes; + list = $('#custom-board-list', Header.bar); list.innerHTML = null; if (!text) { @@ -1089,6 +1134,7 @@ as = $$('#full-board-list a', Header.bar).slice(0, -2); nodes = text.match(/[\w@]+(-(all|title|full|text:"[^"]+"))?|[^\w@]+/g).map(function(t) { var a, board, m, _i, _len; + if (/^[^\w@]/.test(t)) { return $.tn(t); } @@ -1124,6 +1170,7 @@ }, toggleBoardList: function() { var bar, custom, full, showBoardList; + bar = Header.bar; custom = $('#custom-board-list', bar); full = $('#full-board-list', bar); @@ -1133,6 +1180,7 @@ }, setCatalogLinks: function(useCatalog) { var a, as, str, _i, _len; + as = $$('#board-list a[href*="boards.4chan.org"]', Header.bar); str = useCatalog ? 'catalog' : ''; for (_i = 0, _len = as.length; _i < _len; _i++) { @@ -1149,6 +1197,7 @@ }, toggleBarVisibility: function() { var hide, message; + hide = !$.hasClass(Header.bar, 'autohide'); Header.setBarVisibility(hide); message = hide ? 'The header bar will automatically hide itself.' : 'The header bar will remain visible.'; @@ -1157,6 +1206,7 @@ }, addShortcut: function(el) { var shortcut; + shortcut = $.el('span', { className: 'shortcut' }); @@ -1219,6 +1269,7 @@ Settings = { init: function() { var link, settings; + link = $.el('a', { className: 'settings-link', textContent: '4chan X Beta Settings', @@ -1271,6 +1322,7 @@ }, open: function(openSection) { var html, link, links, overlay, section, sectionToOpen, _i, _len, _ref; + if (Settings.dialog) { return; } @@ -1322,6 +1374,7 @@ sections: [], addSection: function(title, open) { var _ref; + if (typeof title !== 'string') { _ref = title.detail, title = _ref.title, open = _ref.open; } @@ -1332,6 +1385,7 @@ }, openSection: function() { var section; + section = $('section', Settings.dialog); section.innerHTML = null; section.className = "section-" + (this.title.toLowerCase().replace(/\s+/g, '-')); @@ -1340,6 +1394,7 @@ }, main: function(section) { var ID, arr, checked, description, div, fs, hiddenNum, key, obj, post, thread, _ref, _ref1, _ref2; + section.innerHTML = "
\n \n \n \n
\n

"; $.on($('.export', section), 'click', Settings["export"]); $.on($('.import', section), 'click', Settings["import"]); @@ -1388,6 +1443,7 @@ }, "export": function() { var a, data, now, output; + now = Date.now(); data = { version: g.VERSION, @@ -1415,6 +1471,7 @@ }, onImport: function() { var file, output, reader; + if (!(file = this.files[0])) { return; } @@ -1425,14 +1482,16 @@ } reader = new FileReader(); reader.onload = function(e) { - var data; + var data, err; + try { data = JSON.parse(decodeURIComponent(escape(e.target.result))); Settings.loadSettings(data); if (confirm('Import successful. Refresh now?')) { return window.location.reload(); } - } catch (err) { + } catch (_error) { + err = _error; output.textContent = 'Import failed due to an error.'; return c.log(err.stack); } @@ -1441,6 +1500,7 @@ }, loadSettings: function(data) { var key, val, version, _ref, _ref1; + version = data.version.split('.'); if (version[0] === '2') { data = Settings.convertSettings(data, { @@ -1525,6 +1585,7 @@ }, convertSettings: function(data, map) { var newKey, prevKey; + for (prevKey in map) { newKey = map[prevKey]; if (newKey) { @@ -1536,6 +1597,7 @@ }, filter: function(section) { var select; + section.innerHTML = "\n
"; select = $('select', section); $.on(select, 'change', Settings.selectFilter); @@ -1543,6 +1605,7 @@ }, selectFilter: function() { var div, name, ta; + div = this.nextElementSibling; if ((name = this.value) !== 'guide') { div.innerHTML = null; @@ -1560,6 +1623,7 @@ }, sauce: function(section) { var sauce; + section.innerHTML = "
Sauce is disabled.
\n
Lines starting with a # will be ignored.
\n
You can specify a display text by appending ;text:[text] to the URL.
\n
    These parameters will be replaced by their corresponding values:\n
  • %TURL: Thumbnail URL.
  • \n
  • %URL: Full image URL.
  • \n
  • %MD5: MD5 hash.
  • \n
  • %board: Current board.
  • \n
\n"; sauce = $('textarea', section); sauce.value = $.get('sauces', Conf['sauces']); @@ -1567,6 +1631,7 @@ }, rice: function(section) { var event, input, name, _i, _len, _ref; + section.innerHTML = "
\n Custom Board Navigation is disabled.\n
\n
In the following, board can translate to a board ID (a, b, etc...), the current board (current), or the Status/Twitter link (status, @).
\n
Board link: board
\n
Title link: board-title
\n
Full text link: board-full
\n
Custom text link: board-text:\"VIP Board\"
\n
Full board list toggle: toggle-all
\n
\n\n
\n Time Formatting is disabled.\n
:
\n \n
Day: %a, %A, %d, %e
\n
Month: %m, %b, %B
\n
Year: %y
\n
Hour: %k, %H, %l, %I, %p, %P
\n
Minute: %M
\n
Second: %S
\n
\n\n
\n Quote Backlinks formatting is disabled.\n
:
\n
\n\n
\n File Info Formatting is disabled.\n
:
\n
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
\n
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
\n
Spoiler indicator: %p
\n
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
\n
Resolution: %r (Displays 'PDF' for PDF files)
\n
\n\n
\n Unread Tab Icon is disabled.\n \n \n
\n\n
\n Custom CSS is disabled.\n \n \n
"; _ref = ['boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'usercss']; for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -1587,6 +1652,7 @@ }, time: function() { var funk; + funk = Time.createFunc(this.value); return this.nextElementSibling.textContent = funk(Time, new Date()); }, @@ -1595,6 +1661,7 @@ }, fileInfo: function() { var data, funk; + data = { isReply: true, file: { @@ -1626,6 +1693,7 @@ }, keybinds: function(section) { var arr, input, key, tbody, tr, _ref; + section.innerHTML = "
Keybinds are disabled.
\n
Allowed keys: a-z, 0-9, Ctrl, Shift, Alt, Meta, Enter, Esc, Up, Down, Right, Left.
\n
Press Backspace to disable a keybind.
\n\n \n
ActionsKeybinds
"; tbody = $('tbody', section); _ref = Config.hotkeys; @@ -1644,6 +1712,7 @@ }, keybind: function(e) { var key; + if (e.keyCode === 9) { return; } @@ -1660,6 +1729,7 @@ Fourchan = { init: function() { var board; + if (g.VIEW === 'catalog') { return; } @@ -1679,6 +1749,7 @@ }, code: function() { var pre, _i, _len, _ref; + if (this.isClone) { return; } @@ -1690,6 +1761,7 @@ }, math: function() { var jsMath; + if (this.isClone || !$('.math', this.nodes.comment)) { return; } @@ -1738,7 +1810,8 @@ Filter = { filters: {}, init: function() { - var boards, filter, hl, key, op, regexp, stub, top, _i, _len, _ref, _ref1, _ref2, _ref3, _ref4, _ref5; + var boards, err, filter, hl, key, op, regexp, stub, top, _i, _len, _ref, _ref1, _ref2, _ref3, _ref4, _ref5; + if (g.VIEW === 'catalog' || !Conf['Filter']) { return; } @@ -1763,7 +1836,8 @@ } else { try { regexp = RegExp(regexp[1], regexp[2]); - } catch (err) { + } catch (_error) { + err = _error; new Notification('warning', err.message, 60); continue; } @@ -1771,6 +1845,7 @@ op = ((_ref3 = filter.match(/[^t]op:(yes|no|only)/)) != null ? _ref3[1] : void 0) || 'yes'; stub = (function() { var _ref4; + switch ((_ref4 = filter.match(/stub:(yes|no)/)) != null ? _ref4[1] : void 0) { case 'yes': return true; @@ -1801,6 +1876,7 @@ }, createFilter: function(regexp, op, stub, hl, top) { var settings, test; + test = typeof regexp === 'string' ? function(value) { return regexp === value; } : function(value) { @@ -1824,6 +1900,7 @@ }, node: function() { var filter, firstThread, key, result, thisThread, value, _i, _len, _ref; + if (this.isClone) { return; } @@ -1935,6 +2012,7 @@ menu: { init: function() { var div, entry, type, _i, _len, _ref; + if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Filter']) { return; } @@ -1960,6 +2038,7 @@ }, createSubEntry: function(text, type) { var el; + el = $.el('a', { href: 'javascript:;', textContent: text @@ -1970,6 +2049,7 @@ el: el, open: function(post) { var value; + value = Filter[type](post); return value !== false; } @@ -1977,6 +2057,7 @@ }, makeFilter: function() { var re, save, section, select, ta, tl, type, value; + type = this.dataset.type; value = Filter[type](Filter.menu.post); re = type === 'uniqueID' || type === 'MD5' ? value : value.replace(/\/|\\|\^|\$|\n|\.|\(|\)|\{|\}|\[|\]|\?|\*|\+|\|/g, function(c) { @@ -2023,6 +2104,7 @@ }, node: function() { var data; + if (data = ThreadHiding.hiddenThreads.threads[this]) { ThreadHiding.hide(this, data.makeStub); } @@ -2038,6 +2120,7 @@ }, syncFromCatalog: function() { var hiddenThreadsOnCatalog, threadID, threads; + hiddenThreadsOnCatalog = JSON.parse(localStorage.getItem("4chan-hide-t-" + g.BOARD)) || {}; threads = ThreadHiding.hiddenThreads.threads; for (threadID in hiddenThreadsOnCatalog) { @@ -2061,6 +2144,7 @@ menu: { init: function() { var apply, div, makeStub; + if (g.VIEW !== 'index' || !Conf['Menu'] || !Conf['Thread Hiding']) { return; } @@ -2082,6 +2166,7 @@ order: 20, open: function(_arg) { var isReply, thread; + thread = _arg.thread, isReply = _arg.isReply; if (isReply || thread.isHidden) { return false; @@ -2100,6 +2185,7 @@ }, hide: function() { var makeStub, thread; + makeStub = $('input', this.parentNode).checked; thread = ThreadHiding.menu.thread; ThreadHiding.hide(thread, makeStub); @@ -2109,6 +2195,7 @@ }, makeButton: function(thread, type) { var a; + a = $.el('a', { className: "" + type + "-thread-button", innerHTML: "[ " + (type === 'hide' ? '-' : '+') + " ]", @@ -2120,6 +2207,7 @@ }, saveHiddenState: function(thread, makeStub) { var hiddenThreads, hiddenThreadsCatalog; + hiddenThreads = ThreadHiding.getHiddenThreads(); hiddenThreadsCatalog = JSON.parse(localStorage.getItem("4chan-hide-t-" + g.BOARD)) || {}; if (thread.isHidden) { @@ -2147,6 +2235,7 @@ }, hide: function(thread, makeStub) { var OP, a, numReplies, opInfo, span, threadRoot; + if (makeStub == null) { makeStub = Conf['Stubs']; } @@ -2180,6 +2269,7 @@ }, show: function(thread) { var threadRoot; + if (thread.stub) { $.rm(thread.stub); delete thread.stub; @@ -2203,6 +2293,7 @@ }, node: function() { var data, thread; + if (!this.isReply || this.isClone) { return; } @@ -2229,6 +2320,7 @@ menu: { init: function() { var apply, div, makeStub, replies, thisPost; + if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Reply Hiding']) { return; } @@ -2294,6 +2386,7 @@ order: 20, open: function(post) { var data, thread; + if (!post.isReply || post.isClone) { return false; } @@ -2319,6 +2412,7 @@ }, hide: function() { var makeStub, parent, post, replies, thisPost; + parent = this.parentNode; thisPost = $('input[name=thisPost]', parent).checked; replies = $('input[name=replies]', parent).checked; @@ -2337,6 +2431,7 @@ }, show: function() { var data, parent, post, replies, thisPost, thread; + parent = this.parentNode; thisPost = $('input[name=thisPost]', parent).checked; replies = $('input[name=replies]', parent).checked; @@ -2359,6 +2454,7 @@ }, makeButton: function(post, type) { var a; + a = $.el('a', { className: "" + type + "-reply-button", innerHTML: "[ " + (type === 'hide' ? '-' : '+') + " ]", @@ -2369,6 +2465,7 @@ }, saveHiddenState: function(post, isHiding, thisPost, makeStub, hideRecursively) { var hiddenPosts, thread; + hiddenPosts = ReplyHiding.getHiddenPosts(); if (isHiding) { if (!(thread = hiddenPosts.threads[post.thread])) { @@ -2390,6 +2487,7 @@ }, toggle: function() { var post; + post = Get.postFromNode(this); if (post.isHidden) { ReplyHiding.show(post); @@ -2400,6 +2498,7 @@ }, hide: function(post, makeStub, hideRecursively) { var a, postInfo, quotelink, _i, _len, _ref; + if (makeStub == null) { makeStub = Conf['Stubs']; } @@ -2437,6 +2536,7 @@ }, show: function(post, showRecursively) { var quotelink, _i, _len, _ref; + if (showRecursively == null) { showRecursively = Conf['Recursive Hiding']; } @@ -2472,6 +2572,7 @@ }, node: function() { var i, obj, quote, recursive, _i, _j, _len, _len1, _ref, _ref1; + if (this.isClone) { return; } @@ -2489,6 +2590,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: [], @@ -2499,6 +2601,7 @@ }, rm: function(recursive, post) { var i, obj, rec, _i, _len, _ref; + if (!(obj = Recursive.recursives[post.fullID])) { return; } @@ -2513,6 +2616,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; @@ -2537,6 +2641,7 @@ }, node: function() { var board, postID, quotelink, _i, _len, _ref, _ref1, _ref2; + if (this.isClone) { return; } @@ -2564,6 +2669,7 @@ }, node: function() { var button; + button = Menu.makeButton(this); if (this.isClone) { $.replace($('.menu-button', this.nodes.info), button); @@ -2573,9 +2679,11 @@ }, makeButton: (function() { var a; + a = null; return function(post) { var clone; + a || (a = $.el('a', { className: 'menu-button', innerHTML: '[]', @@ -2592,6 +2700,7 @@ })(), toggle: function(e) { var post; + post = this.dataset.clone ? Get.postFromNode(this) : g.posts[this.dataset.postid]; return Menu.menu.toggle(e, this, post); } @@ -2600,6 +2709,7 @@ ReportLink = { init: function() { var a; + if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Report Link']) { return; } @@ -2621,6 +2731,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(); @@ -2632,6 +2743,7 @@ DeleteLink = { init: function() { var div, fileEl, fileEntry, postEl, postEntry; + if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Delete Link'] || !Conf['Quick Reply']) { return; } @@ -2659,6 +2771,7 @@ el: fileEl, open: function(_arg) { var file; + file = _arg.file; if (!file || file.isDead) { return false; @@ -2674,6 +2787,7 @@ order: 40, open: function(post) { var node, seconds, thread, _ref; + if (post.isDead || !((thread = QR.yourPosts.threads[post.thread]) && (_ref = post.ID, __indexOf.call(thread, _ref) >= 0))) { return false; } @@ -2694,6 +2808,7 @@ }, "delete": function() { var form, link, m, post, pwd; + post = DeleteLink.post; if (DeleteLink.cooldown[post.fullID]) { return; @@ -2721,6 +2836,7 @@ }, load: function(link, html) { var msg, s, tmpDoc; + tmpDoc = d.implementation.createHTMLDocument(''); tmpDoc.documentElement.innerHTML = html; if (tmpDoc.title === '4chan - Banned') { @@ -2740,6 +2856,7 @@ cooldown: { start: function(post) { var length, seconds; + if (post.fullID in DeleteLink.cooldown) { return; } @@ -2749,6 +2866,7 @@ }, count: function(fullID, seconds, length) { var el; + if (!((0 <= seconds && seconds <= length))) { return; } @@ -2773,6 +2891,7 @@ DownloadLink = { init: function() { var a; + if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Download Link']) { return; } @@ -2789,6 +2908,7 @@ order: 70, open: function(_arg) { var file; + file = _arg.file; if (!file) { return false; @@ -2804,6 +2924,7 @@ ArchiveLink = { init: function() { var div, entry, type, _i, _len, _ref; + if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Archive Link']) { return; } @@ -2816,6 +2937,7 @@ order: 90, open: function(_arg) { var board, postID, redirect, threadID; + postID = _arg.ID, threadID = _arg.thread, board = _arg.board; redirect = Redirect.to({ postID: postID, @@ -2835,6 +2957,7 @@ }, createSubEntry: function(text, type) { var el, open; + el = $.el('a', { textContent: text, target: '_blank' @@ -2842,6 +2965,7 @@ if (type === 'post') { open = function(_arg) { var board, postID, threadID; + postID = _arg.ID, threadID = _arg.thread, board = _arg.board; el.href = Redirect.to({ postID: postID, @@ -2853,6 +2977,7 @@ } else { open = function(post) { var value; + value = Filter[type](post); if (!value) { return false; @@ -2880,6 +3005,7 @@ } return $.on(d, '4chanXInitFinished', function() { var node, _i, _len, _ref; + $.on(d, 'keydown', Keybinds.keydown); _ref = $$('[accesskey]'); for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -2890,6 +3016,7 @@ }, keydown: function(e) { var form, key, notification, notifications, target, thread, threadRoot, _i, _len, _ref; + if (!(key = Keybinds.keyCode(e))) { return; } @@ -3025,6 +3152,7 @@ }, keyCode: function(e) { var kc, key; + key = (function() { switch (kc = e.keyCode) { case 8: @@ -3077,6 +3205,7 @@ }, tags: function(tag, ta) { var range, selEnd, selStart, value; + value = ta.value; selStart = ta.selectionStart; selEnd = ta.selectionEnd; @@ -3087,6 +3216,7 @@ }, img: function(thread, all) { var post; + if (all) { return ImageExpand.cb.toggleAll(); } else { @@ -3096,6 +3226,7 @@ }, open: function(thread, tab) { var url; + if (g.VIEW !== 'index') { return; } @@ -3108,6 +3239,7 @@ }, hl: function(delta, thread) { var headRect, next, postEl, rect, replies, reply, root, topMargin, _i, _len; + headRect = Header.bar.getBoundingClientRect(); topMargin = headRect.top + headRect.height; if (postEl = $('.reply.highlight', thread)) { @@ -3157,6 +3289,7 @@ Nav = { init: function() { var next, prev, span; + if (g.VIEW !== 'index' || !Conf['Index Navigation']) { return; } @@ -3186,6 +3319,7 @@ }, getThread: function(full) { var headRect, i, rect, thread, threads, topMargin, _i, _len; + headRect = Header.bar.getBoundingClientRect(); topMargin = headRect.top + headRect.height; threads = $$('.thread:not([hidden])'); @@ -3204,6 +3338,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 && Math.ceil(top) < 0) || (delta === +1 && top > 1))) { @@ -3270,6 +3405,7 @@ }, to: function(data) { var board, url; + board = data.board; switch ("" + board) { case 'a': @@ -3327,6 +3463,7 @@ }, path: function(base, archiver, data) { var board, path, postID, threadID, type, value; + if (data.isSearch) { board = data.board, type = data.type, value = data.value; type = type === 'name' ? 'username' : type === 'MD5' ? 'image' : type; @@ -3358,6 +3495,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); @@ -3367,6 +3505,7 @@ }, postFromObject: function(data, board) { var o; + o = { postID: data.no, threadID: data.resto || data.no, @@ -3410,6 +3549,7 @@ */ var a, board, capcode, capcodeClass, 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, board = o.board, 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, file = o.file; isOP = postID === threadID; staticPath = '//static.4chan.org'; @@ -3507,12 +3647,14 @@ 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(); return "/" + thread.board + "/ - " + excerpt; }, postFromRoot: function(root) { var board, index, link, post, postID; + link = $('a[title="Highlight this post"]', root); board = link.pathname.split('/')[1]; postID = link.hash.slice(2); @@ -3532,6 +3674,7 @@ }, postDataFromLink: function(link) { var board, path, postID, threadID; + if (link.hostname === 'boards.4chan.org') { path = link.pathname.split('/'); board = path[1]; @@ -3550,6 +3693,7 @@ }, allQuotelinksLinkingTo: function(post) { var ID, quote, quotedPost, quotelinks, quoterPost, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _ref4; + quotelinks = []; _ref = g.posts; for (ID in _ref) { @@ -3578,12 +3722,14 @@ } return quotelinks.filter(function(quotelink) { var board, postID, _ref5; + _ref5 = Get.postDataFromLink(quotelink), board = _ref5.board, postID = _ref5.postID; return board === post.board.ID && postID === post.ID; }); }, postClone: function(board, threadID, postID, root, context) { var post, url; + if (post = g.posts["" + board + "." + postID]) { Get.insert(post, root, context); return; @@ -3601,6 +3747,7 @@ }, insert: function(post, root, context) { var clone, nodes; + if (!root.parentNode) { return; } @@ -3614,6 +3761,7 @@ }, fetchedPost: function(req, board, threadID, postID, root, context) { var post, posts, status, thread, url, _i, _len; + if (post = g.posts["" + board + "." + postID]) { Get.insert(post, root, context); return; @@ -3657,6 +3805,7 @@ }, archivedPost: function(req, board, postID, root, context) { var bq, comment, data, o, post, thread, threadID, _ref; + if (post = g.posts["" + board + "." + postID]) { Get.insert(post, root, context); return; @@ -3751,6 +3900,7 @@ Misc = { clearThreads: function(key) { var data; + if (!(data = $.get(key))) { return; } @@ -3764,6 +3914,7 @@ return $.ajax("//api.4chan.org/" + g.BOARD + "/catalog.json", { onload: function() { var obj, thread, threads, _i, _j, _len, _len1, _ref, _ref1; + threads = {}; _ref = JSON.parse(this.response); for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -3800,6 +3951,7 @@ }, node: function() { var ID, a, board, deadlink, m, post, quote, quoteID, redirect, _i, _len, _ref, _ref1; + if (this.isClone) { return; } @@ -3878,6 +4030,7 @@ }, node: function() { var link, _i, _j, _len, _len1, _ref, _ref1; + _ref = this.nodes.quotelinks; for (_i = 0, _len = _ref.length; _i < _len; _i++) { link = _ref[_i]; @@ -3891,6 +4044,7 @@ }, toggle: function(e) { var board, context, postID, threadID, _ref; + if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) { return; } @@ -3916,6 +4070,7 @@ }, add: function(quotelink, board, threadID, postID, context) { var i, inline, isBacklink, post; + isBacklink = $.hasClass(quotelink, 'backlink'); inline = $.el('div', { id: "i" + postID, @@ -3937,6 +4092,7 @@ }, rm: function(quotelink, board, threadID, postID, context) { var el, inlined, isBacklink, post, root, _ref; + isBacklink = $.hasClass(quotelink, 'backlink'); root = QuoteInline.findRoot(quotelink, isBacklink); root = $.x("following-sibling::div[@id='i" + postID + "'][1]", root); @@ -3970,6 +4126,7 @@ }, node: function() { var link, _i, _j, _len, _len1, _ref, _ref1; + _ref = this.nodes.quotelinks; for (_i = 0, _len = _ref.length; _i < _len; _i++) { link = _ref[_i]; @@ -3983,6 +4140,7 @@ }, mouseover: function(e) { var board, clone, origin, post, postID, posts, qp, quote, quoterID, threadID, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2; + if ($.hasClass(this, 'inlined')) { return; } @@ -4033,6 +4191,7 @@ }, mouseout: function() { var clone, post, root, _i, _len, _ref; + if (!(root = this.el.firstElementChild)) { return; } @@ -4053,6 +4212,7 @@ QuoteBacklink = { init: function() { var format; + if (g.VIEW === 'catalog' || !Conf['Quote Backlinks']) { return; } @@ -4070,6 +4230,7 @@ }, firstNode: function() { var a, clone, container, containers, link, post, quote, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; + if (this.isClone || !this.quotes.length) { return; } @@ -4104,6 +4265,7 @@ }, secondNode: function() { var container; + if (this.isClone && (this.origin.isReply || Conf['OP Backlinks'])) { this.nodes.backlinkContainer = $('.container', this.nodes.info); return; @@ -4117,6 +4279,7 @@ }, getContainer: function(id) { var _base; + return (_base = this.containers)[id] || (_base[id] = $.el('span', { className: 'container' })); @@ -4136,6 +4299,7 @@ }, node: function() { var postID, quotelink, quotelinks, quotes, thread, threadID, _i, _len, _ref; + if (this.isClone) { return; } @@ -4166,6 +4330,7 @@ }, node: function() { var board, op, postID, quotelink, quotelinks, quotes, _i, _j, _len, _len1, _ref, _ref1; + if (this.isClone && this.thread === this.context.thread) { return; } @@ -4206,6 +4371,7 @@ }, node: function() { var board, data, quotelink, quotelinks, quotes, thread, _i, _len, _ref; + if (this.isClone && this.thread === this.context.thread) { return; } @@ -4242,6 +4408,7 @@ }, node: function() { var email, name, tripcode, _ref; + if (this.info.capcode || this.isClone) { return; } @@ -4283,6 +4450,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) + '"; @@ -4376,6 +4544,7 @@ }, node: function() { var dateEl; + if (this.isClone) { return; } @@ -4385,6 +4554,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) { @@ -4395,6 +4565,7 @@ stale: [], flush: function() { var now, update, _i, _len, _ref; + if (d.hidden) { return; } @@ -4410,13 +4581,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); @@ -4453,6 +4627,7 @@ }, createFunc: function(format) { var code; + code = format.replace(/%(.)/g, function(s, c) { if (c in FileInfo.formatters) { return "' + FileInfo.formatters." + c + ".call(post) + '"; @@ -4464,6 +4639,7 @@ }, convertUnit: function(size, unit) { var i; + if (unit === 'B') { return "" + (size.toFixed()) + " Bytes"; } @@ -4494,6 +4670,7 @@ }, n: function() { var fullname, shortname; + fullname = this.file.name; shortname = Build.shortFilename(this.file.name, this.isReply); if (fullname === shortname) { @@ -4537,6 +4714,7 @@ Sauce = { init: function() { var link, links, _i, _len, _ref; + if (g.VIEW === 'catalog' || !Conf['Sauce']) { return; } @@ -4563,6 +4741,7 @@ }, createSauceLink: function(link) { var m, text; + link = link.replace(/%(T?URL|MD5|board)/g, function(parameter) { switch (parameter) { case '%TURL': @@ -4583,6 +4762,7 @@ }, node: function() { var link, nodes, _i, _len, _ref; + if (this.isClone || !this.file) { return; } @@ -4633,6 +4813,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'; @@ -4662,6 +4843,7 @@ }, setFitness: function() { var checked; + checked = this.checked; (checked ? $.addClass : $.rmClass)(doc, this.name.toLowerCase().replace(/\s+/g, '-')); if (this.name !== 'Fit height') { @@ -4680,6 +4862,7 @@ }, toggle: function(post) { var headRect, postRect, rect, root, thumb, top; + thumb = post.file.thumb; if (!(post.file.isExpanded || $.hasClass(thumb, 'expanding'))) { ImageExpand.expand(post); @@ -4707,6 +4890,7 @@ }, expand: function(post, src) { var img, thumb; + thumb = post.file.thumb; if (post.isHidden || post.file.isExpanded || $.hasClass(thumb, 'expanding')) { return; @@ -4734,6 +4918,7 @@ }, completeExpand: function(post) { var rect, root, thumb; + thumb = post.file.thumb; if (!$.hasClass(thumb, 'expanding')) { return; @@ -4749,6 +4934,7 @@ }, error: function() { var URL, post, src, timeoutID; + post = Get.postFromNode(this); $.rm(this); delete post.file.fullImage; @@ -4770,6 +4956,7 @@ return $.ajax("//api.4chan.org/" + post.board + "/res/" + post.thread + ".json", { onload: function() { var postObj, _i, _len, _ref; + if (this.status !== 200) { return; } @@ -4793,6 +4980,7 @@ menu: { init: function() { var conf, createSubEntry, el, key, subEntries, _ref; + if (g.VIEW === 'catalog' || !Conf['Image Expansion']) { return; } @@ -4816,6 +5004,7 @@ }, createSubEntry: function(type, config) { var input, label; + label = $.el('label', { innerHTML: " " + type }); @@ -4851,6 +5040,7 @@ }, node: function() { var thumb, _ref; + if (this.isClone || !((_ref = this.file) != null ? _ref.isSpoiler : void 0)) { return; } @@ -4863,6 +5053,7 @@ AutoGIF = { init: function() { var _ref; + if (g.VIEW === 'catalog' || !Conf['Auto-GIF'] || ((_ref = g.BOARD.ID) === 'gif' || _ref === 'wsg')) { return; } @@ -4873,6 +5064,7 @@ }, node: function() { var URL, gif, style, thumb, _ref, _ref1; + if (this.isClone || this.isHidden || this.thread.isHidden || !((_ref = this.file) != null ? _ref.isImage : void 0)) { return; } @@ -4904,6 +5096,7 @@ }, node: function() { var _ref; + if (!((_ref = this.file) != null ? _ref.isImage : void 0)) { return; } @@ -4911,6 +5104,7 @@ }, mouseover: function(e) { var el, post; + post = Get.postFromNode(this); el = $.el('img', { id: 'ihover', @@ -4932,6 +5126,7 @@ error: function() { var URL, post, src, timeoutID, _this = this; + if (!doc.contains(this)) { return; } @@ -4952,6 +5147,7 @@ return $.ajax("//api.4chan.org/" + post.board + "/res/" + post.thread + ".json", { onload: function() { var postObj, _i, _len, _ref; + if (this.status !== 200) { return; } @@ -4986,18 +5182,21 @@ }, node: function() { var a; + if (a = $('.abbr > a', this.nodes.comment)) { return $.on(a, 'click', ExpandComment.cb); } }, cb: function(e) { var post; + e.preventDefault(); post = Get.postFromNode(this); return ExpandComment.expand(post); }, expand: function(post) { var a; + if (post.nodes.longComment) { $.replace(post.nodes.shortComment, post.nodes.longComment); post.nodes.comment = post.nodes.longComment; @@ -5013,6 +5212,7 @@ }, contract: function(post) { var a; + if (!post.nodes.shortComment) { return; } @@ -5023,6 +5223,7 @@ }, parse: function(req, a, post) { var clone, comment, href, postObj, posts, quote, spoilerRange, status, _i, _j, _len, _len1, _ref; + status = req.status; if (status !== 200 && status !== 304) { a.textContent = "Error " + req.statusText + " (" + status + ")"; @@ -5095,6 +5296,7 @@ }, node: function() { var a, span; + if (!(span = $('.summary', this.OP.nodes.root.parentNode))) { return; } @@ -5108,11 +5310,13 @@ }, cbToggle: function() { var op; + op = Get.postFromRoot(this.previousElementSibling); return ExpandThread.toggle(op.thread); }, toggle: function(thread) { var a, inlined, num, post, replies, reply, text, threadRoot, url, _i, _j, _k, _len, _len1, _len2, _ref, _ref1; + threadRoot = thread.OP.nodes.root.parentNode; url = "//api.4chan.org/" + thread.board + "/res/" + thread + ".json"; a = $('.summary', threadRoot); @@ -5169,6 +5373,7 @@ }, parse: function(req, thread, a) { var link, node, nodes, post, posts, replies, reply, spoilerRange, status, _i, _len; + if (a.textContent[0] === '+') { return; } @@ -5241,6 +5446,7 @@ }, node: function() { var ID, post, posts, _ref; + Unread.thread = this; Unread.lastReadPost = $.get("lastReadPosts." + this.board, { threads: {} @@ -5270,6 +5476,7 @@ }, addPosts: function(newPosts) { var ID, post, youInThisThread, yourPosts, _i, _len, _ref; + if (Conf['Quick Reply']) { yourPosts = QR.yourPosts; youInThisThread = yourPosts.threads[Unread.thread]; @@ -5293,6 +5500,7 @@ }, addPostQuotingYou: function(post, yourPosts) { var board, postIDs, quote, quoteID, thread, _i, _len, _ref, _ref1, _ref2; + _ref = post.quotes; for (_i = 0, _len = _ref.length; _i < _len; _i++) { quote = _ref[_i]; @@ -5319,6 +5527,7 @@ }, read: function(e) { var bottom, height, i, post, _i, _j, _len, _len1, _ref, _ref1; + if (d.hidden || !Unread.posts.length) { return; } @@ -5351,6 +5560,7 @@ }, saveLastReadPost: $.debounce($.SECOND, function() { var lastReadPosts; + lastReadPosts = $.get("lastReadPosts." + Unread.thread.board, { threads: {} }); @@ -5359,6 +5569,7 @@ }), setLine: function(force) { var post, root; + if (!(d.hidden || force === true)) { return; } @@ -5373,6 +5584,7 @@ }, update: function() { var count; + count = Unread.posts.length; if (Conf['Unread Count']) { d.title = g.DEAD ? "(" + Unread.posts.length + ") /" + g.BOARD + "/ - 404" : "(" + Unread.posts.length + ") " + Unread.title; @@ -5389,6 +5601,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; @@ -5458,6 +5671,7 @@ }, node: function() { var ID, fileCount, post, postCount, _ref; + postCount = 0; fileCount = 0; _ref = this.posts; @@ -5475,6 +5689,7 @@ }, onUpdate: function(e) { var fileCount, fileLimit, postCount, postLimit, _ref; + if (e.detail[404]) { return; } @@ -5492,6 +5707,7 @@ ThreadUpdater = { init: function() { var checked, conf, html, name, _ref; + if (g.VIEW !== 'thread' || !Conf['Thread Updater']) { return; } @@ -5514,6 +5730,7 @@ }, node: function() { var input, _i, _len, _ref; + ThreadUpdater.thread = this; ThreadUpdater.root = this.OP.nodes.root.parentNode; ThreadUpdater.lastPost = +ThreadUpdater.root.lastElementChild.id.match(/\d+/)[0]; @@ -5603,12 +5820,14 @@ }, interval: function() { var val; + val = Math.max(5, parseInt(this.value, 10)); ThreadUpdater.interval = this.value = val; return $.cb.value.call(this); }, load: function() { var klass, req, text, _ref, _ref1; + req = ThreadUpdater.req; switch (req.status) { case 200: @@ -5645,6 +5864,7 @@ }, getInterval: function() { var i, j; + i = ThreadUpdater.interval; j = Math.min(ThreadUpdater.outdateCount, 10); if (!d.hidden) { @@ -5654,6 +5874,7 @@ }, set: function(name, text, klass) { var el, node; + el = ThreadUpdater[name]; if (node = el.firstChild) { node.data = text; @@ -5666,6 +5887,7 @@ }, timeout: function() { var n; + ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.timeout, 1000); if (!(n = --ThreadUpdater.seconds)) { return ThreadUpdater.update(); @@ -5678,6 +5900,7 @@ }, update: function() { var url; + if (!ThreadUpdater.online) { return; } @@ -5698,6 +5921,7 @@ }, updateThreadStatus: function(title, OP) { var icon, message, root, titleLC; + titleLC = title.toLowerCase(); if (ThreadUpdater.thread["is" + title] === !!OP[titleLC]) { return; @@ -5724,6 +5948,7 @@ }, parse: function(postObjects) { var ID, OP, count, deletedFiles, deletedPosts, files, index, node, nodes, num, post, postObject, posts, scroll, _i, _len, _ref; + OP = postObjects[0]; Build.spoilerRange[ThreadUpdater.thread.board] = OP.custom_spoiler; ThreadUpdater.updateThreadStatus('Sticky', OP); @@ -5791,6 +6016,7 @@ } $.queueTask(function() { var length, threadID; + threadID = ThreadUpdater.thread.ID; length = ThreadUpdater.root.children.length; if (Conf['Enable 4chan\'s Extension']) { @@ -5830,6 +6056,7 @@ }, node: function() { var favicon; + favicon = $.el('img', { className: 'favicon' }); @@ -5846,6 +6073,7 @@ }, refresh: function(watched) { var ID, board, div, favicon, id, link, nodes, props, thread, x, _ref, _ref1; + watched || (watched = $.get('WatchedThreads', {})); nodes = [$('.move', ThreadWatcher.dialog)]; for (board in watched) { @@ -5880,11 +6108,13 @@ }, x: function() { var thread; + thread = this.nextElementSibling.pathname.split('/'); return ThreadWatcher.unwatch(thread[1], thread[3]); }, 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']) { @@ -5904,6 +6134,7 @@ }, unwatch: function(board, threadID) { var watched; + watched = $.get('WatchedThreads', {}); delete watched[board][threadID]; if (!Object.keys(watched[board]).length) { @@ -5914,6 +6145,7 @@ }, watch: function(thread) { var watched, _name; + watched = $.get('WatchedThreads', {}); watched[_name = thread.board] || (watched[_name] = {}); watched[thread.board][thread] = { @@ -5943,6 +6175,7 @@ }, initReady: function() { var sc; + QR.postingIsEnabled = !!$.id('postForm'); if (!QR.postingIsEnabled) { return; @@ -5987,6 +6220,8 @@ } }, open: function() { + var err; + if (QR.nodes) { QR.nodes.el.hidden = false; QR.unhide(); @@ -5994,7 +6229,8 @@ } try { return QR.dialog(); - } catch (err) { + } catch (_error) { + err = _error; delete QR.nodes; return Main.handleErrors({ message: 'Quick Reply dialog creation crashed.', @@ -6004,6 +6240,7 @@ }, close: function() { var i, _i, _len, _ref; + if (QR.req) { QR.abort(); return; @@ -6051,6 +6288,7 @@ }, error: function(err) { var el; + QR.open(); if (typeof err === 'string') { el = $.tn(err); @@ -6069,6 +6307,7 @@ notifications: [], cleanNotifications: function() { var notification, _i, _len, _ref; + _ref = QR.notifications; for (_i = 0, _len = _ref.length; _i < _len; _i++) { notification = _ref[_i]; @@ -6078,6 +6317,7 @@ }, status: function() { var disabled, status, value; + if (!QR.nodes) { return; } @@ -6094,6 +6334,7 @@ cooldown: { init: function() { var board; + board = g.BOARD.ID; QR.cooldown.types = { thread: (function() { @@ -6127,6 +6368,7 @@ }, sync: function(cooldowns) { var id; + for (id in cooldowns) { QR.cooldown.cooldowns[id] = cooldowns[id]; } @@ -6134,6 +6376,7 @@ }, set: function(data) { var cooldown, delay, hasFile, isReply, isSage, post, req, start, type, upSpd; + req = data.req, post = data.post, isReply = data.isReply, delay = data.delay; start = req ? req.uploadEndTime : Date.now(); if (delay) { @@ -6170,6 +6413,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; @@ -6223,6 +6467,7 @@ }, quote: function(e) { var OP, caretPos, post, range, s, sel, selectionRoot, ta, text; + if (e != null) { e.preventDefault(); } @@ -6252,6 +6497,7 @@ }, characterCount: function() { var count, counter; + counter = QR.nodes.charCount; count = QR.nodes.com.textLength; counter.textContent = count; @@ -6260,6 +6506,7 @@ }, drag: function(e) { var toggle; + toggle = e.type === 'dragstart' ? $.off : $.on; toggle(d, 'dragover', QR.dragOver); return toggle(d, 'drop', QR.dropFile); @@ -6279,6 +6526,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++) { @@ -6303,6 +6551,7 @@ }, fileInput: function(files) { var file, length, max, post, _i, _len, _ref, _ref1; + if (this instanceof Element) { files = __slice.call(this.files); QR.nodes.fileInput.value = null; @@ -6355,10 +6604,10 @@ }, posts: [], post: (function() { - function _Class() { var el, event, persona, prev, _i, _len, _ref, _this = this; + prev = QR.posts[QR.posts.length - 1]; persona = $.get('QR.persona', {}); this.name = prev ? prev.name : persona.name || null; @@ -6406,6 +6655,7 @@ _Class.prototype.rm = function() { var index; + $.rm(this.nodes.el); index = QR.posts.indexOf(this); if (QR.posts.length === 1) { @@ -6422,6 +6672,7 @@ _Class.prototype.lock = function(lock) { var name, _i, _len, _ref; + if (lock == null) { lock = true; } @@ -6446,6 +6697,7 @@ _Class.prototype.select = function() { var name, rectEl, rectList, _i, _len, _ref; + if (QR.selected) { QR.selected.nodes.el.id = null; QR.selected.forceSave(); @@ -6467,6 +6719,7 @@ _Class.prototype.save = function(input) { var value, _ref; + value = input.value; this[input.dataset.name] = value; if (input.nodeName !== 'TEXTAREA') { @@ -6481,6 +6734,7 @@ _Class.prototype.forceSave = function() { var name, _i, _len, _ref; + if (this !== QR.selected) { return; } @@ -6512,6 +6766,7 @@ _Class.prototype.setThumbnail = function(fileURL) { var img, reader, _this = this; + if (!window.URL) { if (!fileURL) { reader = new FileReader(); @@ -6527,6 +6782,7 @@ img = $.el('img'); img.onload = function() { var applyBlob, cv, data, height, i, l, s, ui8a, width, _i; + s = 90 * 2; height = img.height, width = img.width; if (height < s || width < s) { @@ -6605,9 +6861,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; @@ -6645,6 +6903,7 @@ _Class.prototype.drop = function() { var el, index, newIndex, oldIndex, post; + el = $('.drag', this.parentNode); $.rmClass(el, 'drag'); $.rmClass(this, 'over'); @@ -6678,6 +6937,7 @@ }, ready: function() { var MutationObserver, imgContainer, input, observer; + imgContainer = $.el('div', { className: 'captcha-img', title: 'Reload', @@ -6716,6 +6976,7 @@ }, getOne: function() { var captcha, challenge, response; + this.clear(); if (captcha = this.captchas.shift()) { challenge = captcha.challenge, response = captcha.response; @@ -6740,6 +7001,7 @@ }, save: function() { var response; + if (!(response = this.nodes.input.value.trim())) { return; } @@ -6754,6 +7016,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) { @@ -6771,6 +7034,7 @@ }, load: function() { var challenge; + if (!this.nodes.challenge.firstChild) { return; } @@ -6783,6 +7047,7 @@ }, count: function() { var count; + count = this.captchas.length; this.nodes.input.placeholder = (function() { switch (count) { @@ -6815,6 +7080,7 @@ }, dialog: function() { var dialog, mimeTypes, name, node, nodes, thread, _i, _j, _len, _len1, _ref, _ref1; + dialog = UI.dialog('qr', 'top:0;right:0;', "
\n \n \n \n ×\n
\n
\n
\n \n \n \n \n
\n
\n
\n +\n
\n
\n \n \n
\n
\n \n \n No selected file\n \n \n ×\n \n \n
\n \n
".replace(/>\s+<')); QR.nodes = nodes = { el: dialog, @@ -6911,6 +7177,7 @@ }, submit: function(e) { var callbacks, challenge, err, filetag, m, opts, post, postData, response, textOnly, threadID, _ref, _ref1; + if (e != null) { e.preventDefault(); } @@ -7009,6 +7276,7 @@ }, response: function() { var URL, ban, board, err, h1, persona, post, postID, req, threadID, tmpDoc, _, _base, _ref, _ref1; + req = QR.req; delete QR.req; post = QR.posts[0]; @@ -7109,6 +7377,7 @@ }, ready: function() { var field, form; + form = $('form'); field = $.id('recaptcha_response_field'); $.on(field, 'keydown', function(e) { @@ -7118,6 +7387,7 @@ }); return $.on(form, 'submit', function(e) { var response; + e.preventDefault(); response = field.value.trim(); if (!/\s/.test(response)) { @@ -7129,7 +7399,6 @@ }; Board = (function() { - Board.prototype.toString = function() { return this.ID; }; @@ -7146,7 +7415,6 @@ })(); Thread = (function() { - Thread.prototype.callbacks = []; Thread.prototype.toString = function() { @@ -7171,7 +7439,6 @@ })(); Post = (function() { - Post.prototype.callbacks = []; Post.prototype.toString = function() { @@ -7180,6 +7447,7 @@ function Post(root, thread, board, that) { var alt, anchor, capcode, date, email, file, fileInfo, flag, info, name, post, size, subject, thumb, tripcode, uniqueID, unit; + this.thread = thread; this.board = board; if (that == null) { @@ -7271,6 +7539,7 @@ Post.prototype.parseComment = function() { var bq, data, i, node, nodes, text, _i, _j, _len, _ref, _ref1; + bq = this.nodes.comment.cloneNode(true); _ref = $$('.abbr, .capcodeReplies, .exif, b', bq); for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -7287,6 +7556,7 @@ Post.prototype.parseQuotes = function() { var hash, pathname, quotelink, quotes, _i, _len, _ref; + quotes = {}; _ref = $$('.quotelink', this.nodes.comment); for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -7316,6 +7586,7 @@ Post.prototype.kill = function(file, now) { var clone, quotelink, strong, _i, _j, _len, _len1, _ref, _ref1; + now || (now = new Date()); if (file) { this.file.isDead = true; @@ -7358,6 +7629,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'); @@ -7391,6 +7663,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++) { @@ -7404,11 +7677,11 @@ })(); Clone = (function(_super) { - __extends(Clone, _super); function Clone(origin, context) { var file, index, 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']; @@ -7494,8 +7767,10 @@ Main = { init: function() { var flatten, initFeature, key, pathname, val; + flatten = function(parent, obj) { var key, val; + if (obj instanceof Array) { Conf[parent] = obj[0]; } else if (typeof obj === 'object') { @@ -7534,6 +7809,7 @@ case 'images.4chan.org': $.ready(function() { var url; + if (Conf['404 Redirect'] && d.title === '4chan - 404 Not Found') { url = Redirect.image(pathname[1], pathname[3]); if (url) { @@ -7544,9 +7820,12 @@ return; } initFeature = function(name, module) { + var err; + try { return module.init(); - } catch (err) { + } catch (_error) { + err = _error; return Main.handleErrors({ message: "\"" + name + "\" initialization crashed.", error: err @@ -7605,6 +7884,7 @@ }, initStyle: function() { var MutationObserver, mainStyleSheet, observer, setStyle, style, styleSheets, _ref; + if (!Main.isThisPageLegit()) { return; } @@ -7623,6 +7903,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]; @@ -7648,7 +7929,8 @@ } }, initReady: function() { - var board, boardChild, errors, href, posts, thread, threadChild, threads, _i, _j, _len, _len1, _ref, _ref1; + var board, boardChild, err, errors, href, posts, thread, threadChild, threads, _i, _j, _len, _len1, _ref, _ref1; + if (d.title === '4chan - 404 Not Found') { if (Conf['404 Redirect'] && g.VIEW === 'thread') { href = Redirect.to({ @@ -7682,7 +7964,8 @@ } try { posts.push(new Post(threadChild, thread, g.BOARD)); - } catch (err) { + } catch (_error) { + err = _error; if (!errors) { errors = []; } @@ -7702,7 +7985,8 @@ return $.event('4chanXInitFinished'); }, callbackNodes: function(klass, nodes) { - var callback, errors, i, len, node, _i, _j, _len, _ref; + var callback, err, errors, i, len, node, _i, _j, _len, _ref; + len = nodes.length; _ref = klass.prototype.callbacks; for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -7711,7 +7995,8 @@ node = nodes[i]; try { callback.cb.call(node); - } catch (err) { + } catch (_error) { + err = _error; if (!errors) { errors = []; } @@ -7728,6 +8013,7 @@ }, addCallback: function(e) { var Klass, obj; + obj = e.detail; Klass = obj.type === 'Post' ? Post : Thread; obj.callback.isAddon = true; @@ -7735,6 +8021,7 @@ }, handleErrors: function(errors) { var div, error, logs, _i, _len; + if (!('length' in errors)) { error = errors; } else if (errors.length === 1) { @@ -7767,6 +8054,7 @@ }, parseError: function(data) { var error, message; + message = data.message, error = data.error; c.log(message, error.stack); message = $.el('div', { diff --git a/package.json b/package.json index ad5deea45..a099124d4 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "grunt": "~0.4.0", "grunt-bump": "~0.0.0", "grunt-contrib-clean": "~0.4.0", - "grunt-contrib-coffee": "~0.6.0", + "grunt-contrib-coffee": "~0.6.2", "grunt-contrib-concat": "~0.1.0", "grunt-contrib-watch": "~0.3.0", "grunt-exec": "~0.4.0"