diff --git a/CHANGELOG.md b/CHANGELOG.md index 791380468..2ceddee09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,72 @@ +<<<<<<< HEAD ### v2.9.26 *2014-05-07* +======= +**MayhemYDG**: +- [Security fix](https://github.com/MayhemYDG/4chan-x/issues/1634). + +### v1.7.33 +*2014-05-10* + +**DamonGant** +- Add Innovandalism Archive. + +**ccd0** +- Update archive list. +- Add "disabled" option when Foolz Beta is the only choice. + +### v1.7.32 +*2014-05-10* + +**Zixaphir, ccd0** +- Bug fixes in linkification/embedding. + +**ccd0** +- Begin refactoring code to reduce potential for introducing Javascript injection bugs. + +### v1.7.31 +*2014-05-08* + +**Zixaphir** +- Refactoring, bug fixes. + +**ccd0** +- Fix some potential Javascript injection issues. +- Bug fixes. + +### v1.7.30 +*2014-05-05* + +**thebladeee** +- Update archives. + +### v1.7.29 +*2014-05-03* + +**ccd0**: +- If the original post form not hidden, it is expanded (except on the catalog page). +- 4chan's horizontal rules are no longer hidden. If you want to hide them as before, add the old code to your custom CSS: +``` +body > hr, +#blotter hr, +.desktop > hr, +#delform > hr, +#content > hr { + display: none; +} +:root.index .board > hr:last-of-type, +:root.thread .board > hr { + border: 0px; + margin: 0px; +} +``` + +### v1.7.28 +*2014-05-03* + +**ccd0**: +- Copy Mayhem's fix for 4chan post form changes. +>>>>>>> v3 **zixaphir** - Fixed (maybe?) a vulnerability in the post parser that allowed playful users to inject scripts or elements into posts, which could be used maliciously. diff --git a/LICENSE b/LICENSE index 63a41c12f..529a0e1e0 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ /* -* appchan x - Version 2.9.26 - 2014-05-11 +* appchan x - Version 2.9.26 - 2014-05-27 * * Licensed under the MIT license. * https://github.com/zixaphir/appchan-x/blob/master/LICENSE diff --git a/builds/4chan-X.meta.js b/builds/4chan-X.meta.js index 37163a9bf..972d23bba 100755 --- a/builds/4chan-X.meta.js +++ b/builds/4chan-X.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.7.27 +// @version 1.7.33 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X diff --git a/builds/appchan-x.user.js b/builds/appchan-x.user.js index bd3100c6a..257dc8f20 100644 --- a/builds/appchan-x.user.js +++ b/builds/appchan-x.user.js @@ -25,7 +25,7 @@ // ==/UserScript== /* -* appchan x - Version 2.9.26 - 2014-05-11 +* appchan x - Version 2.9.26 - 2014-05-27 * * Licensed under the MIT license. * https://github.com/zixaphir/appchan-x/blob/master/LICENSE @@ -4770,6 +4770,7 @@ className: 'navLinks', innerHTML: " " }); + this.timeEl = $('time#index-last-refresh', this.navLinks); this.searchInput = $('#index-search', this.navLinks); this.searchTest(true); this.hideLabel = $('#hidden-label', this.navLinks); @@ -4790,7 +4791,8 @@ $.on(this.selectSize, 'change', this.cb.size); Rice.nodes(this.navLinks); this.currentPage = this.getCurrentPage(); - $.on(d, 'scroll', Index.scroll); + $.on(d, 'scroll', this.scroll); + $.on(window, 'focus', this.updateIfNeeded); $.on(this.pagelist, 'click', this.cb.pageNav); returnLink = $.el('a', { id: 'returnIcon', @@ -4933,12 +4935,13 @@ thread = g.threads[this.parentNode.dataset.fullID]; if (e.shiftKey) { PostHiding.toggle(thread.OP); + return e.preventDefault(); } else if (e.altKey) { Index.togglePin(thread); + return e.preventDefault(); } else { - Navigate.navigate.call(this); + return Navigate.navigate.call(this, e); } - return e.preventDefault(); }, onOver: function(e) { var el, nodes; @@ -5035,7 +5038,7 @@ _ref = $$('.navLinks.desktop > a'); for (_i = 0, _len = _ref.length; _i < _len; _i++) { el = _ref[_i]; - if (el.getAttribute('href') === '.././catalog') { + if (/\/catalog$/.test(el.pathname)) { el.href = '.././'; } $.on(el, 'click', function() { @@ -5315,6 +5318,14 @@ Index.hideLabel.hidden = false; return $('#hidden-count', Index.hideLabel).textContent = hiddenCount === 1 ? '1 hidden thread' : "" + hiddenCount + " hidden threads"; }, + updateIfNeeded: function() { + var needed, timeEl; + timeEl = Index.timeEl; + needed = g.VIEW === 'index' && !Index.req && timeEl.dataset.utc && timeEl.dataset.utc < Date.now() - (10 * $.MINUTE); + if (needed) { + return Index.update(); + } + }, update: function(pageNum) { var board, now, onload, sortedThreads, _ref, _ref1; if (!navigator.onLine) { @@ -5412,7 +5423,7 @@ } return; } - timeEl = $('time#index-last-refresh', Index.navLinks); + timeEl = Index.timeEl; timeEl.dataset.utc = Date.parse(req.getResponseHeader('Last-Modified')); RelativeDates.update(timeEl); return Index.scrollToIndex(); @@ -5814,7 +5825,7 @@ o.file = { name: data.filename + data.ext, timestamp: "" + data.tim + data.ext, - url: boardID === 'f' ? "//i.4cdn.org/" + boardID + "/" + data.filename + data.ext : "//i.4cdn.org/" + boardID + "/" + data.tim + data.ext, + url: boardID === 'f' ? "//i.4cdn.org/" + boardID + "/" + (encodeURIComponent(data.filename)) + data.ext : "//i.4cdn.org/" + boardID + "/" + data.tim + data.ext, height: data.h, width: data.w, MD5: data.md5, @@ -5886,7 +5897,7 @@ file.twidth = file.theight = 100; } } - imgSrc = boardID === 'f' ? '' : ("") + ("" + fileSize + "") + ""; + imgSrc = boardID === 'f' ? '' : ("") + ("" + fileSize + "") + ""; a = $.el('a', { innerHTML: file.name }); @@ -5896,7 +5907,7 @@ a.textContent = filename; filename = a.innerHTML.replace(/'/g, '''); fileDims = file.name.slice(-3) === 'pdf' ? 'PDF' : "" + file.width + "x" + file.height; - fileInfo = ("
File: ") + ("" + (file.isSpoiler ? 'Spoiler Image' : shortFilename) + "") + (" (" + fileSize + ", " + fileDims + ")
"); + fileInfo = ("
File: ") + ("" + (file.isSpoiler ? 'Spoiler Image' : shortFilename) + "") + (" (" + fileSize + ", " + fileDims + ")
"); fileHTML = "
" + fileInfo + imgSrc + "
"; } else { fileHTML = ''; @@ -5975,7 +5986,7 @@ postCount = data.replies + 1; fileCount = data.images + !!data.ext; pageCount = Math.floor(Index.liveThreadData.keys.indexOf("" + thread.ID) / Index.threadsNumPerPage) + 1; - subject = thread.OP.info.subject ? "
" + thread.OP.info.subject + "
" : ''; + subject = thread.OP.info.subject ? "
" + thread.OP.nodes.subject.innerHTML + "
" : ''; comment = thread.OP.nodes.comment.innerHTML.replace(/(
\s*){2,}/g, '
'); root = $.el('div', { className: 'catalog-thread', @@ -8093,7 +8104,7 @@ ExpandComment.callbacks.push(this.node); } if (Conf['Embedding'] || Conf['Link Title']) { - this.embedProcess = Function('link', "var data = this.services(link); if (data) { " + ((Conf['Embedding'] ? 'this.embed(data);\n' : '') + (Conf['Link Title'] ? 'this.title(data);' : '')) + " }"); + this.embedProcess = Function('link', "var data = this.services(link);\nif (data) {" + ((Conf['Embedding'] ? 'this.embed(data); ' : '') + (Conf['Link Title'] ? 'data.push(post); this.title(data);' : '')) + "}"); } return Post.callbacks.push({ name: 'Linkify', @@ -8235,8 +8246,8 @@ } }, 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]; + var embed, href, key, link, name, options, post, uid, value, _ref; + key = data[0], uid = data[1], options = data[2], link = data[3], post = data[4]; href = link.href; embed = $.el('a', { className: 'embedder', @@ -8253,29 +8264,22 @@ value = _ref[name]; embed.dataset[name] = value; } - embed.dataset.nodedata = link.innerHTML; $.addClass(link, "" + embed.dataset.key); $.on(embed, 'click', Linkify.cb.toggle); $.after(link, [$.tn(' '), embed]); if (Conf['Auto-embed']) { - Linkify.cb.toggle.call(embed); + return Linkify.cb.toggle.call(embed); } - return data.push(embed); }, 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]; + var err, key, link, options, post, service, title, titles, uid; + key = data[0], uid = data[1], options = data[2], link = data[3], post = data[4]; if (!(service = Linkify.types[key].title)) { return; } titles = Conf['CachedTitles']; if (title = titles[uid]) { - if (link) { - link.textContent = title[0]; - } - if (Conf['Embedding']) { - return embed.dataset.title = title[0]; - } + return link.textContent = title[0]; } else { try { return $.cache(service.api(uid), (function() { @@ -8285,17 +8289,22 @@ }); } catch (_error) { err = _error; - if (link) { - link.innerHTML = "[" + key + "] Title Link Blocked (are you using NoScript?)"; - } + link.innerHTML = 'Title Link Blocked (are you using NoScript?)'; + $.prepend(link, $.tn("[" + key + "] ")); } } }, 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)); + if ($.hasClass(this, "embedded")) { + $.rm(this.previousElementSibling); + this.previousElementSibling.hidden = false; + this.textContent = '(embed)'; + } else { + this.previousElementSibling.hidden = true; + $.before(this, Linkify.cb.embed(this)); + this.textContent = '(unembed)'; + } return $.toggleClass(this, 'embedded'); }, embed: function(a) { @@ -8304,21 +8313,9 @@ el.style.cssText = type.style != null ? type.style : "border: 0; width: 640px; height: 390px"; return el; }, - unembed: function(a) { - var el; - el = $.el('a', { - rel: 'nofollow noreferrer', - target: 'blank', - className: 'linkify', - href: a.dataset.href, - innerHTML: a.dataset.title || a.dataset.nodedata - }); - $.addClass(el, a.dataset.key); - return el; - }, title: function(req, data) { - var embed, key, link, options, service, status, text, uid; - key = data[0], uid = data[1], options = data[2], link = data[3], embed = data[4]; + var key, link, link2, options, post, post2, service, status, text, uid, _i, _j, _len, _len1, _ref, _ref1; + key = data[0], uid = data[1], options = data[2], link = data[3], post = data[4]; status = req.status; service = Linkify.types[key].title; text = "[" + key + "] " + ((function() { @@ -8334,11 +8331,17 @@ return "" + status + "'d"; } })()); - if (Conf['Embedding'] && (status === 200 || status === 304)) { - embed.dataset.title = text; - } - if (link) { - return link.textContent = text; + link.textContent = text; + _ref = post.clones; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + post2 = _ref[_i]; + _ref1 = $$('a', post2.nodes.comment); + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + link2 = _ref1[_j]; + if (link2.href === link.href) { + link2.textContent = text; + } + } } } }, @@ -8382,9 +8385,11 @@ regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/, style: 'border: 0; width: auto; height: auto;', el: function(a) { - return $.el('div', { - innerHTML: "" - }); + var el; + el = $.el('div'); + el.innerHTML = ''; + el.firstChild.href = el.firstChild.firstChild.src = a.dataset.href; + return el; } }, { key: 'InstallGentoo', @@ -8418,19 +8423,19 @@ } }, { key: 'MediaCrush', - regExp: /.*(?:mediacru.sh\/)([0-9a-z_]+)/i, + regExp: /.*(?:mediacru.sh\/)([0-9a-z_-]+)/i, style: 'border: 0;', el: function(a) { var el; el = $.el('div'); $.cache("https://mediacru.sh/" + a.dataset.uid + ".json", function() { - var embed, file, files, status, type, _i, _j, _len, _len1, _ref; + var embed, ext, file, files, i, status, type, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _results, _results1; status = this.status; if (status !== 200 && status !== 304) { - return div.innerHTML = "ERROR " + status; + return el.textContent = "ERROR " + status; } files = this.response.files; - _ref = ['video/mp4', 'video/ogv', 'image/svg+xml', 'image/png', 'image/gif', 'image/jpeg', 'image/svg', 'audio/mpeg']; + _ref = ['video/mp4', 'video/webm', 'video/ogv', 'image/svg+xml', 'image/png', 'image/gif', 'image/jpeg', 'audio/mpeg', 'audio/ogg']; for (_i = 0, _len = _ref.length; _i < _len; _i++) { type = _ref[_i]; for (_j = 0, _len1 = files.length; _j < _len1; _j++) { @@ -8445,26 +8450,42 @@ } } if (!embed) { - return div.innerHTML = "ERROR: Not a valid filetype"; + return div.textContent = "ERROR: Not a valid filetype"; + } + switch (embed.type) { + case 'video/mp4': + case 'video/webm': + case 'video/ogv': + el.innerHTML = ''; + _ref1 = ['mp4', 'webm', 'ogv']; + _results = []; + for (i = _k = 0, _len2 = _ref1.length; _k < _len2; i = ++_k) { + ext = _ref1[i]; + _results.push(el.firstChild.children[i].src = "https://mediacru.sh/" + a.dataset.uid + "." + ext); + } + return _results; + break; + case 'image/svg+xml': + case 'image/png': + case 'image/gif': + case 'image/jpeg': + el.innerHTML = ''; + el.firstChild.href = a.dataset.href; + return el.firstChild.firstChild.src = "https://mediacru.sh/" + file.file; + case 'audio/mpeg': + case 'audio/ogg': + el.innerHTML = ''; + _ref2 = ['ogg', 'mp3']; + _results1 = []; + for (i = _l = 0, _len3 = _ref2.length; _l < _len3; i = ++_l) { + ext = _ref2[i]; + _results1.push(el.firstChild.children[i].src = "https://mediacru.sh/" + a.dataset.uid + "." + ext); + } + return _results1; + break; + default: + return el.textContent = "ERROR: No valid filetype."; } - return el.innerHTML = (function() { - switch (embed.type) { - case 'video/mp4': - case 'video/ogv': - return ""; - case 'image/png': - case 'image/gif': - case 'image/jpeg': - return ""; - case 'image/svg': - case 'image/svg+xml': - return ""; - case 'audio/mpeg': - return ""; - default: - return "ERROR: No valid filetype."; - } - })(); }); return el; } @@ -8489,23 +8510,15 @@ }, { key: 'SoundCloud', regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/, - style: 'height: auto; width: 500px; display: inline-block;', + style: 'border: 0; width: 500px; height: 400px;', el: function(a) { - var div; - div = $.el('div', { - className: "soundcloud", - name: "soundcloud" + return $.el('iframe', { + src: "//w.soundcloud.com/player/?visual=true&show_comments=false&url=https%3A%2F%2Fsoundcloud.com%2F" + (encodeURIComponent(a.dataset.uid)) }); - $.ajax("//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + a.dataset.uid, { - onloadend: function() { - return div.innerHTML = JSON.parse(this.responseText).html; - } - }, false); - return div; }, title: { api: function(uid) { - return "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + uid; + return "//soundcloud.com/oembed?format=json&url=https%3A%2F%2Fsoundcloud.com%2F" + (encodeURIComponent(uid)); }, text: function(_) { return _.title; @@ -8525,19 +8538,27 @@ regExp: /.*(?:twitch.tv\/)([^#\&\?]*).*/, 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', { - data: 'http://www.twitch.tv/widgets/archive_embed_player.swf', - innerHTML: "\n" + var channel, id, idparam, obj, result, type, _; + if (result = /(\w+)\/([bc])\/(\d+)/i.exec(a.dataset.uid)) { + _ = result[0], channel = result[1], type = result[2], id = result[3]; + idparam = { + 'b': 'archive_id', + 'c': 'chapter_id' + }; + obj = $.el('object', { + data: 'http://www.twitch.tv/widgets/archive_embed_player.swf' }); + obj.innerHTML = ''; + obj.children[1].value = "channel=" + channel + "&start_volume=25&auto_play=false&" + idparam[type] + "=" + id; + return obj; } else { channel = (/(\w+)/.exec(a.dataset.uid))[0]; - return $.el('object', { - data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=" + channel, - innerHTML: "\n\n" + obj = $.el('object', { + data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=" + channel }); + obj.innerHTML = ''; + obj.children[1].value = "hostname=www.twitch.tv&channel=" + channel + "&auto_play=true&start_volume=25"; + return obj; } } }, { @@ -9043,7 +9064,7 @@ if (/^text\//.test(file.type)) { if (isSingle) { post = QR.selected; - } else if (index !== 0 || (post = QR.posts[QR.posts.length - 1]).com) { + } else if ((post = QR.posts[QR.posts.length - 1]).com) { post = new QR.post(); } post.pasteText(file); @@ -9051,9 +9072,7 @@ } if (_ref = file.type, __indexOf.call(QR.mimeTypes, _ref) < 0) { QR.error("" + file.name + ": Unsupported file type."); - if (!isSingle) { - return; - } + return; } max = QR.nodes.fileInput.max; if (/^video\//.test(file.type)) { @@ -9061,20 +9080,14 @@ } if (file.size > max) { QR.error("" + file.name + ": File too large (file: " + ($.bytesToString(file.size)) + ", max: " + ($.bytesToString(max)) + ")."); - if (!isSingle) { - return; - } + return; } if (isSingle) { post = QR.selected; - } else if (index !== 0 || (post = QR.posts[QR.posts.length - 1]).file) { + } else if ((post = QR.posts[QR.posts.length - 1]).file) { post = new QR.post(); } - if (/^text/.test(file.type)) { - return post.pasteText(file); - } else { - return post.setFile(file); - } + return post.setFile(file); }, openFileInput: function(e) { var _ref; @@ -9144,7 +9157,6 @@ setNode('addPost', '#add-post'); setNode('charCount', '#char-count'); setNode('fileSubmit', '#file-n-submit'); - setNode('filesize', '#qr-filesize'); setNode('filename', '#qr-filename'); setNode('fileContainer', '#qr-filename-container'); setNode('fileRM', '#qr-filerm'); @@ -10227,7 +10239,11 @@ QR.error(error); } _this.URL = fileURL; - return _this.rmFile(); + if ((QR.posts.length === 1) || (_this.com && _this.com.length)) { + return _this.rmFile(); + } else { + return _this.rm(); + } } s = 90 * 2 * window.devicePixelRatio; if (_this.file.type === 'image/gif') { @@ -13198,7 +13214,7 @@ Redirect = { init: function() { - var archive, archives, boardID, boards, data, files, id, name, o, record, software, type, _i, _j, _len, _len1, _ref, _ref1; + var archive, archives, boardID, boards, data, files, id, name, o, record, software, type, withCredentials, _i, _j, _len, _len1, _ref, _ref1; o = { thread: {}, post: {}, @@ -13208,10 +13224,13 @@ _ref = Redirect.archives; for (_i = 0, _len = _ref.length; _i < _len; _i++) { data = _ref[_i]; - name = data.name, boards = data.boards, files = data.files, software = data.software; + name = data.name, boards = data.boards, files = data.files, software = data.software, withCredentials = data.withCredentials; archives[name] = data; for (_j = 0, _len1 = boards.length; _j < _len1; _j++) { boardID = boards[_j]; + if (!(!withCredentials)) { + continue; + } if (!(boardID in o.thread)) { o.thread[boardID] = data; } @@ -13240,7 +13259,7 @@ } return Redirect.data = o; }, - archives: [{"uid":0,"name":"Foolz","domain":"archive.foolz.us","http":true,"https":true,"software":"foolfuuka","boards":["a","biz","co","diy","gd","jp","m","sci","sp","tg","tv","vg","vp","vr","wsg"],"files":["a","biz","gd","diy","jp","m","sci","tg","vg","vp","vr","wsg"]},{"uid":1,"name":"NSFW Foolz","domain":"nsfw.foolz.us","http":true,"https":true,"software":"foolfuuka","boards":["u"],"files":["u"]},{"uid":2,"name":"The Dark Cave","domain":"archive.thedarkcave.org","http":true,"https":true,"software":"foolfuuka","boards":["c","int","out","po"],"files":["c","po"]},{"uid":3,"name":"4plebs Archive","domain":"archive.4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["adv","hr","o","pol","s4s","tg","trv","tv","x"],"files":["adv","hr","o","pol","s4s","tg","trv","tv","x"]},{"uid":18,"name":"4plebs Flash Archive","domain":"flash.4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["f"],"files":["f"]},{"uid":4,"name":"Nyafuu","domain":"archive.nyafuu.org","http":true,"https":true,"software":"foolfuuka","boards":["c","e","w","wg"],"files":["c","e","w","wg"]},{"uid":5,"name":"Love is Over","domain":"archive.loveisover.me","http":true,"https":true,"software":"foolfuuka","boards":["d","i","lgbt"],"files":["d","i","lgbt"]},{"uid":8,"name":"Rebecca Black Tech","domain":"rbt.asia","http":true,"https":true,"software":"fuuka","boards":["cgl","g","mu","w"],"files":["cgl","g","mu","w"]},{"uid":9,"name":"Heinessen","domain":"archive.heinessen.com","http":true,"https":false,"software":"fuuka","boards":["an","fit","k","mlp","r9k","toy"],"files":["an","fit","k","r9k","toy"]},{"uid":10,"name":"warosu","domain":"fuuka.warosu.org","http":false,"https":true,"software":"fuuka","boards":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"],"files":["3","biz","cgl","ck","diy","fa","ic","jp","lit","sci","tg","vr"]},{"uid":15,"name":"fgts","domain":"fgts.eu","http":true,"https":true,"software":"foolfuuka","boards":["asp","cm","h","hc","hm","n","p","r","s","soc","y"],"files":["asp","cm","h","hc","hm","n","p","r","s","soc","y"]},{"uid":16,"name":"maware","domain":"archive.mawa.re","http":true,"https":false,"software":"foolfuuka","boards":["t"],"files":["t"]},{"uid":17,"name":"installgentoo.com","domain":"chan.installgentoo.com","http":true,"https":false,"software":"foolfuuka","boards":["g","t"],"files":["g","t"]},{"uid":13,"name":"Foolz Beta","domain":"beta.foolz.us","http":true,"https":true,"withCredentials":true,"software":"foolfuuka","boards":["a","biz","co","d","diy","gd","jp","m","s4s","sci","sp","tg","tv","u","vg","vp","vr","wsg"],"files":["a","biz","d","diy","gd","jp","m","s4s","sci","tg","u","vg","vp","vr","wsg"]}], + archives: [{"uid":0,"name":"Foolz","domain":"archive.foolz.us","http":true,"https":true,"software":"foolfuuka","boards":["a","biz","co","diy","gd","jp","m","sci","sp","tg","tv","vg","vp","vr","wsg"],"files":["a","biz","diy","gd","jp","m","sci","tg","vg","vp","vr","wsg"]},{"uid":1,"name":"NSFW Foolz","domain":"nsfw.foolz.us","http":true,"https":true,"software":"foolfuuka","boards":["u"],"files":["u"]},{"uid":2,"name":"The Dark Cave","domain":"archive.thedarkcave.org","http":true,"https":true,"software":"foolfuuka","boards":["c","int","out","po"],"files":["c","po"]},{"uid":3,"name":"4plebs Archive","domain":"archive.4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["adv","hr","o","pol","s4s","tg","trv","tv","x"],"files":["adv","hr","o","pol","s4s","tg","trv","tv","x"]},{"uid":18,"name":"4plebs Flash Archive","domain":"flash.4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["f"],"files":["f"]},{"uid":4,"name":"Nyafuu","domain":"archive.nyafuu.org","http":true,"https":true,"software":"foolfuuka","boards":["c","e","w","wg"],"files":["c","e","w","wg"]},{"uid":5,"name":"Love is Over","domain":"archive.loveisover.me","http":true,"https":true,"software":"foolfuuka","boards":["d","i","lgbt"],"files":["d","i","lgbt"]},{"uid":8,"name":"Rebecca Black Tech","domain":"rbt.asia","http":false,"https":true,"software":"fuuka","boards":["cgl","g","mu","w"],"files":["cgl","g","mu","w"]},{"uid":9,"name":"Heinessen","domain":"archive.heinessen.com","http":true,"https":false,"software":"fuuka","boards":["an","fit","k","mlp","r9k","toy"],"files":["an","fit","k","mlp","r9k","toy"]},{"uid":10,"name":"warosu","domain":"fuuka.warosu.org","http":false,"https":true,"software":"fuuka","boards":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"],"files":["3","biz","cgl","ck","diy","fa","ic","jp","lit","sci","tg","vr"]},{"uid":15,"name":"fgts","domain":"fgts.eu","http":true,"https":true,"software":"foolfuuka","boards":["asp","cm","h","hc","hm","n","p","r","s","soc","y"],"files":["asp","cm","h","hc","hm","n","p","r","s","soc","y"]},{"uid":16,"name":"maware","domain":"archive.mawa.re","http":true,"https":false,"software":"foolfuuka","boards":["t"],"files":["t"]},{"uid":17,"name":"installgentoo.com","domain":"chan.installgentoo.com","http":true,"https":false,"software":"foolfuuka","boards":["g","t"],"files":["g","t"]},{"uid":19,"name":"Innovandalism Archive","domain":"boards.innovandalism.eu","http":true,"https":false,"software":"foolfuuka","boards":["v"],"files":[]},{"uid":13,"name":"Foolz Beta","domain":"beta.foolz.us","http":true,"https":true,"withCredentials":true,"software":"foolfuuka","boards":["a","biz","co","d","diy","gd","jp","m","s4s","sci","sp","tg","tv","u","vg","vp","vr","wsg"],"files":["a","biz","d","diy","gd","jp","m","s4s","sci","tg","u","vg","vp","vr","wsg"]},{"uid":19,"name":"Innovandalism Archive","domain":"boards.innovandalism.eu","http":true,"https":false,"software":"foolfuuka","boards":["v"],"files":[]}], to: function(dest, data) { var archive; archive = (dest === 'search' || dest === 'board' ? Redirect.data.thread : Redirect.data[dest])[data.boardID]; @@ -13305,7 +13324,7 @@ "https": true, "software": "foolfuuka", "boards": ["a", "biz", "co", "diy", "gd", "jp", "m", "sci", "sp", "tg", "tv", "vg", "vp", "vr", "wsg"], - "files": ["a", "biz", "gd", "diy", "jp", "m", "sci", "tg", "vg", "vp", "vr", "wsg"] + "files": ["a", "biz", "diy", "gd", "jp", "m", "sci", "tg", "vg", "vp", "vr", "wsg"] }, { "uid": 1, "name": "NSFW Foolz", @@ -13364,7 +13383,7 @@ "uid": 8, "name": "Rebecca Black Tech", "domain": "rbt.asia", - "http": true, + "http": false, "https": true, "software": "fuuka", "boards": ["cgl", "g", "mu", "w"], @@ -13377,7 +13396,7 @@ "https": false, "software": "fuuka", "boards": ["an", "fit", "k", "mlp", "r9k", "toy"], - "files": ["an", "fit", "k", "r9k", "toy"] + "files": ["an", "fit", "k", "mlp", "r9k", "toy"] }, { "uid": 10, "name": "warosu", @@ -13414,6 +13433,15 @@ "software": "foolfuuka", "boards": ["g", "t"], "files": ["g", "t"] + }, { + "uid": 19, + "name": "Innovandalism Archive", + "domain": "boards.innovandalism.eu", + "http": true, + "https": false, + "software": "foolfuuka", + "boards": ["v"], + "files": [] }, { "uid": 13, "name": "Foolz Beta", @@ -13424,6 +13452,15 @@ "software": "foolfuuka", "boards": ["a", "biz", "co", "d", "diy", "gd", "jp", "m", "s4s", "sci", "sp", "tg", "tv", "u", "vg", "vp", "vr", "wsg"], "files": ["a", "biz", "d", "diy", "gd", "jp", "m", "s4s", "sci", "tg", "u", "vg", "vp", "vr", "wsg"] + }, { + "uid": 19, + "name": "Innovandalism Archive", + "domain": "boards.innovandalism.eu", + "http": true, + "https": false, + "software": "foolfuuka", + "boards": ["v"], + "files": [] } ]; @@ -15112,65 +15149,10 @@ return CatalogLinks.el.title = "Turn catalog links " + (useCatalog ? 'off' : 'on') + "."; }, external: function(board) { - switch (board) { - case 'a': - case 'c': - case 'g': - case 'co': - case 'k': - case 'm': - case 'o': - case 'p': - case 'v': - case 'vg': - case 'w': - case 'cm': - case '3': - case 'adv': - case 'an': - case 'cgl': - case 'ck': - case 'diy': - case 'fa': - case 'fit': - case 'int': - case 'jp': - case 'mlp': - case 'lit': - case 'mu': - case 'n': - case 'po': - case 'sci': - case 'toy': - case 'trv': - case 'tv': - case 'vp': - case 'x': - case 'q': - return "http://catalog.neet.tv/" + board; - case 'd': - case 'e': - case 'gif': - case 'h': - case 'hr': - case 'hc': - case 'r9k': - case 's': - case 'pol': - case 'soc': - case 'u': - case 'i': - case 'ic': - case 'hm': - case 'r': - case 'w': - case 'wg': - case 'wsg': - case 't': - case 'y': - return "http://4index.gropes.us/" + board; - default: - return "/" + board + "/catalog"; + if (board === 'a' || board === 'c' || board === 'g' || board === 'co' || board === 'k' || board === 'm' || board === 'o' || board === 'p' || board === 'v' || board === 'vg' || board === 'w' || board === 'cm' || board === '3' || board === 'adv' || board === 'an' || board === 'cgl' || board === 'ck' || board === 'diy' || board === 'fa' || board === 'fit' || board === 'int' || board === 'jp' || board === 'mlp' || board === 'lit' || board === 'mu' || board === 'n' || board === 'po' || board === 'sci' || board === 'toy' || board === 'trv' || board === 'tv' || board === 'vp' || board === 'x' || board === 'q') { + return "http://catalog.neet.tv/" + board; + } else { + return "/" + board + "/catalog"; } } }; @@ -15897,6 +15879,9 @@ return; } target = e.target; + if (target.nodeName === 'EMBED') { + return; + } if ((_ref = target.nodeName) === 'INPUT' || _ref === 'TEXTAREA') { if (!/(Esc|Alt|Ctrl|Meta|Shift\+\w{2,})/.test(key)) { return; @@ -16852,7 +16837,7 @@ } if (e) { if (e.shiftKey || e.ctrlKey || (e.type === 'click' && e.button !== 0)) { - if ((e != null ? e.button : void 0) !== 2) { + if (e.button !== 2) { Navigate.setMode(this); } return; @@ -17341,7 +17326,7 @@ return $.on(ta, 'change', $.cb.value); }, advanced: function(section) { - var archBoards, boardID, boardOptions, boardSelect, boards, event, files, input, inputs, item, items, name, o, row, rows, software, ta, table, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2, _ref3, _ref4; + var archBoards, boardID, boardOptions, boardSelect, boards, event, files, i, input, inputs, item, items, name, o, row, rows, software, ta, table, withCredentials, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _len5, _m, _n, _ref, _ref1, _ref2, _ref3, _ref4, _ref5; 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 Twitter link (@).
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\"
External link: external-text:\"Google\",\"http://www.google.com\"
Index mode: g-mode:\"type\" where type is paged, all threads or catalog
Index sort: g-sort:\"type\" where type is bump order, last reply, creation date, reply count or file countCombinations are possible: g-text:\"VIP Catalog\"-mode:\"catalog\"-sort:\"creation date\"
Full board list toggle: toggle-all

[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h-mode:\"catalog\"-sort:\"file count\"] [t-text:\"Piracy\"]
will give you
[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
if you are on /g/.
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

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

Unread Favicon is disabled.
Emoji is disabled.
Sage Icon:
Thread Updater is disabled.
Interval:
Custom CSS
"; items = {}; inputs = {}; @@ -17379,28 +17364,40 @@ archBoards = {}; _ref1 = Redirect.archives; for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - _ref2 = _ref1[_j], name = _ref2.name, boards = _ref2.boards, files = _ref2.files, software = _ref2.software; + _ref2 = _ref1[_j], name = _ref2.name, boards = _ref2.boards, files = _ref2.files, software = _ref2.software, withCredentials = _ref2.withCredentials; for (_k = 0, _len2 = boards.length; _k < _len2; _k++) { boardID = boards[_k]; o = archBoards[boardID] || (archBoards[boardID] = { - thread: [], - post: [], - file: [] + thread: [[], []], + post: [[], []], + file: [[], []] }); - o.thread.push(name); + i = +(!!withCredentials); + o.thread[i].push(name); if (software === 'foolfuuka') { - o.post.push(name); + o.post[i].push(name); } if (__indexOf.call(files, boardID) >= 0) { - o.file.push(name); + o.file[i].push(name); } } } + for (boardID in archBoards) { + o = archBoards[boardID]; + _ref3 = ['thread', 'post', 'file']; + for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) { + item = _ref3[_l]; + if (o[item][0].length === 0 && o[item][1].length !== 0) { + o[item][0].push('disabled'); + } + o[item] = o[item][0].concat(o[item][1]); + } + } rows = []; boardOptions = []; - _ref3 = Object.keys(archBoards).sort(); - for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) { - boardID = _ref3[_l]; + _ref4 = Object.keys(archBoards).sort(); + for (_m = 0, _len4 = _ref4.length; _m < _len4; _m++) { + boardID = _ref4[_m]; row = $.el('tr', { className: "board-" + boardID }); @@ -17411,9 +17408,9 @@ selected: boardID === g.BOARD.ID })); o = archBoards[boardID]; - _ref4 = ['thread', 'post', 'file']; - for (_m = 0, _len4 = _ref4.length; _m < _len4; _m++) { - item = _ref4[_m]; + _ref5 = ['thread', 'post', 'file']; + for (_n = 0, _len5 = _ref5.length; _n < _len5; _n++) { + item = _ref5[_n]; $.add(row, Settings.addArchiveCell(boardID, o, item)); } rows.push(row); @@ -18179,7 +18176,7 @@ }); }, initFeatures: function() { - var href, init, video, _ref; + var href, init, _ref; Favicon.el.type = 'image/x-icon'; href = Favicon.el.href; Favicon.SFW = /ws\.ico$/.test(href); @@ -18208,20 +18205,8 @@ Report.init(); return; case 'i.4cdn.org': - if (Conf['Loop in New Tab'] && (video = $('video'))) { - Video.configure(video); - $.on(video, 'click', function() { - if (!video.controls) { - if (video.paused) { - return video.play(); - } else { - return video.pause(); - } - } - }); - } $.ready(function() { - var URL, pathname, _ref1; + var URL, pathname, video, _ref1; if (Conf['404 Redirect'] && ((_ref1 = d.title) === '4chan - Temporarily Offline' || _ref1 === '4chan - 404 Not Found')) { Redirect.init(); pathname = location.pathname.split('/'); @@ -18232,6 +18217,17 @@ if (URL) { return location.replace(URL); } + } else if (Conf['Loop in New Tab'] && (video = $('video'))) { + Video.configure(video); + if (!video.controls) { + return $.on(video, 'click', function() { + if (video.paused) { + return video.play(); + } else { + return video.pause(); + } + }); + } } }); return; diff --git a/builds/crx/script.js b/builds/crx/script.js index 72855929e..e1b3a450f 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript /* -* appchan x - Version 2.9.26 - 2014-05-11 +* appchan x - Version 2.9.26 - 2014-05-27 * * Licensed under the MIT license. * https://github.com/zixaphir/appchan-x/blob/master/LICENSE @@ -4828,6 +4828,7 @@ className: 'navLinks', innerHTML: " " }); + this.timeEl = $('time#index-last-refresh', this.navLinks); this.searchInput = $('#index-search', this.navLinks); this.searchTest(true); this.hideLabel = $('#hidden-label', this.navLinks); @@ -4848,7 +4849,8 @@ $.on(this.selectSize, 'change', this.cb.size); Rice.nodes(this.navLinks); this.currentPage = this.getCurrentPage(); - $.on(d, 'scroll', Index.scroll); + $.on(d, 'scroll', this.scroll); + $.on(window, 'focus', this.updateIfNeeded); $.on(this.pagelist, 'click', this.cb.pageNav); returnLink = $.el('a', { id: 'returnIcon', @@ -4991,12 +4993,13 @@ thread = g.threads[this.parentNode.dataset.fullID]; if (e.shiftKey) { PostHiding.toggle(thread.OP); + return e.preventDefault(); } else if (e.altKey) { Index.togglePin(thread); + return e.preventDefault(); } else { - Navigate.navigate.call(this); + return Navigate.navigate.call(this, e); } - return e.preventDefault(); }, onOver: function(e) { var el, nodes; @@ -5093,7 +5096,7 @@ _ref = $$('.navLinks.desktop > a'); for (_i = 0, _len = _ref.length; _i < _len; _i++) { el = _ref[_i]; - if (el.getAttribute('href') === '.././catalog') { + if (/\/catalog$/.test(el.pathname)) { el.href = '.././'; } $.on(el, 'click', function() { @@ -5373,6 +5376,14 @@ Index.hideLabel.hidden = false; return $('#hidden-count', Index.hideLabel).textContent = hiddenCount === 1 ? '1 hidden thread' : "" + hiddenCount + " hidden threads"; }, + updateIfNeeded: function() { + var needed, timeEl; + timeEl = Index.timeEl; + needed = g.VIEW === 'index' && !Index.req && timeEl.dataset.utc && timeEl.dataset.utc < Date.now() - (10 * $.MINUTE); + if (needed) { + return Index.update(); + } + }, update: function(pageNum) { var board, now, onload, sortedThreads, _ref, _ref1; if (!navigator.onLine) { @@ -5470,7 +5481,7 @@ } return; } - timeEl = $('time#index-last-refresh', Index.navLinks); + timeEl = Index.timeEl; timeEl.dataset.utc = Date.parse(req.getResponseHeader('Last-Modified')); RelativeDates.update(timeEl); return Index.scrollToIndex(); @@ -5872,7 +5883,7 @@ o.file = { name: data.filename + data.ext, timestamp: "" + data.tim + data.ext, - url: boardID === 'f' ? "//i.4cdn.org/" + boardID + "/" + data.filename + data.ext : "//i.4cdn.org/" + boardID + "/" + data.tim + data.ext, + url: boardID === 'f' ? "//i.4cdn.org/" + boardID + "/" + (encodeURIComponent(data.filename)) + data.ext : "//i.4cdn.org/" + boardID + "/" + data.tim + data.ext, height: data.h, width: data.w, MD5: data.md5, @@ -5944,7 +5955,7 @@ file.twidth = file.theight = 100; } } - imgSrc = boardID === 'f' ? '' : ("") + ("" + fileSize + "") + ""; + imgSrc = boardID === 'f' ? '' : ("") + ("" + fileSize + "") + ""; a = $.el('a', { innerHTML: file.name }); @@ -5954,7 +5965,7 @@ a.textContent = filename; filename = a.innerHTML.replace(/'/g, '''); fileDims = file.name.slice(-3) === 'pdf' ? 'PDF' : "" + file.width + "x" + file.height; - fileInfo = ("
File: ") + ("" + (file.isSpoiler ? 'Spoiler Image' : shortFilename) + "") + (" (" + fileSize + ", " + fileDims + ")
"); + fileInfo = ("
File: ") + ("" + (file.isSpoiler ? 'Spoiler Image' : shortFilename) + "") + (" (" + fileSize + ", " + fileDims + ")
"); fileHTML = "
" + fileInfo + imgSrc + "
"; } else { fileHTML = ''; @@ -6033,7 +6044,7 @@ postCount = data.replies + 1; fileCount = data.images + !!data.ext; pageCount = Math.floor(Index.liveThreadData.keys.indexOf("" + thread.ID) / Index.threadsNumPerPage) + 1; - subject = thread.OP.info.subject ? "
" + thread.OP.info.subject + "
" : ''; + subject = thread.OP.info.subject ? "
" + thread.OP.nodes.subject.innerHTML + "
" : ''; comment = thread.OP.nodes.comment.innerHTML.replace(/(
\s*){2,}/g, '
'); root = $.el('div', { className: 'catalog-thread', @@ -8144,7 +8155,7 @@ ExpandComment.callbacks.push(this.node); } if (Conf['Embedding'] || Conf['Link Title']) { - this.embedProcess = Function('link', "var data = this.services(link); if (data) { " + ((Conf['Embedding'] ? 'this.embed(data);\n' : '') + (Conf['Link Title'] ? 'this.title(data);' : '')) + " }"); + this.embedProcess = Function('link', "var data = this.services(link);\nif (data) {" + ((Conf['Embedding'] ? 'this.embed(data); ' : '') + (Conf['Link Title'] ? 'data.push(post); this.title(data);' : '')) + "}"); } return Post.callbacks.push({ name: 'Linkify', @@ -8286,8 +8297,8 @@ } }, 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]; + var embed, href, key, link, name, options, post, uid, value, _ref; + key = data[0], uid = data[1], options = data[2], link = data[3], post = data[4]; href = link.href; embed = $.el('a', { className: 'embedder', @@ -8304,29 +8315,22 @@ value = _ref[name]; embed.dataset[name] = value; } - embed.dataset.nodedata = link.innerHTML; $.addClass(link, "" + embed.dataset.key); $.on(embed, 'click', Linkify.cb.toggle); $.after(link, [$.tn(' '), embed]); if (Conf['Auto-embed']) { - Linkify.cb.toggle.call(embed); + return Linkify.cb.toggle.call(embed); } - return data.push(embed); }, 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]; + var err, key, link, options, post, service, title, titles, uid; + key = data[0], uid = data[1], options = data[2], link = data[3], post = data[4]; if (!(service = Linkify.types[key].title)) { return; } titles = Conf['CachedTitles']; if (title = titles[uid]) { - if (link) { - link.textContent = title[0]; - } - if (Conf['Embedding']) { - return embed.dataset.title = title[0]; - } + return link.textContent = title[0]; } else { try { return $.cache(service.api(uid), (function() { @@ -8336,17 +8340,22 @@ }); } catch (_error) { err = _error; - if (link) { - link.innerHTML = "[" + key + "] Title Link Blocked (are you using NoScript?)"; - } + link.innerHTML = 'Title Link Blocked (are you using NoScript?)'; + $.prepend(link, $.tn("[" + key + "] ")); } } }, 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)); + if ($.hasClass(this, "embedded")) { + $.rm(this.previousElementSibling); + this.previousElementSibling.hidden = false; + this.textContent = '(embed)'; + } else { + this.previousElementSibling.hidden = true; + $.before(this, Linkify.cb.embed(this)); + this.textContent = '(unembed)'; + } return $.toggleClass(this, 'embedded'); }, embed: function(a) { @@ -8355,21 +8364,9 @@ el.style.cssText = type.style != null ? type.style : "border: 0; width: 640px; height: 390px"; return el; }, - unembed: function(a) { - var el; - el = $.el('a', { - rel: 'nofollow noreferrer', - target: 'blank', - className: 'linkify', - href: a.dataset.href, - innerHTML: a.dataset.title || a.dataset.nodedata - }); - $.addClass(el, a.dataset.key); - return el; - }, title: function(req, data) { - var embed, key, link, options, service, status, text, uid; - key = data[0], uid = data[1], options = data[2], link = data[3], embed = data[4]; + var key, link, link2, options, post, post2, service, status, text, uid, _i, _j, _len, _len1, _ref, _ref1; + key = data[0], uid = data[1], options = data[2], link = data[3], post = data[4]; status = req.status; service = Linkify.types[key].title; text = "[" + key + "] " + ((function() { @@ -8385,11 +8382,17 @@ return "" + status + "'d"; } })()); - if (Conf['Embedding'] && (status === 200 || status === 304)) { - embed.dataset.title = text; - } - if (link) { - return link.textContent = text; + link.textContent = text; + _ref = post.clones; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + post2 = _ref[_i]; + _ref1 = $$('a', post2.nodes.comment); + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + link2 = _ref1[_j]; + if (link2.href === link.href) { + link2.textContent = text; + } + } } } }, @@ -8433,9 +8436,11 @@ regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/, style: 'border: 0; width: auto; height: auto;', el: function(a) { - return $.el('div', { - innerHTML: "" - }); + var el; + el = $.el('div'); + el.innerHTML = ''; + el.firstChild.href = el.firstChild.firstChild.src = a.dataset.href; + return el; } }, { key: 'InstallGentoo', @@ -8469,19 +8474,19 @@ } }, { key: 'MediaCrush', - regExp: /.*(?:mediacru.sh\/)([0-9a-z_]+)/i, + regExp: /.*(?:mediacru.sh\/)([0-9a-z_-]+)/i, style: 'border: 0;', el: function(a) { var el; el = $.el('div'); $.cache("https://mediacru.sh/" + a.dataset.uid + ".json", function() { - var embed, file, files, status, type, _i, _j, _len, _len1, _ref; + var embed, ext, file, files, i, status, type, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _results, _results1; status = this.status; if (status !== 200 && status !== 304) { - return div.innerHTML = "ERROR " + status; + return el.textContent = "ERROR " + status; } files = this.response.files; - _ref = ['video/mp4', 'video/ogv', 'image/svg+xml', 'image/png', 'image/gif', 'image/jpeg', 'image/svg', 'audio/mpeg']; + _ref = ['video/mp4', 'video/webm', 'video/ogv', 'image/svg+xml', 'image/png', 'image/gif', 'image/jpeg', 'audio/mpeg', 'audio/ogg']; for (_i = 0, _len = _ref.length; _i < _len; _i++) { type = _ref[_i]; for (_j = 0, _len1 = files.length; _j < _len1; _j++) { @@ -8496,26 +8501,42 @@ } } if (!embed) { - return div.innerHTML = "ERROR: Not a valid filetype"; + return div.textContent = "ERROR: Not a valid filetype"; + } + switch (embed.type) { + case 'video/mp4': + case 'video/webm': + case 'video/ogv': + el.innerHTML = ''; + _ref1 = ['mp4', 'webm', 'ogv']; + _results = []; + for (i = _k = 0, _len2 = _ref1.length; _k < _len2; i = ++_k) { + ext = _ref1[i]; + _results.push(el.firstChild.children[i].src = "https://mediacru.sh/" + a.dataset.uid + "." + ext); + } + return _results; + break; + case 'image/svg+xml': + case 'image/png': + case 'image/gif': + case 'image/jpeg': + el.innerHTML = ''; + el.firstChild.href = a.dataset.href; + return el.firstChild.firstChild.src = "https://mediacru.sh/" + file.file; + case 'audio/mpeg': + case 'audio/ogg': + el.innerHTML = ''; + _ref2 = ['ogg', 'mp3']; + _results1 = []; + for (i = _l = 0, _len3 = _ref2.length; _l < _len3; i = ++_l) { + ext = _ref2[i]; + _results1.push(el.firstChild.children[i].src = "https://mediacru.sh/" + a.dataset.uid + "." + ext); + } + return _results1; + break; + default: + return el.textContent = "ERROR: No valid filetype."; } - return el.innerHTML = (function() { - switch (embed.type) { - case 'video/mp4': - case 'video/ogv': - return ""; - case 'image/png': - case 'image/gif': - case 'image/jpeg': - return ""; - case 'image/svg': - case 'image/svg+xml': - return ""; - case 'audio/mpeg': - return ""; - default: - return "ERROR: No valid filetype."; - } - })(); }); return el; } @@ -8540,23 +8561,15 @@ }, { key: 'SoundCloud', regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/, - style: 'height: auto; width: 500px; display: inline-block;', + style: 'border: 0; width: 500px; height: 400px;', el: function(a) { - var div; - div = $.el('div', { - className: "soundcloud", - name: "soundcloud" + return $.el('iframe', { + src: "//w.soundcloud.com/player/?visual=true&show_comments=false&url=https%3A%2F%2Fsoundcloud.com%2F" + (encodeURIComponent(a.dataset.uid)) }); - $.ajax("//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + a.dataset.uid, { - onloadend: function() { - return div.innerHTML = JSON.parse(this.responseText).html; - } - }, false); - return div; }, title: { api: function(uid) { - return "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + uid; + return "//soundcloud.com/oembed?format=json&url=https%3A%2F%2Fsoundcloud.com%2F" + (encodeURIComponent(uid)); }, text: function(_) { return _.title; @@ -8576,19 +8589,27 @@ regExp: /.*(?:twitch.tv\/)([^#\&\?]*).*/, 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', { - data: 'http://www.twitch.tv/widgets/archive_embed_player.swf', - innerHTML: "\n" + var channel, id, idparam, obj, result, type, _; + if (result = /(\w+)\/([bc])\/(\d+)/i.exec(a.dataset.uid)) { + _ = result[0], channel = result[1], type = result[2], id = result[3]; + idparam = { + 'b': 'archive_id', + 'c': 'chapter_id' + }; + obj = $.el('object', { + data: 'http://www.twitch.tv/widgets/archive_embed_player.swf' }); + obj.innerHTML = ''; + obj.children[1].value = "channel=" + channel + "&start_volume=25&auto_play=false&" + idparam[type] + "=" + id; + return obj; } else { channel = (/(\w+)/.exec(a.dataset.uid))[0]; - return $.el('object', { - data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=" + channel, - innerHTML: "\n\n" + obj = $.el('object', { + data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=" + channel }); + obj.innerHTML = ''; + obj.children[1].value = "hostname=www.twitch.tv&channel=" + channel + "&auto_play=true&start_volume=25"; + return obj; } } }, { @@ -9100,7 +9121,7 @@ if (/^text\//.test(file.type)) { if (isSingle) { post = QR.selected; - } else if (index !== 0 || (post = QR.posts[QR.posts.length - 1]).com) { + } else if ((post = QR.posts[QR.posts.length - 1]).com) { post = new QR.post(); } post.pasteText(file); @@ -9108,9 +9129,7 @@ } if (_ref = file.type, __indexOf.call(QR.mimeTypes, _ref) < 0) { QR.error("" + file.name + ": Unsupported file type."); - if (!isSingle) { - return; - } + return; } max = QR.nodes.fileInput.max; if (/^video\//.test(file.type)) { @@ -9118,20 +9137,14 @@ } if (file.size > max) { QR.error("" + file.name + ": File too large (file: " + ($.bytesToString(file.size)) + ", max: " + ($.bytesToString(max)) + ")."); - if (!isSingle) { - return; - } + return; } if (isSingle) { post = QR.selected; - } else if (index !== 0 || (post = QR.posts[QR.posts.length - 1]).file) { + } else if ((post = QR.posts[QR.posts.length - 1]).file) { post = new QR.post(); } - if (/^text/.test(file.type)) { - return post.pasteText(file); - } else { - return post.setFile(file); - } + return post.setFile(file); }, openFileInput: function(e) { var _ref; @@ -9201,7 +9214,6 @@ setNode('addPost', '#add-post'); setNode('charCount', '#char-count'); setNode('fileSubmit', '#file-n-submit'); - setNode('filesize', '#qr-filesize'); setNode('filename', '#qr-filename'); setNode('fileContainer', '#qr-filename-container'); setNode('fileRM', '#qr-filerm'); @@ -10267,7 +10279,11 @@ QR.error(error); } _this.URL = fileURL; - return _this.rmFile(); + if ((QR.posts.length === 1) || (_this.com && _this.com.length)) { + return _this.rmFile(); + } else { + return _this.rm(); + } } s = 90 * 2 * window.devicePixelRatio; if (_this.file.type === 'image/gif') { @@ -13212,7 +13228,7 @@ Redirect = { init: function() { - var archive, archives, boardID, boards, data, files, id, name, o, record, software, type, _i, _j, _len, _len1, _ref, _ref1; + var archive, archives, boardID, boards, data, files, id, name, o, record, software, type, withCredentials, _i, _j, _len, _len1, _ref, _ref1; o = { thread: {}, post: {}, @@ -13222,10 +13238,13 @@ _ref = Redirect.archives; for (_i = 0, _len = _ref.length; _i < _len; _i++) { data = _ref[_i]; - name = data.name, boards = data.boards, files = data.files, software = data.software; + name = data.name, boards = data.boards, files = data.files, software = data.software, withCredentials = data.withCredentials; archives[name] = data; for (_j = 0, _len1 = boards.length; _j < _len1; _j++) { boardID = boards[_j]; + if (!(!withCredentials)) { + continue; + } if (!(boardID in o.thread)) { o.thread[boardID] = data; } @@ -13254,7 +13273,7 @@ } return Redirect.data = o; }, - archives: [{"uid":0,"name":"Foolz","domain":"archive.foolz.us","http":true,"https":true,"software":"foolfuuka","boards":["a","biz","co","diy","gd","jp","m","sci","sp","tg","tv","vg","vp","vr","wsg"],"files":["a","biz","gd","diy","jp","m","sci","tg","vg","vp","vr","wsg"]},{"uid":1,"name":"NSFW Foolz","domain":"nsfw.foolz.us","http":true,"https":true,"software":"foolfuuka","boards":["u"],"files":["u"]},{"uid":2,"name":"The Dark Cave","domain":"archive.thedarkcave.org","http":true,"https":true,"software":"foolfuuka","boards":["c","int","out","po"],"files":["c","po"]},{"uid":3,"name":"4plebs Archive","domain":"archive.4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["adv","hr","o","pol","s4s","tg","trv","tv","x"],"files":["adv","hr","o","pol","s4s","tg","trv","tv","x"]},{"uid":18,"name":"4plebs Flash Archive","domain":"flash.4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["f"],"files":["f"]},{"uid":4,"name":"Nyafuu","domain":"archive.nyafuu.org","http":true,"https":true,"software":"foolfuuka","boards":["c","e","w","wg"],"files":["c","e","w","wg"]},{"uid":5,"name":"Love is Over","domain":"archive.loveisover.me","http":true,"https":true,"software":"foolfuuka","boards":["d","i","lgbt"],"files":["d","i","lgbt"]},{"uid":8,"name":"Rebecca Black Tech","domain":"rbt.asia","http":true,"https":true,"software":"fuuka","boards":["cgl","g","mu","w"],"files":["cgl","g","mu","w"]},{"uid":9,"name":"Heinessen","domain":"archive.heinessen.com","http":true,"https":false,"software":"fuuka","boards":["an","fit","k","mlp","r9k","toy"],"files":["an","fit","k","r9k","toy"]},{"uid":10,"name":"warosu","domain":"fuuka.warosu.org","http":false,"https":true,"software":"fuuka","boards":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"],"files":["3","biz","cgl","ck","diy","fa","ic","jp","lit","sci","tg","vr"]},{"uid":15,"name":"fgts","domain":"fgts.eu","http":true,"https":true,"software":"foolfuuka","boards":["asp","cm","h","hc","hm","n","p","r","s","soc","y"],"files":["asp","cm","h","hc","hm","n","p","r","s","soc","y"]},{"uid":16,"name":"maware","domain":"archive.mawa.re","http":true,"https":false,"software":"foolfuuka","boards":["t"],"files":["t"]},{"uid":17,"name":"installgentoo.com","domain":"chan.installgentoo.com","http":true,"https":false,"software":"foolfuuka","boards":["g","t"],"files":["g","t"]},{"uid":13,"name":"Foolz Beta","domain":"beta.foolz.us","http":true,"https":true,"withCredentials":true,"software":"foolfuuka","boards":["a","biz","co","d","diy","gd","jp","m","s4s","sci","sp","tg","tv","u","vg","vp","vr","wsg"],"files":["a","biz","d","diy","gd","jp","m","s4s","sci","tg","u","vg","vp","vr","wsg"]}], + archives: [{"uid":0,"name":"Foolz","domain":"archive.foolz.us","http":true,"https":true,"software":"foolfuuka","boards":["a","biz","co","diy","gd","jp","m","sci","sp","tg","tv","vg","vp","vr","wsg"],"files":["a","biz","diy","gd","jp","m","sci","tg","vg","vp","vr","wsg"]},{"uid":1,"name":"NSFW Foolz","domain":"nsfw.foolz.us","http":true,"https":true,"software":"foolfuuka","boards":["u"],"files":["u"]},{"uid":2,"name":"The Dark Cave","domain":"archive.thedarkcave.org","http":true,"https":true,"software":"foolfuuka","boards":["c","int","out","po"],"files":["c","po"]},{"uid":3,"name":"4plebs Archive","domain":"archive.4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["adv","hr","o","pol","s4s","tg","trv","tv","x"],"files":["adv","hr","o","pol","s4s","tg","trv","tv","x"]},{"uid":18,"name":"4plebs Flash Archive","domain":"flash.4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["f"],"files":["f"]},{"uid":4,"name":"Nyafuu","domain":"archive.nyafuu.org","http":true,"https":true,"software":"foolfuuka","boards":["c","e","w","wg"],"files":["c","e","w","wg"]},{"uid":5,"name":"Love is Over","domain":"archive.loveisover.me","http":true,"https":true,"software":"foolfuuka","boards":["d","i","lgbt"],"files":["d","i","lgbt"]},{"uid":8,"name":"Rebecca Black Tech","domain":"rbt.asia","http":false,"https":true,"software":"fuuka","boards":["cgl","g","mu","w"],"files":["cgl","g","mu","w"]},{"uid":9,"name":"Heinessen","domain":"archive.heinessen.com","http":true,"https":false,"software":"fuuka","boards":["an","fit","k","mlp","r9k","toy"],"files":["an","fit","k","mlp","r9k","toy"]},{"uid":10,"name":"warosu","domain":"fuuka.warosu.org","http":false,"https":true,"software":"fuuka","boards":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"],"files":["3","biz","cgl","ck","diy","fa","ic","jp","lit","sci","tg","vr"]},{"uid":15,"name":"fgts","domain":"fgts.eu","http":true,"https":true,"software":"foolfuuka","boards":["asp","cm","h","hc","hm","n","p","r","s","soc","y"],"files":["asp","cm","h","hc","hm","n","p","r","s","soc","y"]},{"uid":16,"name":"maware","domain":"archive.mawa.re","http":true,"https":false,"software":"foolfuuka","boards":["t"],"files":["t"]},{"uid":17,"name":"installgentoo.com","domain":"chan.installgentoo.com","http":true,"https":false,"software":"foolfuuka","boards":["g","t"],"files":["g","t"]},{"uid":19,"name":"Innovandalism Archive","domain":"boards.innovandalism.eu","http":true,"https":false,"software":"foolfuuka","boards":["v"],"files":[]},{"uid":13,"name":"Foolz Beta","domain":"beta.foolz.us","http":true,"https":true,"withCredentials":true,"software":"foolfuuka","boards":["a","biz","co","d","diy","gd","jp","m","s4s","sci","sp","tg","tv","u","vg","vp","vr","wsg"],"files":["a","biz","d","diy","gd","jp","m","s4s","sci","tg","u","vg","vp","vr","wsg"]},{"uid":19,"name":"Innovandalism Archive","domain":"boards.innovandalism.eu","http":true,"https":false,"software":"foolfuuka","boards":["v"],"files":[]}], to: function(dest, data) { var archive; archive = (dest === 'search' || dest === 'board' ? Redirect.data.thread : Redirect.data[dest])[data.boardID]; @@ -13319,7 +13338,7 @@ "https": true, "software": "foolfuuka", "boards": ["a", "biz", "co", "diy", "gd", "jp", "m", "sci", "sp", "tg", "tv", "vg", "vp", "vr", "wsg"], - "files": ["a", "biz", "gd", "diy", "jp", "m", "sci", "tg", "vg", "vp", "vr", "wsg"] + "files": ["a", "biz", "diy", "gd", "jp", "m", "sci", "tg", "vg", "vp", "vr", "wsg"] }, { "uid": 1, "name": "NSFW Foolz", @@ -13378,7 +13397,7 @@ "uid": 8, "name": "Rebecca Black Tech", "domain": "rbt.asia", - "http": true, + "http": false, "https": true, "software": "fuuka", "boards": ["cgl", "g", "mu", "w"], @@ -13391,7 +13410,7 @@ "https": false, "software": "fuuka", "boards": ["an", "fit", "k", "mlp", "r9k", "toy"], - "files": ["an", "fit", "k", "r9k", "toy"] + "files": ["an", "fit", "k", "mlp", "r9k", "toy"] }, { "uid": 10, "name": "warosu", @@ -13428,6 +13447,15 @@ "software": "foolfuuka", "boards": ["g", "t"], "files": ["g", "t"] + }, { + "uid": 19, + "name": "Innovandalism Archive", + "domain": "boards.innovandalism.eu", + "http": true, + "https": false, + "software": "foolfuuka", + "boards": ["v"], + "files": [] }, { "uid": 13, "name": "Foolz Beta", @@ -13438,6 +13466,15 @@ "software": "foolfuuka", "boards": ["a", "biz", "co", "d", "diy", "gd", "jp", "m", "s4s", "sci", "sp", "tg", "tv", "u", "vg", "vp", "vr", "wsg"], "files": ["a", "biz", "d", "diy", "gd", "jp", "m", "s4s", "sci", "tg", "u", "vg", "vp", "vr", "wsg"] + }, { + "uid": 19, + "name": "Innovandalism Archive", + "domain": "boards.innovandalism.eu", + "http": true, + "https": false, + "software": "foolfuuka", + "boards": ["v"], + "files": [] } ]; @@ -15132,65 +15169,10 @@ return CatalogLinks.el.title = "Turn catalog links " + (useCatalog ? 'off' : 'on') + "."; }, external: function(board) { - switch (board) { - case 'a': - case 'c': - case 'g': - case 'co': - case 'k': - case 'm': - case 'o': - case 'p': - case 'v': - case 'vg': - case 'w': - case 'cm': - case '3': - case 'adv': - case 'an': - case 'cgl': - case 'ck': - case 'diy': - case 'fa': - case 'fit': - case 'int': - case 'jp': - case 'mlp': - case 'lit': - case 'mu': - case 'n': - case 'po': - case 'sci': - case 'toy': - case 'trv': - case 'tv': - case 'vp': - case 'x': - case 'q': - return "http://catalog.neet.tv/" + board; - case 'd': - case 'e': - case 'gif': - case 'h': - case 'hr': - case 'hc': - case 'r9k': - case 's': - case 'pol': - case 'soc': - case 'u': - case 'i': - case 'ic': - case 'hm': - case 'r': - case 'w': - case 'wg': - case 'wsg': - case 't': - case 'y': - return "http://4index.gropes.us/" + board; - default: - return "/" + board + "/catalog"; + if (board === 'a' || board === 'c' || board === 'g' || board === 'co' || board === 'k' || board === 'm' || board === 'o' || board === 'p' || board === 'v' || board === 'vg' || board === 'w' || board === 'cm' || board === '3' || board === 'adv' || board === 'an' || board === 'cgl' || board === 'ck' || board === 'diy' || board === 'fa' || board === 'fit' || board === 'int' || board === 'jp' || board === 'mlp' || board === 'lit' || board === 'mu' || board === 'n' || board === 'po' || board === 'sci' || board === 'toy' || board === 'trv' || board === 'tv' || board === 'vp' || board === 'x' || board === 'q') { + return "http://catalog.neet.tv/" + board; + } else { + return "/" + board + "/catalog"; } } }; @@ -15917,6 +15899,9 @@ return; } target = e.target; + if (target.nodeName === 'EMBED') { + return; + } if ((_ref = target.nodeName) === 'INPUT' || _ref === 'TEXTAREA') { if (!/(Esc|Alt|Ctrl|Meta|Shift\+\w{2,})/.test(key)) { return; @@ -16877,7 +16862,7 @@ } if (e) { if (e.shiftKey || e.ctrlKey || (e.type === 'click' && e.button !== 0)) { - if ((e != null ? e.button : void 0) !== 2) { + if (e.button !== 2) { Navigate.setMode(this); } return; @@ -17364,7 +17349,7 @@ return $.on(ta, 'change', $.cb.value); }, advanced: function(section) { - var archBoards, boardID, boardOptions, boardSelect, boards, event, files, input, inputs, item, items, name, o, row, rows, software, ta, table, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2, _ref3, _ref4; + var archBoards, boardID, boardOptions, boardSelect, boards, event, files, i, input, inputs, item, items, name, o, row, rows, software, ta, table, withCredentials, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _len5, _m, _n, _ref, _ref1, _ref2, _ref3, _ref4, _ref5; 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 Twitter link (@).
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\"
External link: external-text:\"Google\",\"http://www.google.com\"
Index mode: g-mode:\"type\" where type is paged, all threads or catalog
Index sort: g-sort:\"type\" where type is bump order, last reply, creation date, reply count or file countCombinations are possible: g-text:\"VIP Catalog\"-mode:\"catalog\"-sort:\"creation date\"
Full board list toggle: toggle-all

[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h-mode:\"catalog\"-sort:\"file count\"] [t-text:\"Piracy\"]
will give you
[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
if you are on /g/.
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

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

Unread Favicon is disabled.
Emoji is disabled.
Sage Icon:
Thread Updater is disabled.
Interval:
Custom CSS
"; items = {}; inputs = {}; @@ -17402,28 +17387,40 @@ archBoards = {}; _ref1 = Redirect.archives; for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - _ref2 = _ref1[_j], name = _ref2.name, boards = _ref2.boards, files = _ref2.files, software = _ref2.software; + _ref2 = _ref1[_j], name = _ref2.name, boards = _ref2.boards, files = _ref2.files, software = _ref2.software, withCredentials = _ref2.withCredentials; for (_k = 0, _len2 = boards.length; _k < _len2; _k++) { boardID = boards[_k]; o = archBoards[boardID] || (archBoards[boardID] = { - thread: [], - post: [], - file: [] + thread: [[], []], + post: [[], []], + file: [[], []] }); - o.thread.push(name); + i = +(!!withCredentials); + o.thread[i].push(name); if (software === 'foolfuuka') { - o.post.push(name); + o.post[i].push(name); } if (__indexOf.call(files, boardID) >= 0) { - o.file.push(name); + o.file[i].push(name); } } } + for (boardID in archBoards) { + o = archBoards[boardID]; + _ref3 = ['thread', 'post', 'file']; + for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) { + item = _ref3[_l]; + if (o[item][0].length === 0 && o[item][1].length !== 0) { + o[item][0].push('disabled'); + } + o[item] = o[item][0].concat(o[item][1]); + } + } rows = []; boardOptions = []; - _ref3 = Object.keys(archBoards).sort(); - for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) { - boardID = _ref3[_l]; + _ref4 = Object.keys(archBoards).sort(); + for (_m = 0, _len4 = _ref4.length; _m < _len4; _m++) { + boardID = _ref4[_m]; row = $.el('tr', { className: "board-" + boardID }); @@ -17434,9 +17431,9 @@ selected: boardID === g.BOARD.ID })); o = archBoards[boardID]; - _ref4 = ['thread', 'post', 'file']; - for (_m = 0, _len4 = _ref4.length; _m < _len4; _m++) { - item = _ref4[_m]; + _ref5 = ['thread', 'post', 'file']; + for (_n = 0, _len5 = _ref5.length; _n < _len5; _n++) { + item = _ref5[_n]; $.add(row, Settings.addArchiveCell(boardID, o, item)); } rows.push(row); @@ -18196,7 +18193,7 @@ }); }, initFeatures: function() { - var href, init, video, _ref; + var href, init, _ref; Favicon.el.type = 'image/x-icon'; href = Favicon.el.href; Favicon.SFW = /ws\.ico$/.test(href); @@ -18225,20 +18222,8 @@ Report.init(); return; case 'i.4cdn.org': - if (Conf['Loop in New Tab'] && (video = $('video'))) { - Video.configure(video); - $.on(video, 'click', function() { - if (!video.controls) { - if (video.paused) { - return video.play(); - } else { - return video.pause(); - } - } - }); - } $.ready(function() { - var URL, pathname, _ref1; + var URL, pathname, video, _ref1; if (Conf['404 Redirect'] && ((_ref1 = d.title) === '4chan - Temporarily Offline' || _ref1 === '4chan - 404 Not Found')) { Redirect.init(); pathname = location.pathname.split('/'); @@ -18249,6 +18234,17 @@ if (URL) { return location.replace(URL); } + } else if (Conf['Loop in New Tab'] && (video = $('video'))) { + Video.configure(video); + if (!video.controls) { + return $.on(video, 'click', function() { + if (video.paused) { + return video.play(); + } else { + return video.pause(); + } + }); + } } }); return; diff --git a/builds/updates.xml b/builds/updates.xml index e4881e51d..786a7fdf3 100644 --- a/builds/updates.xml +++ b/builds/updates.xml @@ -1,7 +1,7 @@ - + diff --git a/css/style.css b/css/style.css index 545a7422b..13be06eec 100644 --- a/css/style.css +++ b/css/style.css @@ -18,9 +18,9 @@ outline: none; transition: color .25s, border-color .25s, flex .25s; } -.field::-moz-placeholder, -.field:hover::-moz-placeholder { - color: #AAA !important; +.field::-moz-placeholder { + color: #AAA; + opacity: 1; } .field:hover { border-color: #999; diff --git a/src/Archive/Redirect.coffee b/src/Archive/Redirect.coffee index 126ebc815..c058a61d2 100755 --- a/src/Archive/Redirect.coffee +++ b/src/Archive/Redirect.coffee @@ -7,9 +7,9 @@ Redirect = archives = {} for data in Redirect.archives - {name, boards, files, software} = data + {name, boards, files, software, withCredentials} = data archives[name] = data - for boardID in boards + for boardID in boards when !withCredentials o.thread[boardID] = data unless boardID of o.thread o.post[boardID] = data unless boardID of o.post or software isnt 'foolfuuka' o.file[boardID] = data unless boardID of o.file or boardID not in files diff --git a/src/Archive/archives.json b/src/Archive/archives.json index 8c45af6c1..0fb712920 100644 --- a/src/Archive/archives.json +++ b/src/Archive/archives.json @@ -6,7 +6,7 @@ "https": true, "software": "foolfuuka", "boards": ["a", "biz", "co", "diy", "gd", "jp", "m", "sci", "sp", "tg", "tv", "vg", "vp", "vr", "wsg"], - "files": ["a", "biz", "gd", "diy", "jp", "m", "sci", "tg", "vg", "vp", "vr", "wsg"] + "files": ["a", "biz", "diy", "gd", "jp", "m", "sci", "tg", "vg", "vp", "vr", "wsg"] }, { "uid": 1, "name": "NSFW Foolz", @@ -65,7 +65,7 @@ "uid": 8, "name": "Rebecca Black Tech", "domain": "rbt.asia", - "http": true, + "http": false, "https": true, "software": "fuuka", "boards": ["cgl", "g", "mu", "w"], @@ -78,7 +78,7 @@ "https": false, "software": "fuuka", "boards": ["an", "fit", "k", "mlp", "r9k", "toy"], - "files": ["an", "fit", "k", "r9k", "toy"] + "files": ["an", "fit", "k", "mlp", "r9k", "toy"] }, { "uid": 10, "name": "warosu", @@ -115,6 +115,15 @@ "software": "foolfuuka", "boards": ["g", "t"], "files": ["g", "t"] +}, { + "uid": 19, + "name": "Innovandalism Archive", + "domain": "boards.innovandalism.eu", + "http": true, + "https": false, + "software": "foolfuuka", + "boards": ["v"], + "files": [] }, { "uid": 13, "name": "Foolz Beta", @@ -125,4 +134,13 @@ "software": "foolfuuka", "boards": ["a", "biz", "co", "d", "diy", "gd", "jp", "m", "s4s", "sci", "sp", "tg", "tv", "u", "vg", "vp", "vr", "wsg"], "files": ["a", "biz", "d", "diy", "gd", "jp", "m", "s4s", "sci", "tg", "u", "vg", "vp", "vr", "wsg"] +}, { + "uid": 19, + "name": "Innovandalism Archive", + "domain": "boards.innovandalism.eu", + "http": true, + "https": false, + "software": "foolfuuka", + "boards": ["v"], + "files": [] }] diff --git a/src/General/Build.coffee b/src/General/Build.coffee index ee3023c23..b827f417d 100755 --- a/src/General/Build.coffee +++ b/src/General/Build.coffee @@ -47,7 +47,7 @@ Build = name: data.filename + data.ext timestamp: "#{data.tim}#{data.ext}" url: if boardID is 'f' - "//i.4cdn.org/#{boardID}/#{data.filename}#{data.ext}" + "//i.4cdn.org/#{boardID}/#{encodeURIComponent data.filename}#{data.ext}" else "//i.4cdn.org/#{boardID}/#{data.tim}#{data.ext}" height: data.h @@ -150,7 +150,7 @@ Build = imgSrc = if boardID is 'f' '' else - "" + + "" + "#{fileSize}" + "" @@ -166,7 +166,7 @@ Build = fileDims = if file.name[-3..] is 'pdf' then 'PDF' else "#{file.width}x#{file.height}" fileInfo = "" fileHTML = "
#{fileInfo}#{imgSrc}
" @@ -284,7 +284,7 @@ Build = pageCount = Index.liveThreadData.keys.indexOf("#{thread.ID}") // Index.threadsNumPerPage + 1 subject = if thread.OP.info.subject - "
#{thread.OP.info.subject}
" + "
#{thread.OP.nodes.subject.innerHTML}
" else '' comment = thread.OP.nodes.comment.innerHTML.replace /(
\s*){2,}/g, '
' diff --git a/src/General/Index.coffee b/src/General/Index.coffee index 9f1f3702c..d1c7df116 100644 --- a/src/General/Index.coffee +++ b/src/General/Index.coffee @@ -91,6 +91,7 @@ Index = @navLinks = $.el 'div', className: 'navLinks' innerHTML: <%= importHTML('Features/Index-navlinks') %> + @timeEl = $ 'time#index-last-refresh', @navLinks @searchInput = $ '#index-search', @navLinks @@ -114,7 +115,8 @@ Index = @currentPage = @getCurrentPage() - $.on d, 'scroll', Index.scroll + $.on d, 'scroll', @scroll + $.on window, 'focus', @updateIfNeeded $.on @pagelist, 'click', @cb.pageNav returnLink = $.el 'a', @@ -221,11 +223,12 @@ Index = thread = g.threads[@parentNode.dataset.fullID] if e.shiftKey PostHiding.toggle thread.OP + e.preventDefault() else if e.altKey Index.togglePin thread + e.preventDefault() else - Navigate.navigate.call @ - e.preventDefault() + Navigate.navigate.call @, e onOver: (e) -> # 4chan's less than stellar CSS forces us to include a .post and .postInfo @@ -297,7 +300,7 @@ Index = setupNavLinks: -> for el in $$ '.navLinks.desktop > a' - if el.getAttribute('href') is '.././catalog' + if /\/catalog$/.test el.pathname el.href = '.././' $.on el, 'click', -> switch @textContent @@ -508,6 +511,18 @@ Index = else "#{hiddenCount} hidden threads" + updateIfNeeded: -> + {timeEl} = Index + needed = + # we're on the index, + g.VIEW is 'index' and + # not currently refreshing + !Index.req and + timeEl.dataset.utc and + # more than 10 minutes have elapsed since the last refresh. + timeEl.dataset.utc < Date.now() - (10 * $.MINUTE) + Index.update() if needed + update: (pageNum) -> return unless navigator.onLine if g.VIEW is 'thread' @@ -585,7 +600,7 @@ Index = new Notice 'error', 'Index refresh failed.', 1 return - timeEl = $ 'time#index-last-refresh', Index.navLinks + {timeEl} = Index timeEl.dataset.utc = Date.parse req.getResponseHeader 'Last-Modified' RelativeDates.update timeEl Index.scrollToIndex() diff --git a/src/General/Main.coffee b/src/General/Main.coffee index fd9ff37a5..a0b164864 100644 --- a/src/General/Main.coffee +++ b/src/General/Main.coffee @@ -87,11 +87,6 @@ Main = Report.init() return when 'i.4cdn.org' - if Conf['Loop in New Tab'] and video = $ 'video' - Video.configure video - $.on video, 'click', -> - if !video.controls - if video.paused then video.play() else video.pause() $.ready -> if Conf['404 Redirect'] and d.title in ['4chan - Temporarily Offline', '4chan - 404 Not Found'] Redirect.init() @@ -100,6 +95,11 @@ Main = boardID: g.BOARD.ID filename: pathname[pathname.length - 1] location.replace URL if URL + else if Conf['Loop in New Tab'] and video = $ 'video' + Video.configure video + if !video.controls + $.on video, 'click', -> + if video.paused then video.play() else video.pause() return # c.time 'All initializations' diff --git a/src/General/Navigate.coffee b/src/General/Navigate.coffee index ab0b9c6e3..e93d9c015 100644 --- a/src/General/Navigate.coffee +++ b/src/General/Navigate.coffee @@ -196,7 +196,7 @@ Navigate = return if @hostname isnt 'boards.4chan.org' or window.location.hostname is 'rs.4chan.org' if e if e.shiftKey or e.ctrlKey or (e.type is 'click' and e.button isnt 0) # Not simply a left click - Navigate.setMode @ unless e?.button is 2 # Right Click + Navigate.setMode @ unless e.button is 2 # Right Click return if @pathname is Navigate.path diff --git a/src/General/Settings.coffee b/src/General/Settings.coffee index bf53a7bd5..3ca8f5e37 100755 --- a/src/General/Settings.coffee +++ b/src/General/Settings.coffee @@ -266,15 +266,21 @@ Settings = $.on $.id('apply-css'), 'click', Settings.usercss archBoards = {} - for {name, boards, files, software} in Redirect.archives + for {name, boards, files, software, withCredentials} in Redirect.archives for boardID in boards o = archBoards[boardID] or= - thread: [] - post: [] - file: [] - o.thread.push name - o.post.push name if software is 'foolfuuka' - o.file.push name if boardID in files + thread: [[], []] + post: [[], []] + file: [[], []] + i = +!!withCredentials + o.thread[i].push name + o.post[i].push name if software is 'foolfuuka' + o.file[i].push name if boardID in files + for boardID, o of archBoards + for item in ['thread', 'post', 'file'] + if o[item][0].length is 0 and o[item][1].length isnt 0 + o[item][0].push 'disabled' + o[item] = o[item][0].concat(o[item][1]) rows = [] boardOptions = [] diff --git a/src/General/css/style.css b/src/General/css/style.css index dd4425a8b..425e106b7 100755 --- a/src/General/css/style.css +++ b/src/General/css/style.css @@ -69,24 +69,9 @@ a { border-radius: 3px; padding: 0px 2px; } -body > hr, -#blotter hr, -.desktop > hr, -#delform > hr, -#content > hr { - display: none; -} -:root.index .board > hr:last-of-type, -:root.thread .board > hr { - border: 0px; - margin: 0px; -} .ad-plea { display: none; } -.ad-cnt { - margin: 10px !important; -} /* 4chan style fixes */ .opContainer, .op { @@ -904,13 +889,16 @@ span.hide-announcement { /* QR */ :root.hide-original-post-form #postForm, -:root.hide-original-post-form .postingMode, -:root.hide-original-post-form #togglePostForm, +:root.hide-original-post-form #togglePostFormLink, +:root:not(.catalog) #togglePostFormLink, #qr.autohide:not(.focus):not(:hover):not(:active) > form, .thread #qr select[data-name=thread], #file-n-submit:not(.has-file) #qr-filerm { display: none; } +:root:not(.hide-original-post-form):not(.catalog) #postForm { + display: table; +} #qr select, #dump-button, #url-button, diff --git a/src/General/html/Build/post.html b/src/General/html/Build/post.html index ca90ffeb9..c92354f68 100755 --- a/src/General/html/Build/post.html +++ b/src/General/html/Build/post.html @@ -24,7 +24,7 @@ "javascript:quote(#{postID})" else "/#{boardID}/thread/#{threadID}#q#{postID}" - }' title='Quote this post'>#{postID} + }' title='Reply to this post'>#{postID} #{pageIcon + sticky + closed + replyLink} diff --git a/src/Linkification/Linkify.coffee b/src/Linkification/Linkify.coffee index 4544d15f6..f9a081b6f 100755 --- a/src/Linkification/Linkify.coffee +++ b/src/Linkification/Linkify.coffee @@ -10,14 +10,13 @@ Linkify = if Conf['Embedding'] or Conf['Link Title'] @embedProcess = Function 'link', - "var data = this.services(link); - if (data) { - #{ - (if Conf['Embedding'] then 'this.embed(data);\n' else '') + - if Conf['Link Title'] then 'this.title(data);' else '' - } - } - " + """ + var data = this.services(link); + if (data) {#{ + (if Conf['Embedding'] then 'this.embed(data); ' else '') + + if Conf['Link Title'] then 'data.push(post); this.title(data);' else '' + }} + """ Post.callbacks.push name: 'Linkify' @@ -156,7 +155,7 @@ Linkify = return embed: (data) -> - [key, uid, options, link] = data + [key, uid, options, link, post] = data href = link.href embed = $.el 'a', className: 'embedder' @@ -164,7 +163,6 @@ Linkify = textContent: '(embed)' embed.dataset[name] = value for name, value of {key, href, uid, options} - embed.dataset.nodedata = link.innerHTML $.addClass link, "#{embed.dataset.key}" @@ -173,33 +171,30 @@ Linkify = Linkify.cb.toggle.call embed if Conf['Auto-embed'] - data.push embed - title: (data) -> - [key, uid, options, link, embed] = data + [key, uid, options, link, post] = data return unless service = Linkify.types[key].title titles = Conf['CachedTitles'] if title = titles[uid] - # Auto-embed may destroy our links. - if link - link.textContent = title[0] - if Conf['Embedding'] - embed.dataset.title = title[0] + link.textContent = title[0] else try $.cache service.api(uid), (-> Linkify.cb.title @, data), responseType: 'json' catch err - if link - link.innerHTML = "[#{key}] Title Link Blocked (are you using NoScript?)" + link.innerHTML = 'Title Link Blocked (are you using NoScript?)' + $.prepend link, $.tn "[#{key}] " return cb: toggle: -> - [string, @textContent] = if $.hasClass @, "embedded" - ['unembed', '(embed)'] + if $.hasClass @, "embedded" + $.rm @previousElementSibling + @previousElementSibling.hidden = false + @textContent = '(embed)' else - ['embed', '(unembed)'] - $.replace @previousElementSibling, Linkify.cb[string] @ + @previousElementSibling.hidden = true + $.before @, Linkify.cb.embed @ + @textContent = '(unembed)' $.toggleClass @, 'embedded' embed: (a) -> @@ -214,21 +209,8 @@ Linkify = return el - unembed: (a) -> - # Recreate the original link. - el = $.el 'a', - rel: 'nofollow noreferrer' - target: 'blank' - className: 'linkify' - href: a.dataset.href - innerHTML: a.dataset.title or a.dataset.nodedata - - $.addClass el, a.dataset.key - - return el - title: (req, data) -> - [key, uid, options, link, embed] = data + [key, uid, options, link, post] = data {status} = req service = Linkify.types[key].title @@ -243,8 +225,11 @@ Linkify = "#{status}'d" }" - embed.dataset.title = text if Conf['Embedding'] and status in [200, 304] - link.textContent = text if link + link.textContent = text + for post2 in post.clones + for link2 in $$ 'a', post2.nodes.comment when link2.href is link.href + link2.textContent = text + return ordered_types: [ key: 'audio' @@ -271,8 +256,10 @@ Linkify = regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/ style: 'border: 0; width: auto; height: auto;' el: (a) -> - $.el 'div', - innerHTML: "" + el = $.el 'div' + el.innerHTML = '' + el.firstChild.href = el.firstChild.firstChild.src = a.dataset.href + el , key: 'InstallGentoo' regExp: /.*(?:paste.installgentoo.com\/view\/)([0-9a-z_]+)/ @@ -298,35 +285,36 @@ Linkify = el , key: 'MediaCrush' - regExp: /.*(?:mediacru.sh\/)([0-9a-z_]+)/i + regExp: /.*(?:mediacru.sh\/)([0-9a-z_-]+)/i style: 'border: 0;' el: (a) -> el = $.el 'div' $.cache "https://mediacru.sh/#{a.dataset.uid}.json", -> {status} = @ - return div.innerHTML = "ERROR #{status}" unless status in [200, 304] + return el.textContent = "ERROR #{status}" unless status in [200, 304] {files} = @response - for type in ['video/mp4', 'video/ogv', 'image/svg+xml', 'image/png', 'image/gif', 'image/jpeg', 'image/svg', 'audio/mpeg'] + for type in ['video/mp4', 'video/webm', 'video/ogv', 'image/svg+xml', 'image/png', 'image/gif', 'image/jpeg', 'audio/mpeg', 'audio/ogg'] for file in files if file.type is type embed = file break break if embed - return div.innerHTML = "ERROR: Not a valid filetype" unless embed - el.innerHTML = switch embed.type - when 'video/mp4', 'video/ogv' then """ -""" - when 'image/png', 'image/gif', 'image/jpeg' - "" - when 'image/svg', 'image/svg+xml' - "" - when 'audio/mpeg' - "" + return div.textContent = "ERROR: Not a valid filetype" unless embed + switch embed.type + when 'video/mp4', 'video/webm', 'video/ogv' + el.innerHTML = '' + for ext, i in ['mp4', 'webm', 'ogv'] + el.firstChild.children[i].src = "https://mediacru.sh/#{a.dataset.uid}.#{ext}" + when 'image/svg+xml', 'image/png', 'image/gif', 'image/jpeg' + el.innerHTML = '' + el.firstChild.href = a.dataset.href + el.firstChild.firstChild.src = "https://mediacru.sh/#{file.file}" + when 'audio/mpeg', 'audio/ogg' + el.innerHTML = '' + for ext, i in ['ogg', 'mp3'] + el.firstChild.children[i].src = "https://mediacru.sh/#{a.dataset.uid}.#{ext}" else - "ERROR: No valid filetype." + el.textContent = "ERROR: No valid filetype." el , key: 'pastebin' @@ -343,19 +331,12 @@ Linkify = , key: 'SoundCloud' regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/ - style: 'height: auto; width: 500px; display: inline-block;' + style: 'border: 0; width: 500px; height: 400px;' el: (a) -> - div = $.el 'div', - className: "soundcloud" - name: "soundcloud" - $.ajax( - "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/#{a.dataset.uid}" - onloadend: -> - div.innerHTML = JSON.parse(@responseText).html - false) - div + $.el 'iframe', + src: "//w.soundcloud.com/player/?visual=true&show_comments=false&url=https%3A%2F%2Fsoundcloud.com%2F#{encodeURIComponent a.dataset.uid}" title: - api: (uid) -> "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/#{uid}" + api: (uid) -> "//soundcloud.com/oembed?format=json&url=https%3A%2F%2Fsoundcloud.com%2F#{encodeURIComponent uid}" text: (_) -> _.title , key: 'StrawPoll' @@ -369,26 +350,21 @@ Linkify = regExp: /.*(?:twitch.tv\/)([^#\&\?]*).*/ style: "border: none; width: 640px; height: 360px;" el: (a) -> - if result = /(\w+)\/(?:[a-z]\/)?(\d+)/i.exec a.dataset.uid - [_, channel, chapter] = result - - $.el 'object', + if result = /(\w+)\/([bc])\/(\d+)/i.exec a.dataset.uid + [_, channel, type, id] = result + idparam = {'b': 'archive_id', 'c': 'chapter_id'} + obj = $.el 'object', data: 'http://www.twitch.tv/widgets/archive_embed_player.swf' - innerHTML: """ - - -""" - + obj.innerHTML = '' + obj.children[1].value = "channel=#{channel}&start_volume=25&auto_play=false&#{idparam[type]}=#{id}" + obj else channel = (/(\w+)/.exec a.dataset.uid)[0] - - $.el 'object', + obj = $.el 'object', data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=#{channel}" - innerHTML: """ - - - -""" + obj.innerHTML = '' + obj.children[1].value = "hostname=www.twitch.tv&channel=#{channel}&auto_play=true&start_volume=25" + obj , key: 'Vocaroo' regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/ diff --git a/src/Miscellaneous/CatalogLinks.coffee b/src/Miscellaneous/CatalogLinks.coffee index 54bf4c4f8..6cf21509b 100755 --- a/src/Miscellaneous/CatalogLinks.coffee +++ b/src/Miscellaneous/CatalogLinks.coffee @@ -44,10 +44,7 @@ CatalogLinks = CatalogLinks.el.title = "Turn catalog links #{if useCatalog then 'off' else 'on'}." external: (board) -> - switch board - when 'a', 'c', 'g', 'co', 'k', 'm', 'o', 'p', 'v', 'vg', 'w', 'cm', '3', 'adv', 'an', 'cgl', 'ck', 'diy', 'fa', 'fit', 'int', 'jp', 'mlp', 'lit', 'mu', 'n', 'po', 'sci', 'toy', 'trv', 'tv', 'vp', 'x', 'q' - "http://catalog.neet.tv/#{board}" - when 'd', 'e', 'gif', 'h', 'hr', 'hc', 'r9k', 's', 'pol', 'soc', 'u', 'i', 'ic', 'hm', 'r', 'w', 'wg', 'wsg', 't', 'y' - "http://4index.gropes.us/#{board}" - else - "/#{board}/catalog" + if board in ['a', 'c', 'g', 'co', 'k', 'm', 'o', 'p', 'v', 'vg', 'w', 'cm', '3', 'adv', 'an', 'cgl', 'ck', 'diy', 'fa', 'fit', 'int', 'jp', 'mlp', 'lit', 'mu', 'n', 'po', 'sci', 'toy', 'trv', 'tv', 'vp', 'x', 'q'] + "http://catalog.neet.tv/#{board}" + else + "/#{board}/catalog" diff --git a/src/Miscellaneous/Keybinds.coffee b/src/Miscellaneous/Keybinds.coffee index 3be2a9ea7..799ca10c3 100755 --- a/src/Miscellaneous/Keybinds.coffee +++ b/src/Miscellaneous/Keybinds.coffee @@ -19,6 +19,7 @@ Keybinds = keydown: (e) -> return unless key = Keybinds.keyCode e {target} = e + return if target.nodeName is 'EMBED' # Prevent keybinds from firing on /f/ embeds. if target.nodeName in ['INPUT', 'TEXTAREA'] return unless /(Esc|Alt|Ctrl|Meta|Shift\+\w{2,})/.test key unless g.VIEW is 'catalog' diff --git a/src/Posting/QR.coffee b/src/Posting/QR.coffee index ef4f787ce..923554eaa 100644 --- a/src/Posting/QR.coffee +++ b/src/Posting/QR.coffee @@ -43,8 +43,7 @@ QR = initReady: -> $.off d, '4chanXInitFinished', @initReady QR.postingIsEnabled = !!$.id 'postForm' - unless QR.postingIsEnabled - return + return unless QR.postingIsEnabled $.on d, 'QRGetSelectedPost', ({detail: cb}) -> cb QR.selected @@ -359,26 +358,23 @@ QR = if /^text\//.test file.type if isSingle post = QR.selected - else if index isnt 0 or (post = QR.posts[QR.posts.length - 1]).com + else if (post = QR.posts[QR.posts.length - 1]).com post = new QR.post() post.pasteText file return unless file.type in QR.mimeTypes QR.error "#{file.name}: Unsupported file type." - return unless isSingle + return max = QR.nodes.fileInput.max max = Math.min(max, QR.max_size_video) if /^video\//.test file.type if file.size > max QR.error "#{file.name}: File too large (file: #{$.bytesToString file.size}, max: #{$.bytesToString max})." - return unless isSingle + return if isSingle post = QR.selected - else if index isnt 0 or (post = QR.posts[QR.posts.length - 1]).file + else if (post = QR.posts[QR.posts.length - 1]).file post = new QR.post() - if /^text/.test file.type - return post.pasteText file - else - post.setFile file + post.setFile file openFileInput: (e) -> e.stopPropagation() @@ -436,7 +432,6 @@ QR = setNode 'addPost', '#add-post' setNode 'charCount', '#char-count' setNode 'fileSubmit', '#file-n-submit' - setNode 'filesize', '#qr-filesize' setNode 'filename', '#qr-filename' setNode 'fileContainer', '#qr-filename-container' setNode 'fileRM', '#qr-filerm' diff --git a/src/Posting/QR.post.coffee b/src/Posting/QR.post.coffee index 846b7e59f..a8ffb86b5 100644 --- a/src/Posting/QR.post.coffee +++ b/src/Posting/QR.post.coffee @@ -82,6 +82,7 @@ QR.post = class (QR.posts[index-1] or QR.posts[index+1]).select() QR.posts.splice index, 1 QR.status() + delete: -> $.rm @nodes.el URL.revokeObjectURL @URL @@ -185,7 +186,7 @@ QR.post = class if errors.length QR.error error for error in errors @URL = fileURL # this.removeFile will revoke this proper. - return @rmFile() + return if (QR.posts.length is 1) or (@com and @com.length) then @rmFile() else @rm() # I wrote this while listening to MCR # Generate thumbnails only if they're really big. # Resized pictures through canvases look like ass,