diff --git a/CHANGELOG.md b/CHANGELOG.md index d55402a05..08d2e9cd7 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ Sometimes the changelog has notes (not comprehensive) acknowledging people's work. This does not mean the changes are their fault, only that their code was used. All changes to the script are chosen by and the fault of the maintainer (ccd0). +### v1.11.12 + +**v1.11.12.0** *(2015-10-04)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.12.0/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.12.0/builds/4chan-X-noupdate.crx "Chromium version")] +- Based on v1.11.11.5. +- Update Twitch, Vocaroo, and Clyp embedding. +- Links to images/videos on 4chan can now be embedded, with videos on 4chan set to loop by default. +- Remove link to HTTP version of post on links that can't be embedded in HTTPS. +- Add feedback page links to image captcha error messages. +- Minor bugfixes. + ### v1.11.11 **v1.11.11.5** *(2015-10-03)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.11.5/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.11.5/builds/4chan-X-noupdate.crx "Chromium version")] diff --git a/builds/4chan-X-beta.crx b/builds/4chan-X-beta.crx index acca62add..3b17d1595 100644 Binary files a/builds/4chan-X-beta.crx and b/builds/4chan-X-beta.crx differ diff --git a/builds/4chan-X-beta.meta.js b/builds/4chan-X-beta.meta.js index a66e9bdd5..3c6242bb9 100644 --- a/builds/4chan-X-beta.meta.js +++ b/builds/4chan-X-beta.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X beta -// @version 1.11.11.5 +// @version 1.11.12.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X diff --git a/builds/4chan-X-beta.user.js b/builds/4chan-X-beta.user.js index f1fff680b..c030c9bec 100644 --- a/builds/4chan-X-beta.user.js +++ b/builds/4chan-X-beta.user.js @@ -1,7 +1,7 @@ // Generated by CoffeeScript // ==UserScript== // @name 4chan X beta -// @version 1.11.11.5 +// @version 1.11.12.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -413,7 +413,7 @@ doc = d.documentElement; g = { - VERSION: '1.11.11.5', + VERSION: '1.11.12.0', NAMESPACE: '4chan X.', boards: {} }; @@ -1475,7 +1475,7 @@ Post.prototype.parseQuote = function(quotelink) { var fullID, match; - if (!(match = quotelink.href.match(/boards\.4chan\.org\/([^\/]+)\/(?:res|thread)\/\d+(?:\/[^#]*)?#p(\d+)$/))) { + if (!(match = quotelink.href.match(/^https?:\/\/boards\.4chan\.org\/+([^\/]+)\/+(?:res|thread)\/+\d+(?:\/[^#]*)?#p(\d+)$/))) { return; } this.nodes.quotelinks.push(quotelink); @@ -3508,7 +3508,7 @@ return; } e.preventDefault(); - return Index.userPageNav(+a.pathname.split('/')[2] || 1); + return Index.userPageNav(+a.pathname.split(/\/+/)[2] || 1); }, refreshFront: function() { return Index.update(Index.pushState({ @@ -3525,7 +3525,7 @@ if ((ref = Conf['Index Mode']) === 'all pages' || ref === 'catalog') { return 1; } else { - return +window.location.pathname.split('/')[2] || 1; + return +window.location.pathname.split(/\/+/)[2] || 1; } }, userPageNav: function(page) { @@ -3594,7 +3594,7 @@ mode: Conf['Index Mode'], searched: Index.search, oldpage: pageBeforeSearch - }, '', pathname + hash); + }, '', location.protocol + "//" + location.host + pathname + hash); return state; }, saveMode: function(mode) { @@ -4458,7 +4458,7 @@ postFromRoot: function(root) { var boardID, index, link, post, postID; link = $('.postNum > a[href*="#"]', root); - boardID = link.pathname.split('/')[1]; + boardID = link.pathname.split(/\/+/)[1]; postID = link.hash.slice(2); index = root.dataset.clone; post = g.posts[boardID + "." + postID]; @@ -4477,7 +4477,7 @@ postDataFromLink: function(link) { var boardID, path, postID, ref, threadID; if (link.hostname === 'boards.4chan.org') { - path = link.pathname.split('/'); + path = link.pathname.split(/\/+/); boardID = path[1]; threadID = path[3]; postID = link.hash.slice(2); @@ -7147,7 +7147,7 @@ return status.disabled = disabled || false; }, quote: function(e) { - var ancestor, caretPos, com, frag, index, insideCode, k, len1, len2, len3, len4, len5, len6, node, post, q, range, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, sel, text, thread, u, v, y, z; + var aa, ancestor, caretPos, com, frag, index, insideCode, k, len1, len2, len3, len4, len5, len6, node, post, q, range, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, sel, text, thread, u, v, z; if (e != null) { e.preventDefault(); } @@ -7192,13 +7192,13 @@ $.replace(node, [$.tn('[code]')].concat(slice.call(node.childNodes), [$.tn('[/code]')])); } ref4 = $$('.linkify[data-original]', frag); - for (y = 0, len5 = ref4.length; y < len5; y++) { - node = ref4[y]; + for (z = 0, len5 = ref4.length; z < len5; z++) { + node = ref4[z]; $.replace(node, $.tn(node.dataset.original)); } ref5 = $$('.embedder', frag); - for (z = 0, len6 = ref5.length; z < len6; z++) { - node = ref5[z]; + for (aa = 0, len6 = ref5.length; aa < len6; aa++) { + node = ref5[aa]; if (((ref6 = node.previousSibling) != null ? ref6.nodeValue : void 0) === ' ') { $.rm(node.previousSibling); } @@ -7880,7 +7880,23 @@ img.tabIndex = 0; } if (this.images.length === 9) { - return this.addTooltips(this.images); + this.addTooltips(this.images); + } + return this.complaintLinks(); + }, + complaintLinks: function() { + var errmsg, k, len1, link, ref; + ref = $$('.rc-imageselect-incorrect-response, .rc-imageselect-error-select-one, .rc-imageselect-error-select-more'); + for (k = 0, len1 = ref.length; k < len1; k++) { + errmsg = ref[k]; + if (!$('a', errmsg)) { + link = $.el('a', { + href: 'https://www.4chan.org/feedback', + target: '_blank', + textContent: '[complain]' + }); + $.add(errmsg, [$.tn(' '), link]); + } } }, addLabels: function() { @@ -11621,16 +11637,10 @@ var embed, href, key, link, name, options, post, ref, uid, value; key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post; href = link.href; - $.addClass(link, key.toLowerCase()); if (Embedding.types[key].httpOnly && location.protocol !== 'http:') { - embed = $.el('a', { - href: "http://boards.4chan.org/" + post.board + "/thread/" + post.thread + "#p" + post, - textContent: '(HTTP)', - title: key + " does not support HTTPS." - }); - $.after(link, [$.tn(' '), embed]); return; } + $.addClass(link, key.toLowerCase()); embed = $.el('a', { className: 'embedder', href: 'javascript:;', @@ -11691,6 +11701,7 @@ if (!(service = Embedding.types[key].title)) { return; } + $.addClass(link, key.toLowerCase()); if (service.batchSize) { (service.queue || (service.queue = [])).push(data); if (service.queue.length >= service.batchSize) { @@ -11877,13 +11888,11 @@ key: 'LiveLeak', regExp: /^\w+:\/\/(?:\w+\.)?liveleak\.com\/.*\?.*i=(\w+)/, httpOnly: true, + style: 'border: none; width: 640px; height: 360px;', el: function(a) { var el; el = $.el('iframe', { - width: "640", - height: "360", - src: "http://www.liveleak.com/ll_embed?i=" + a.dataset.uid, - frameborder: "0" + src: "http://www.liveleak.com/ll_embed?i=" + a.dataset.uid }); el.setAttribute("allowfullscreen", "true"); return el; @@ -11936,35 +11945,38 @@ }, { key: 'TwitchTV', regExp: /^\w+:\/\/(?:www\.)?twitch\.tv\/(\w[^#\&\?]*)/, - httpOnly: true, - style: "border: none; width: 640px; height: 360px;", + style: "border: none; width: 620px; height: 378px;", el: function(a) { - var _, channel, id, idparam, obj, result, type; - if (result = /(\w+)\/([bc])\/(\d+)/i.exec(a.dataset.uid)) { + var _, channel, flashvars, id, idprefix, k, len1, obj, part, ref, result, seconds, start, type; + if (result = /(\w+)\/([bcv])\/(\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' - }); - $.extend(obj, { - innerHTML: "" - }); - obj.children[1].value = "channel=" + channel + "&start_volume=25&auto_play=false&" + idparam[type] + "=" + id; - return obj; + idprefix = type === 'b' ? 'a' : type; + flashvars = "channel=" + channel + "&start_volume=25&auto_play=false&videoId=" + idprefix + id; + if (start = a.dataset.href.match(/\bt=(\w+)/)) { + seconds = 0; + ref = start[1].match(/\d+[hms]/g); + for (k = 0, len1 = ref.length; k < len1; k++) { + part = ref[k]; + seconds += +part.slice(0, -1) * { + 'h': 3600, + 'm': 60, + 's': 1 + }[part.slice(-1)]; + } + flashvars += "&initial_time=" + seconds; + } } else { channel = (/(\w+)/.exec(a.dataset.uid))[0]; - obj = $.el('object', { - data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=" + channel - }); - $.extend(obj, { - innerHTML: "" - }); - obj.children[1].value = "hostname=www.twitch.tv&channel=" + channel + "&auto_play=true&start_volume=25"; - return obj; + flashvars = "channel=" + channel + "&start_volume=25&auto_play=false"; } + obj = $.el('object', { + data: '//www-cdn.jtvnw.net/swflibs/TwitchPlayer.swf' + }); + $.extend(obj, { + innerHTML: "" + }); + obj.children[1].value = flashvars; + return obj; } }, { key: 'Vocaroo', @@ -11990,7 +12002,7 @@ }, title: { api: function(uid) { - return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + uid; + return "https://vimeo.com/api/oembed.json?url=https://vimeo.com/" + uid; }, text: function(_) { return _.title; @@ -12046,7 +12058,7 @@ } }, { key: 'Loopvid', - regExp: /^\w+:\/\/(?:www\.)?loopvid.appspot.com\/#?((?:pf|kd|lv|gd|gh|db|dx|nn|cp|wu|ig|ky|gc)\/[\w\-\/]+(,[\w\-\/]+)*|fc\/\w+\/\d+)/, + regExp: /^\w+:\/\/(?:www\.)?loopvid.appspot.com\/#?((?:pf|kd|lv|gd|gh|db|dx|nn|cp|wu|ig|ky|mf|pc|gc)\/[\w\-\/]+(,[\w\-\/]+)*|fc\/\w+\/\d+)/, style: 'max-width: 80vw; max-height: 80vh;', el: function(a) { var _, base, el, host, k, len1, len2, name, names, q, ref, ref1, type, types, url; @@ -12077,11 +12089,11 @@ url = (function() { switch (host) { case 'pf': - return "https://a.pomf.se/" + base; + return "https://web.archive.org/web/2/http://a.pomf.se/" + base; case 'kd': - return "http://2.kastden.org/loopvid/" + base; + return "http://kastden.org/loopvid/" + base; case 'lv': - return "http://loopvid.mooo.com/videos/" + base; + return "http://kastden.org/_loopvid_media/lv/" + base; case 'gd': return "https://docs.google.com/uc?export=download&id=" + base; case 'gh': @@ -12100,6 +12112,10 @@ return "https://i.imgur.com/" + base; case 'ky': return "https://kiyo.me/" + base; + case 'mf': + return "https://d.maxfile.ro/" + base; + case 'pc': + return "http://a.pomf.cat/" + base; case 'fc': return "//i.4cdn.org/" + base + ".webm"; case 'gc': @@ -12124,7 +12140,7 @@ preload: 'auto' }); type = el.canPlayType('audio/ogg') ? 'ogg' : 'mp3'; - el.src = "http://clyp.it/" + a.dataset.uid + "." + type; + el.src = "https://clyp.it/" + a.dataset.uid + "." + type; return el; } }, { @@ -12143,7 +12159,8 @@ return $.el('video', { controls: true, preload: 'auto', - src: a.dataset.href + src: a.dataset.href, + loop: /^https?:\/\/i\.4cdn\.org\//.test(a.dataset.href) }); } } @@ -12170,16 +12187,22 @@ return Embedding.init(); }, node: function() { - var k, len1, link, links; + var k, len1, len2, link, links, q, ref; if (this.isClone) { return Embedding.events(this); } if (!Linkify.regString.test(this.info.comment)) { return; } + ref = $$('a[href^="http://i.4cdn.org/"], a[href^="https://i.4cdn.org/"]', this.nodes.comment); + for (k = 0, len1 = ref.length; k < len1; k++) { + link = ref[k]; + $.addClass(link, 'linkify'); + Embedding.process(link, this); + } links = Linkify.process(this.nodes.comment); - for (k = 0, len1 = links.length; k < len1; k++) { - link = links[k]; + for (q = 0, len2 = links.length; q < len2; q++) { + link = links[q]; Embedding.process(link, this); } }, @@ -12190,9 +12213,9 @@ return Linkify.process(this.nodes.comment); }, process: function(node) { - var data, end, endNode, i, index, length, links, result, saved, snapshot, space, test, word; - test = /[^\s'"]+/g; - space = /[\s'"]/; + var data, end, endNode, i, index, length, links, ref, ref1, result, saved, snapshot, space, test, word; + test = /[^\s"]+/g; + space = /[\s"]/; snapshot = $.X('.//br|.//text()', node); i = 0; links = []; @@ -12209,7 +12232,11 @@ test.lastIndex = 0; while ((saved = snapshot.snapshotItem(i++))) { if (saved.nodeName === 'BR') { - break; + if (/^(https?:\/\/)?[a-z0-9\-\.]+$/i.test(word) && ((ref = snapshot.snapshotItem(i)) != null ? (ref1 = ref.data) != null ? ref1.match(/^(\.[a-z0-9\-]+)*\//i) : void 0 : void 0)) { + continue; + } else { + break; + } } endNode = saved; data = saved.data; @@ -12238,7 +12265,7 @@ } return links; }, - regString: /((https?|mailto|git|magnet|ftp|irc):([a-z\d%\/?])|([-a-z\d]+[.])+(aero|asia|biz|cat|com|coop|dance|info|int|jobs|mobi|moe|museum|name|net|org|post|pro|tel|travel|xxx|xyz|edu|gov|mil|[a-z]{2})([:\/]|(?![^\s'"]))|[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}|[-\w\d.@]+@[a-z\d.-]+\.[a-z\d])/i, + regString: /((https?|mailto|git|magnet|ftp|irc):([a-z\d%\/?])|([-a-z\d]+[.])+(aero|asia|biz|cat|com|coop|dance|info|int|jobs|mobi|moe|museum|name|net|org|post|pro|tel|travel|xxx|xyz|edu|gov|mil|[a-z]{2})([:\/]|(?![^\s"]))|[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}|[-\w\d.@]+@[a-z\d.-]+\.[a-z\d])/i, makeRange: function(startNode, endNode, startOffset, endOffset) { var range; range = document.createRange(); @@ -12247,7 +12274,7 @@ return range; }, makeLink: function(range) { - var a, i, t, text; + var a, encodedDomain, i, t, text; text = range.toString(); i = text.search(Linkify.regString); if (i > 0) { @@ -12278,6 +12305,15 @@ if (!/((mailto|magnet):|.+:\/\/)/.test(text)) { text = (/@/.test(text) ? 'mailto:' : 'http://') + text; } + if (encodedDomain = text.match(/^(https?:\/\/[^\/]*%[0-9a-f]{2})(.*)$/i)) { + text = encodedDomain[1].replace(/%([0-9a-f]{2})/ig, function(x, y) { + if (y === '25') { + return x; + } else { + return String.fromCharCode(parseInt(y, 16)); + } + }) + encodedDomain[2]; + } a = $.el('a', { className: 'linkify', rel: 'nofollow noreferrer', @@ -14814,7 +14850,7 @@ ref = $$(selector); for (k = 0, len1 = ref.length; k < len1; k++) { link = ref[k]; - switch (link.pathname) { + switch (link.pathname.replace(/\/+/g, '/')) { case "/" + g.BOARD + "/": if (Conf['JSON Navigation']) { link.textContent = 'Index'; @@ -14881,7 +14917,7 @@ ref = $$('a:not([data-only])', Header.boardList).concat($$('a', Header.bottomBoardList)); for (k = 0, len1 = ref.length; k < len1; k++) { a = ref[k]; - if (((ref1 = a.hostname) !== 'boards.4chan.org' && ref1 !== 'catalog.neet.tv' && ref1 !== '4index.gropes.us') || !(board = a.pathname.split('/')[1]) || (board === 'f' || board === 'status' || board === '4chan') || a.pathname.split('/')[2] === 'archive' || $.hasClass(a, 'external')) { + if (((ref1 = a.hostname) !== 'boards.4chan.org' && ref1 !== 'catalog.neet.tv') || !(board = a.pathname.split('/')[1]) || (board === 'f' || board === 'status' || board === '4chan') || a.pathname.split('/')[2] === 'archive' || $.hasClass(a, 'external')) { continue; } a.href = useCatalog ? CatalogLinks.catalog(board) : "/" + board + "/"; @@ -14894,7 +14930,7 @@ board = g.BOARD.ID; } if (Conf['External Catalog'] && (board === 'a' || board === 'c' || board === 'g' || board === 'biz' || board === 'k' || board === 'm' || board === 'o' || board === 'p' || board === 'v' || board === 'vg' || board === 'vr' || board === 'w' || board === 'wg' || board === 'cm' || board === '3' || board === 'adv' || board === 'an' || board === 'asp' || board === 'cgl' || board === 'ck' || board === 'co' || board === 'diy' || board === 'fa' || board === 'fit' || board === 'gd' || board === 'int' || board === 'jp' || board === 'lit' || board === 'mlp' || board === 'mu' || board === 'n' || board === 'out' || board === 'po' || board === 'sci' || board === 'sp' || board === 'tg' || board === 'toy' || board === 'trv' || board === 'tv' || board === 'vp' || board === 'wsg' || board === 'x' || board === 'f' || board === 'pol' || board === 's4s' || board === 'lgbt')) { - return "http://catalog.neet.tv/" + board; + return "http://catalog.neet.tv/" + board + "/"; } else if (Conf['JSON Navigation'] && Conf['Use 4chan X Catalog']) { if (g.BOARD.ID === board && g.VIEW === 'index') { return '#catalog'; @@ -14985,7 +15021,7 @@ return; } a.textContent = "Post No." + post + " Loading..."; - return $.cache("//a.4cdn.org" + (a.pathname.split('/').splice(0, 4).join('/')) + ".json", function() { + return $.cache("//a.4cdn.org" + (a.pathname.split(/\/+/).splice(0, 4).join('/')) + ".json", function() { return ExpandComment.parse(this, a, post); }); }, @@ -15031,9 +15067,9 @@ continue; } if (href[0] === '#') { - quote.href = "" + (a.pathname.split('/').splice(0, 4).join('/')) + href; + quote.href = "" + (a.pathname.split(/\/+/).splice(0, 4).join('/')) + href; } else { - quote.href = (a.pathname.split('/').splice(0, 3).join('/')) + "/" + href; + quote.href = (a.pathname.split(/\/+/).splice(0, 3).join('/')) + "/" + href; } } post.nodes.shortComment = comment; @@ -16886,7 +16922,7 @@ return $.on(ta, 'change', $.cb.value); }, advanced: function(section) { - var aa, applyCSS, archBoards, archive, boardID, boardOptions, boardSelect, boards, customCSS, files, i, input, inputs, interval, item, items, k, len1, len2, len3, len4, len5, len6, len7, name, o, q, ref, ref1, ref2, ref3, ref4, ref5, ref6, row, rows, software, ta, table, u, uid, v, warning, withCredentials, y, z; + var aa, ab, applyCSS, archBoards, archive, boardID, boardOptions, boardSelect, boards, customCSS, files, i, input, inputs, interval, item, items, k, len1, len2, len3, len4, len5, len6, len7, name, o, q, ref, ref1, ref2, ref3, ref4, ref5, ref6, row, rows, software, ta, table, u, uid, v, warning, withCredentials, z; $.extend(section, { innerHTML: "
Archiver
404 Redirect is disabled.
Thread redirectionPost fetchingFile redirection
Captcha Language
Choose from list of language codes. Leave blank to autoselect.
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
Archive link: g-archive
Internal archive link: g-expired
Title link: g-title
Board link (Replace with title when on that board): g-replace
Full text link: g-full
Custom text link: g-text:"Install Gentoo"
Index-only link: g-index
Catalog-only link: g-catalog
External link: external-text:"Google","http://www.google.com"
Combinations are possible: g-index-text:"Technology Index"
Full board list toggle: toggle-all

[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:"Piracy"]
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
Literal %: %%
Quote Backlinks formatting is disabled.
:
File Info Formatting is disabled.
:
Link: %l (truncated), %L (untruncated), %T (4chan filename)
Filename: %n (truncated), %N (untruncated), %t (4chan filename)
Spoiler indicator: %p
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
Resolution: %r (Displays 'PDF' for PDF files)
Tag: %g
Literal %: %%
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.
Thread Updater is disabled.
Interval: seconds
Custom Cooldown Time
Seconds:
" }); @@ -16966,8 +17002,8 @@ for (boardID in archBoards) { o = archBoards[boardID]; ref4 = ['thread', 'post', 'file']; - for (y = 0, len5 = ref4.length; y < len5; y++) { - item = ref4[y]; + for (z = 0, len5 = ref4.length; z < len5; z++) { + item = ref4[z]; i = o[item][0].length ? 1 : 0; o[item][i].push([null, 'disabled']); o[item] = o[item][0].concat(o[item][1]); @@ -16976,8 +17012,8 @@ rows = []; boardOptions = []; ref5 = Object.keys(archBoards).sort(); - for (z = 0, len6 = ref5.length; z < len6; z++) { - boardID = ref5[z]; + for (aa = 0, len6 = ref5.length; aa < len6; aa++) { + boardID = ref5[aa]; row = $.el('tr', { className: "board-" + boardID }); @@ -16989,8 +17025,8 @@ })); o = archBoards[boardID]; ref6 = ['thread', 'post', 'file']; - for (aa = 0, len7 = ref6.length; aa < len7; aa++) { - item = ref6[aa]; + for (ab = 0, len7 = ref6.length; ab < len7; ab++) { + item = ref6[ab]; $.add(row, Settings.addArchiveCell(boardID, o, item)); } rows.push(row); @@ -17197,7 +17233,7 @@ } g.threads = new SimpleDict(); g.posts = new SimpleDict(); - pathname = location.pathname.split('/'); + pathname = location.pathname.split(/\/+/); g.BOARD = new Board(pathname[1]); if ((ref = g.BOARD.ID) === 'z' || ref === 'fk') { return; @@ -17331,7 +17367,7 @@ }), function() { var pathname, ref1, video; if (Conf['404 Redirect'] && ((ref1 = d.title) === '4chan - Temporarily Offline' || ref1 === '4chan - 404 Not Found')) { - pathname = location.pathname.split('/'); + pathname = location.pathname.split(/\/+/); return Redirect.navigate('file', { boardID: g.BOARD.ID, filename: pathname[pathname.length - 1] @@ -17350,11 +17386,19 @@ }); return; } - if (Conf['Normalize URL'] && g.VIEW === 'thread') { - pathname = location.pathname.split('/'); - if (pathname[2] !== 'thread' || pathname.length > 4) { - pathname[2] = 'thread'; - history.replaceState(null, '', pathname.slice(0, 4).join('/') + location.hash); + if (Conf['Normalize URL']) { + pathname = location.pathname.split(/\/+/); + switch (g.VIEW) { + case 'thread': + pathname[2] = 'thread'; + pathname = pathname.slice(0, 4); + break; + case 'index': + pathname = pathname.slice(0, 3); + } + pathname = pathname.join('/'); + if (location.pathname !== pathname) { + history.replaceState(history.state, '', location.protocol + "//" + location.host + pathname + location.hash); } } ref1 = Main.features; diff --git a/builds/4chan-X-noupdate.crx b/builds/4chan-X-noupdate.crx index 632b9e822..95b37ed37 100644 Binary files a/builds/4chan-X-noupdate.crx and b/builds/4chan-X-noupdate.crx differ diff --git a/builds/4chan-X-noupdate.user.js b/builds/4chan-X-noupdate.user.js index 0f7fcf73a..70366f946 100644 --- a/builds/4chan-X-noupdate.user.js +++ b/builds/4chan-X-noupdate.user.js @@ -1,7 +1,7 @@ // Generated by CoffeeScript // ==UserScript== // @name 4chan X -// @version 1.11.11.5 +// @version 1.11.12.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -413,7 +413,7 @@ doc = d.documentElement; g = { - VERSION: '1.11.11.5', + VERSION: '1.11.12.0', NAMESPACE: '4chan X.', boards: {} }; @@ -1475,7 +1475,7 @@ Post.prototype.parseQuote = function(quotelink) { var fullID, match; - if (!(match = quotelink.href.match(/boards\.4chan\.org\/([^\/]+)\/(?:res|thread)\/\d+(?:\/[^#]*)?#p(\d+)$/))) { + if (!(match = quotelink.href.match(/^https?:\/\/boards\.4chan\.org\/+([^\/]+)\/+(?:res|thread)\/+\d+(?:\/[^#]*)?#p(\d+)$/))) { return; } this.nodes.quotelinks.push(quotelink); @@ -3508,7 +3508,7 @@ return; } e.preventDefault(); - return Index.userPageNav(+a.pathname.split('/')[2] || 1); + return Index.userPageNav(+a.pathname.split(/\/+/)[2] || 1); }, refreshFront: function() { return Index.update(Index.pushState({ @@ -3525,7 +3525,7 @@ if ((ref = Conf['Index Mode']) === 'all pages' || ref === 'catalog') { return 1; } else { - return +window.location.pathname.split('/')[2] || 1; + return +window.location.pathname.split(/\/+/)[2] || 1; } }, userPageNav: function(page) { @@ -3594,7 +3594,7 @@ mode: Conf['Index Mode'], searched: Index.search, oldpage: pageBeforeSearch - }, '', pathname + hash); + }, '', location.protocol + "//" + location.host + pathname + hash); return state; }, saveMode: function(mode) { @@ -4458,7 +4458,7 @@ postFromRoot: function(root) { var boardID, index, link, post, postID; link = $('.postNum > a[href*="#"]', root); - boardID = link.pathname.split('/')[1]; + boardID = link.pathname.split(/\/+/)[1]; postID = link.hash.slice(2); index = root.dataset.clone; post = g.posts[boardID + "." + postID]; @@ -4477,7 +4477,7 @@ postDataFromLink: function(link) { var boardID, path, postID, ref, threadID; if (link.hostname === 'boards.4chan.org') { - path = link.pathname.split('/'); + path = link.pathname.split(/\/+/); boardID = path[1]; threadID = path[3]; postID = link.hash.slice(2); @@ -7147,7 +7147,7 @@ return status.disabled = disabled || false; }, quote: function(e) { - var ancestor, caretPos, com, frag, index, insideCode, k, len1, len2, len3, len4, len5, len6, node, post, q, range, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, sel, text, thread, u, v, y, z; + var aa, ancestor, caretPos, com, frag, index, insideCode, k, len1, len2, len3, len4, len5, len6, node, post, q, range, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, sel, text, thread, u, v, z; if (e != null) { e.preventDefault(); } @@ -7192,13 +7192,13 @@ $.replace(node, [$.tn('[code]')].concat(slice.call(node.childNodes), [$.tn('[/code]')])); } ref4 = $$('.linkify[data-original]', frag); - for (y = 0, len5 = ref4.length; y < len5; y++) { - node = ref4[y]; + for (z = 0, len5 = ref4.length; z < len5; z++) { + node = ref4[z]; $.replace(node, $.tn(node.dataset.original)); } ref5 = $$('.embedder', frag); - for (z = 0, len6 = ref5.length; z < len6; z++) { - node = ref5[z]; + for (aa = 0, len6 = ref5.length; aa < len6; aa++) { + node = ref5[aa]; if (((ref6 = node.previousSibling) != null ? ref6.nodeValue : void 0) === ' ') { $.rm(node.previousSibling); } @@ -7880,7 +7880,23 @@ img.tabIndex = 0; } if (this.images.length === 9) { - return this.addTooltips(this.images); + this.addTooltips(this.images); + } + return this.complaintLinks(); + }, + complaintLinks: function() { + var errmsg, k, len1, link, ref; + ref = $$('.rc-imageselect-incorrect-response, .rc-imageselect-error-select-one, .rc-imageselect-error-select-more'); + for (k = 0, len1 = ref.length; k < len1; k++) { + errmsg = ref[k]; + if (!$('a', errmsg)) { + link = $.el('a', { + href: 'https://www.4chan.org/feedback', + target: '_blank', + textContent: '[complain]' + }); + $.add(errmsg, [$.tn(' '), link]); + } } }, addLabels: function() { @@ -11621,16 +11637,10 @@ var embed, href, key, link, name, options, post, ref, uid, value; key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post; href = link.href; - $.addClass(link, key.toLowerCase()); if (Embedding.types[key].httpOnly && location.protocol !== 'http:') { - embed = $.el('a', { - href: "http://boards.4chan.org/" + post.board + "/thread/" + post.thread + "#p" + post, - textContent: '(HTTP)', - title: key + " does not support HTTPS." - }); - $.after(link, [$.tn(' '), embed]); return; } + $.addClass(link, key.toLowerCase()); embed = $.el('a', { className: 'embedder', href: 'javascript:;', @@ -11691,6 +11701,7 @@ if (!(service = Embedding.types[key].title)) { return; } + $.addClass(link, key.toLowerCase()); if (service.batchSize) { (service.queue || (service.queue = [])).push(data); if (service.queue.length >= service.batchSize) { @@ -11877,13 +11888,11 @@ key: 'LiveLeak', regExp: /^\w+:\/\/(?:\w+\.)?liveleak\.com\/.*\?.*i=(\w+)/, httpOnly: true, + style: 'border: none; width: 640px; height: 360px;', el: function(a) { var el; el = $.el('iframe', { - width: "640", - height: "360", - src: "http://www.liveleak.com/ll_embed?i=" + a.dataset.uid, - frameborder: "0" + src: "http://www.liveleak.com/ll_embed?i=" + a.dataset.uid }); el.setAttribute("allowfullscreen", "true"); return el; @@ -11936,35 +11945,38 @@ }, { key: 'TwitchTV', regExp: /^\w+:\/\/(?:www\.)?twitch\.tv\/(\w[^#\&\?]*)/, - httpOnly: true, - style: "border: none; width: 640px; height: 360px;", + style: "border: none; width: 620px; height: 378px;", el: function(a) { - var _, channel, id, idparam, obj, result, type; - if (result = /(\w+)\/([bc])\/(\d+)/i.exec(a.dataset.uid)) { + var _, channel, flashvars, id, idprefix, k, len1, obj, part, ref, result, seconds, start, type; + if (result = /(\w+)\/([bcv])\/(\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' - }); - $.extend(obj, { - innerHTML: "" - }); - obj.children[1].value = "channel=" + channel + "&start_volume=25&auto_play=false&" + idparam[type] + "=" + id; - return obj; + idprefix = type === 'b' ? 'a' : type; + flashvars = "channel=" + channel + "&start_volume=25&auto_play=false&videoId=" + idprefix + id; + if (start = a.dataset.href.match(/\bt=(\w+)/)) { + seconds = 0; + ref = start[1].match(/\d+[hms]/g); + for (k = 0, len1 = ref.length; k < len1; k++) { + part = ref[k]; + seconds += +part.slice(0, -1) * { + 'h': 3600, + 'm': 60, + 's': 1 + }[part.slice(-1)]; + } + flashvars += "&initial_time=" + seconds; + } } else { channel = (/(\w+)/.exec(a.dataset.uid))[0]; - obj = $.el('object', { - data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=" + channel - }); - $.extend(obj, { - innerHTML: "" - }); - obj.children[1].value = "hostname=www.twitch.tv&channel=" + channel + "&auto_play=true&start_volume=25"; - return obj; + flashvars = "channel=" + channel + "&start_volume=25&auto_play=false"; } + obj = $.el('object', { + data: '//www-cdn.jtvnw.net/swflibs/TwitchPlayer.swf' + }); + $.extend(obj, { + innerHTML: "" + }); + obj.children[1].value = flashvars; + return obj; } }, { key: 'Vocaroo', @@ -11990,7 +12002,7 @@ }, title: { api: function(uid) { - return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + uid; + return "https://vimeo.com/api/oembed.json?url=https://vimeo.com/" + uid; }, text: function(_) { return _.title; @@ -12046,7 +12058,7 @@ } }, { key: 'Loopvid', - regExp: /^\w+:\/\/(?:www\.)?loopvid.appspot.com\/#?((?:pf|kd|lv|gd|gh|db|dx|nn|cp|wu|ig|ky|gc)\/[\w\-\/]+(,[\w\-\/]+)*|fc\/\w+\/\d+)/, + regExp: /^\w+:\/\/(?:www\.)?loopvid.appspot.com\/#?((?:pf|kd|lv|gd|gh|db|dx|nn|cp|wu|ig|ky|mf|pc|gc)\/[\w\-\/]+(,[\w\-\/]+)*|fc\/\w+\/\d+)/, style: 'max-width: 80vw; max-height: 80vh;', el: function(a) { var _, base, el, host, k, len1, len2, name, names, q, ref, ref1, type, types, url; @@ -12077,11 +12089,11 @@ url = (function() { switch (host) { case 'pf': - return "https://a.pomf.se/" + base; + return "https://web.archive.org/web/2/http://a.pomf.se/" + base; case 'kd': - return "http://2.kastden.org/loopvid/" + base; + return "http://kastden.org/loopvid/" + base; case 'lv': - return "http://loopvid.mooo.com/videos/" + base; + return "http://kastden.org/_loopvid_media/lv/" + base; case 'gd': return "https://docs.google.com/uc?export=download&id=" + base; case 'gh': @@ -12100,6 +12112,10 @@ return "https://i.imgur.com/" + base; case 'ky': return "https://kiyo.me/" + base; + case 'mf': + return "https://d.maxfile.ro/" + base; + case 'pc': + return "http://a.pomf.cat/" + base; case 'fc': return "//i.4cdn.org/" + base + ".webm"; case 'gc': @@ -12124,7 +12140,7 @@ preload: 'auto' }); type = el.canPlayType('audio/ogg') ? 'ogg' : 'mp3'; - el.src = "http://clyp.it/" + a.dataset.uid + "." + type; + el.src = "https://clyp.it/" + a.dataset.uid + "." + type; return el; } }, { @@ -12143,7 +12159,8 @@ return $.el('video', { controls: true, preload: 'auto', - src: a.dataset.href + src: a.dataset.href, + loop: /^https?:\/\/i\.4cdn\.org\//.test(a.dataset.href) }); } } @@ -12170,16 +12187,22 @@ return Embedding.init(); }, node: function() { - var k, len1, link, links; + var k, len1, len2, link, links, q, ref; if (this.isClone) { return Embedding.events(this); } if (!Linkify.regString.test(this.info.comment)) { return; } + ref = $$('a[href^="http://i.4cdn.org/"], a[href^="https://i.4cdn.org/"]', this.nodes.comment); + for (k = 0, len1 = ref.length; k < len1; k++) { + link = ref[k]; + $.addClass(link, 'linkify'); + Embedding.process(link, this); + } links = Linkify.process(this.nodes.comment); - for (k = 0, len1 = links.length; k < len1; k++) { - link = links[k]; + for (q = 0, len2 = links.length; q < len2; q++) { + link = links[q]; Embedding.process(link, this); } }, @@ -12190,9 +12213,9 @@ return Linkify.process(this.nodes.comment); }, process: function(node) { - var data, end, endNode, i, index, length, links, result, saved, snapshot, space, test, word; - test = /[^\s'"]+/g; - space = /[\s'"]/; + var data, end, endNode, i, index, length, links, ref, ref1, result, saved, snapshot, space, test, word; + test = /[^\s"]+/g; + space = /[\s"]/; snapshot = $.X('.//br|.//text()', node); i = 0; links = []; @@ -12209,7 +12232,11 @@ test.lastIndex = 0; while ((saved = snapshot.snapshotItem(i++))) { if (saved.nodeName === 'BR') { - break; + if (/^(https?:\/\/)?[a-z0-9\-\.]+$/i.test(word) && ((ref = snapshot.snapshotItem(i)) != null ? (ref1 = ref.data) != null ? ref1.match(/^(\.[a-z0-9\-]+)*\//i) : void 0 : void 0)) { + continue; + } else { + break; + } } endNode = saved; data = saved.data; @@ -12238,7 +12265,7 @@ } return links; }, - regString: /((https?|mailto|git|magnet|ftp|irc):([a-z\d%\/?])|([-a-z\d]+[.])+(aero|asia|biz|cat|com|coop|dance|info|int|jobs|mobi|moe|museum|name|net|org|post|pro|tel|travel|xxx|xyz|edu|gov|mil|[a-z]{2})([:\/]|(?![^\s'"]))|[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}|[-\w\d.@]+@[a-z\d.-]+\.[a-z\d])/i, + regString: /((https?|mailto|git|magnet|ftp|irc):([a-z\d%\/?])|([-a-z\d]+[.])+(aero|asia|biz|cat|com|coop|dance|info|int|jobs|mobi|moe|museum|name|net|org|post|pro|tel|travel|xxx|xyz|edu|gov|mil|[a-z]{2})([:\/]|(?![^\s"]))|[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}|[-\w\d.@]+@[a-z\d.-]+\.[a-z\d])/i, makeRange: function(startNode, endNode, startOffset, endOffset) { var range; range = document.createRange(); @@ -12247,7 +12274,7 @@ return range; }, makeLink: function(range) { - var a, i, t, text; + var a, encodedDomain, i, t, text; text = range.toString(); i = text.search(Linkify.regString); if (i > 0) { @@ -12278,6 +12305,15 @@ if (!/((mailto|magnet):|.+:\/\/)/.test(text)) { text = (/@/.test(text) ? 'mailto:' : 'http://') + text; } + if (encodedDomain = text.match(/^(https?:\/\/[^\/]*%[0-9a-f]{2})(.*)$/i)) { + text = encodedDomain[1].replace(/%([0-9a-f]{2})/ig, function(x, y) { + if (y === '25') { + return x; + } else { + return String.fromCharCode(parseInt(y, 16)); + } + }) + encodedDomain[2]; + } a = $.el('a', { className: 'linkify', rel: 'nofollow noreferrer', @@ -14814,7 +14850,7 @@ ref = $$(selector); for (k = 0, len1 = ref.length; k < len1; k++) { link = ref[k]; - switch (link.pathname) { + switch (link.pathname.replace(/\/+/g, '/')) { case "/" + g.BOARD + "/": if (Conf['JSON Navigation']) { link.textContent = 'Index'; @@ -14881,7 +14917,7 @@ ref = $$('a:not([data-only])', Header.boardList).concat($$('a', Header.bottomBoardList)); for (k = 0, len1 = ref.length; k < len1; k++) { a = ref[k]; - if (((ref1 = a.hostname) !== 'boards.4chan.org' && ref1 !== 'catalog.neet.tv' && ref1 !== '4index.gropes.us') || !(board = a.pathname.split('/')[1]) || (board === 'f' || board === 'status' || board === '4chan') || a.pathname.split('/')[2] === 'archive' || $.hasClass(a, 'external')) { + if (((ref1 = a.hostname) !== 'boards.4chan.org' && ref1 !== 'catalog.neet.tv') || !(board = a.pathname.split('/')[1]) || (board === 'f' || board === 'status' || board === '4chan') || a.pathname.split('/')[2] === 'archive' || $.hasClass(a, 'external')) { continue; } a.href = useCatalog ? CatalogLinks.catalog(board) : "/" + board + "/"; @@ -14894,7 +14930,7 @@ board = g.BOARD.ID; } if (Conf['External Catalog'] && (board === 'a' || board === 'c' || board === 'g' || board === 'biz' || board === 'k' || board === 'm' || board === 'o' || board === 'p' || board === 'v' || board === 'vg' || board === 'vr' || board === 'w' || board === 'wg' || board === 'cm' || board === '3' || board === 'adv' || board === 'an' || board === 'asp' || board === 'cgl' || board === 'ck' || board === 'co' || board === 'diy' || board === 'fa' || board === 'fit' || board === 'gd' || board === 'int' || board === 'jp' || board === 'lit' || board === 'mlp' || board === 'mu' || board === 'n' || board === 'out' || board === 'po' || board === 'sci' || board === 'sp' || board === 'tg' || board === 'toy' || board === 'trv' || board === 'tv' || board === 'vp' || board === 'wsg' || board === 'x' || board === 'f' || board === 'pol' || board === 's4s' || board === 'lgbt')) { - return "http://catalog.neet.tv/" + board; + return "http://catalog.neet.tv/" + board + "/"; } else if (Conf['JSON Navigation'] && Conf['Use 4chan X Catalog']) { if (g.BOARD.ID === board && g.VIEW === 'index') { return '#catalog'; @@ -14985,7 +15021,7 @@ return; } a.textContent = "Post No." + post + " Loading..."; - return $.cache("//a.4cdn.org" + (a.pathname.split('/').splice(0, 4).join('/')) + ".json", function() { + return $.cache("//a.4cdn.org" + (a.pathname.split(/\/+/).splice(0, 4).join('/')) + ".json", function() { return ExpandComment.parse(this, a, post); }); }, @@ -15031,9 +15067,9 @@ continue; } if (href[0] === '#') { - quote.href = "" + (a.pathname.split('/').splice(0, 4).join('/')) + href; + quote.href = "" + (a.pathname.split(/\/+/).splice(0, 4).join('/')) + href; } else { - quote.href = (a.pathname.split('/').splice(0, 3).join('/')) + "/" + href; + quote.href = (a.pathname.split(/\/+/).splice(0, 3).join('/')) + "/" + href; } } post.nodes.shortComment = comment; @@ -16886,7 +16922,7 @@ return $.on(ta, 'change', $.cb.value); }, advanced: function(section) { - var aa, applyCSS, archBoards, archive, boardID, boardOptions, boardSelect, boards, customCSS, files, i, input, inputs, interval, item, items, k, len1, len2, len3, len4, len5, len6, len7, name, o, q, ref, ref1, ref2, ref3, ref4, ref5, ref6, row, rows, software, ta, table, u, uid, v, warning, withCredentials, y, z; + var aa, ab, applyCSS, archBoards, archive, boardID, boardOptions, boardSelect, boards, customCSS, files, i, input, inputs, interval, item, items, k, len1, len2, len3, len4, len5, len6, len7, name, o, q, ref, ref1, ref2, ref3, ref4, ref5, ref6, row, rows, software, ta, table, u, uid, v, warning, withCredentials, z; $.extend(section, { innerHTML: "
Archiver
404 Redirect is disabled.
Thread redirectionPost fetchingFile redirection
Captcha Language
Choose from list of language codes. Leave blank to autoselect.
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
Archive link: g-archive
Internal archive link: g-expired
Title link: g-title
Board link (Replace with title when on that board): g-replace
Full text link: g-full
Custom text link: g-text:"Install Gentoo"
Index-only link: g-index
Catalog-only link: g-catalog
External link: external-text:"Google","http://www.google.com"
Combinations are possible: g-index-text:"Technology Index"
Full board list toggle: toggle-all

[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:"Piracy"]
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
Literal %: %%
Quote Backlinks formatting is disabled.
:
File Info Formatting is disabled.
:
Link: %l (truncated), %L (untruncated), %T (4chan filename)
Filename: %n (truncated), %N (untruncated), %t (4chan filename)
Spoiler indicator: %p
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
Resolution: %r (Displays 'PDF' for PDF files)
Tag: %g
Literal %: %%
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.
Thread Updater is disabled.
Interval: seconds
Custom Cooldown Time
Seconds:
" }); @@ -16966,8 +17002,8 @@ for (boardID in archBoards) { o = archBoards[boardID]; ref4 = ['thread', 'post', 'file']; - for (y = 0, len5 = ref4.length; y < len5; y++) { - item = ref4[y]; + for (z = 0, len5 = ref4.length; z < len5; z++) { + item = ref4[z]; i = o[item][0].length ? 1 : 0; o[item][i].push([null, 'disabled']); o[item] = o[item][0].concat(o[item][1]); @@ -16976,8 +17012,8 @@ rows = []; boardOptions = []; ref5 = Object.keys(archBoards).sort(); - for (z = 0, len6 = ref5.length; z < len6; z++) { - boardID = ref5[z]; + for (aa = 0, len6 = ref5.length; aa < len6; aa++) { + boardID = ref5[aa]; row = $.el('tr', { className: "board-" + boardID }); @@ -16989,8 +17025,8 @@ })); o = archBoards[boardID]; ref6 = ['thread', 'post', 'file']; - for (aa = 0, len7 = ref6.length; aa < len7; aa++) { - item = ref6[aa]; + for (ab = 0, len7 = ref6.length; ab < len7; ab++) { + item = ref6[ab]; $.add(row, Settings.addArchiveCell(boardID, o, item)); } rows.push(row); @@ -17197,7 +17233,7 @@ } g.threads = new SimpleDict(); g.posts = new SimpleDict(); - pathname = location.pathname.split('/'); + pathname = location.pathname.split(/\/+/); g.BOARD = new Board(pathname[1]); if ((ref = g.BOARD.ID) === 'z' || ref === 'fk') { return; @@ -17331,7 +17367,7 @@ }), function() { var pathname, ref1, video; if (Conf['404 Redirect'] && ((ref1 = d.title) === '4chan - Temporarily Offline' || ref1 === '4chan - 404 Not Found')) { - pathname = location.pathname.split('/'); + pathname = location.pathname.split(/\/+/); return Redirect.navigate('file', { boardID: g.BOARD.ID, filename: pathname[pathname.length - 1] @@ -17350,11 +17386,19 @@ }); return; } - if (Conf['Normalize URL'] && g.VIEW === 'thread') { - pathname = location.pathname.split('/'); - if (pathname[2] !== 'thread' || pathname.length > 4) { - pathname[2] = 'thread'; - history.replaceState(null, '', pathname.slice(0, 4).join('/') + location.hash); + if (Conf['Normalize URL']) { + pathname = location.pathname.split(/\/+/); + switch (g.VIEW) { + case 'thread': + pathname[2] = 'thread'; + pathname = pathname.slice(0, 4); + break; + case 'index': + pathname = pathname.slice(0, 3); + } + pathname = pathname.join('/'); + if (location.pathname !== pathname) { + history.replaceState(history.state, '', location.protocol + "//" + location.host + pathname + location.hash); } } ref1 = Main.features; diff --git a/builds/4chan-X.crx b/builds/4chan-X.crx index 88226a992..1ea3c54d8 100644 Binary files a/builds/4chan-X.crx and b/builds/4chan-X.crx differ diff --git a/builds/4chan-X.meta.js b/builds/4chan-X.meta.js index 60d66138c..02d8e025d 100644 --- a/builds/4chan-X.meta.js +++ b/builds/4chan-X.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.11.11.5 +// @version 1.11.12.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 1c966fe6f..f938b320d 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -1,7 +1,7 @@ // Generated by CoffeeScript // ==UserScript== // @name 4chan X -// @version 1.11.11.5 +// @version 1.11.12.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -413,7 +413,7 @@ doc = d.documentElement; g = { - VERSION: '1.11.11.5', + VERSION: '1.11.12.0', NAMESPACE: '4chan X.', boards: {} }; @@ -1475,7 +1475,7 @@ Post.prototype.parseQuote = function(quotelink) { var fullID, match; - if (!(match = quotelink.href.match(/boards\.4chan\.org\/([^\/]+)\/(?:res|thread)\/\d+(?:\/[^#]*)?#p(\d+)$/))) { + if (!(match = quotelink.href.match(/^https?:\/\/boards\.4chan\.org\/+([^\/]+)\/+(?:res|thread)\/+\d+(?:\/[^#]*)?#p(\d+)$/))) { return; } this.nodes.quotelinks.push(quotelink); @@ -3508,7 +3508,7 @@ return; } e.preventDefault(); - return Index.userPageNav(+a.pathname.split('/')[2] || 1); + return Index.userPageNav(+a.pathname.split(/\/+/)[2] || 1); }, refreshFront: function() { return Index.update(Index.pushState({ @@ -3525,7 +3525,7 @@ if ((ref = Conf['Index Mode']) === 'all pages' || ref === 'catalog') { return 1; } else { - return +window.location.pathname.split('/')[2] || 1; + return +window.location.pathname.split(/\/+/)[2] || 1; } }, userPageNav: function(page) { @@ -3594,7 +3594,7 @@ mode: Conf['Index Mode'], searched: Index.search, oldpage: pageBeforeSearch - }, '', pathname + hash); + }, '', location.protocol + "//" + location.host + pathname + hash); return state; }, saveMode: function(mode) { @@ -4458,7 +4458,7 @@ postFromRoot: function(root) { var boardID, index, link, post, postID; link = $('.postNum > a[href*="#"]', root); - boardID = link.pathname.split('/')[1]; + boardID = link.pathname.split(/\/+/)[1]; postID = link.hash.slice(2); index = root.dataset.clone; post = g.posts[boardID + "." + postID]; @@ -4477,7 +4477,7 @@ postDataFromLink: function(link) { var boardID, path, postID, ref, threadID; if (link.hostname === 'boards.4chan.org') { - path = link.pathname.split('/'); + path = link.pathname.split(/\/+/); boardID = path[1]; threadID = path[3]; postID = link.hash.slice(2); @@ -7147,7 +7147,7 @@ return status.disabled = disabled || false; }, quote: function(e) { - var ancestor, caretPos, com, frag, index, insideCode, k, len1, len2, len3, len4, len5, len6, node, post, q, range, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, sel, text, thread, u, v, y, z; + var aa, ancestor, caretPos, com, frag, index, insideCode, k, len1, len2, len3, len4, len5, len6, node, post, q, range, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, sel, text, thread, u, v, z; if (e != null) { e.preventDefault(); } @@ -7192,13 +7192,13 @@ $.replace(node, [$.tn('[code]')].concat(slice.call(node.childNodes), [$.tn('[/code]')])); } ref4 = $$('.linkify[data-original]', frag); - for (y = 0, len5 = ref4.length; y < len5; y++) { - node = ref4[y]; + for (z = 0, len5 = ref4.length; z < len5; z++) { + node = ref4[z]; $.replace(node, $.tn(node.dataset.original)); } ref5 = $$('.embedder', frag); - for (z = 0, len6 = ref5.length; z < len6; z++) { - node = ref5[z]; + for (aa = 0, len6 = ref5.length; aa < len6; aa++) { + node = ref5[aa]; if (((ref6 = node.previousSibling) != null ? ref6.nodeValue : void 0) === ' ') { $.rm(node.previousSibling); } @@ -7880,7 +7880,23 @@ img.tabIndex = 0; } if (this.images.length === 9) { - return this.addTooltips(this.images); + this.addTooltips(this.images); + } + return this.complaintLinks(); + }, + complaintLinks: function() { + var errmsg, k, len1, link, ref; + ref = $$('.rc-imageselect-incorrect-response, .rc-imageselect-error-select-one, .rc-imageselect-error-select-more'); + for (k = 0, len1 = ref.length; k < len1; k++) { + errmsg = ref[k]; + if (!$('a', errmsg)) { + link = $.el('a', { + href: 'https://www.4chan.org/feedback', + target: '_blank', + textContent: '[complain]' + }); + $.add(errmsg, [$.tn(' '), link]); + } } }, addLabels: function() { @@ -11621,16 +11637,10 @@ var embed, href, key, link, name, options, post, ref, uid, value; key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post; href = link.href; - $.addClass(link, key.toLowerCase()); if (Embedding.types[key].httpOnly && location.protocol !== 'http:') { - embed = $.el('a', { - href: "http://boards.4chan.org/" + post.board + "/thread/" + post.thread + "#p" + post, - textContent: '(HTTP)', - title: key + " does not support HTTPS." - }); - $.after(link, [$.tn(' '), embed]); return; } + $.addClass(link, key.toLowerCase()); embed = $.el('a', { className: 'embedder', href: 'javascript:;', @@ -11691,6 +11701,7 @@ if (!(service = Embedding.types[key].title)) { return; } + $.addClass(link, key.toLowerCase()); if (service.batchSize) { (service.queue || (service.queue = [])).push(data); if (service.queue.length >= service.batchSize) { @@ -11877,13 +11888,11 @@ key: 'LiveLeak', regExp: /^\w+:\/\/(?:\w+\.)?liveleak\.com\/.*\?.*i=(\w+)/, httpOnly: true, + style: 'border: none; width: 640px; height: 360px;', el: function(a) { var el; el = $.el('iframe', { - width: "640", - height: "360", - src: "http://www.liveleak.com/ll_embed?i=" + a.dataset.uid, - frameborder: "0" + src: "http://www.liveleak.com/ll_embed?i=" + a.dataset.uid }); el.setAttribute("allowfullscreen", "true"); return el; @@ -11936,35 +11945,38 @@ }, { key: 'TwitchTV', regExp: /^\w+:\/\/(?:www\.)?twitch\.tv\/(\w[^#\&\?]*)/, - httpOnly: true, - style: "border: none; width: 640px; height: 360px;", + style: "border: none; width: 620px; height: 378px;", el: function(a) { - var _, channel, id, idparam, obj, result, type; - if (result = /(\w+)\/([bc])\/(\d+)/i.exec(a.dataset.uid)) { + var _, channel, flashvars, id, idprefix, k, len1, obj, part, ref, result, seconds, start, type; + if (result = /(\w+)\/([bcv])\/(\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' - }); - $.extend(obj, { - innerHTML: "" - }); - obj.children[1].value = "channel=" + channel + "&start_volume=25&auto_play=false&" + idparam[type] + "=" + id; - return obj; + idprefix = type === 'b' ? 'a' : type; + flashvars = "channel=" + channel + "&start_volume=25&auto_play=false&videoId=" + idprefix + id; + if (start = a.dataset.href.match(/\bt=(\w+)/)) { + seconds = 0; + ref = start[1].match(/\d+[hms]/g); + for (k = 0, len1 = ref.length; k < len1; k++) { + part = ref[k]; + seconds += +part.slice(0, -1) * { + 'h': 3600, + 'm': 60, + 's': 1 + }[part.slice(-1)]; + } + flashvars += "&initial_time=" + seconds; + } } else { channel = (/(\w+)/.exec(a.dataset.uid))[0]; - obj = $.el('object', { - data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=" + channel - }); - $.extend(obj, { - innerHTML: "" - }); - obj.children[1].value = "hostname=www.twitch.tv&channel=" + channel + "&auto_play=true&start_volume=25"; - return obj; + flashvars = "channel=" + channel + "&start_volume=25&auto_play=false"; } + obj = $.el('object', { + data: '//www-cdn.jtvnw.net/swflibs/TwitchPlayer.swf' + }); + $.extend(obj, { + innerHTML: "" + }); + obj.children[1].value = flashvars; + return obj; } }, { key: 'Vocaroo', @@ -11990,7 +12002,7 @@ }, title: { api: function(uid) { - return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + uid; + return "https://vimeo.com/api/oembed.json?url=https://vimeo.com/" + uid; }, text: function(_) { return _.title; @@ -12046,7 +12058,7 @@ } }, { key: 'Loopvid', - regExp: /^\w+:\/\/(?:www\.)?loopvid.appspot.com\/#?((?:pf|kd|lv|gd|gh|db|dx|nn|cp|wu|ig|ky|gc)\/[\w\-\/]+(,[\w\-\/]+)*|fc\/\w+\/\d+)/, + regExp: /^\w+:\/\/(?:www\.)?loopvid.appspot.com\/#?((?:pf|kd|lv|gd|gh|db|dx|nn|cp|wu|ig|ky|mf|pc|gc)\/[\w\-\/]+(,[\w\-\/]+)*|fc\/\w+\/\d+)/, style: 'max-width: 80vw; max-height: 80vh;', el: function(a) { var _, base, el, host, k, len1, len2, name, names, q, ref, ref1, type, types, url; @@ -12077,11 +12089,11 @@ url = (function() { switch (host) { case 'pf': - return "https://a.pomf.se/" + base; + return "https://web.archive.org/web/2/http://a.pomf.se/" + base; case 'kd': - return "http://2.kastden.org/loopvid/" + base; + return "http://kastden.org/loopvid/" + base; case 'lv': - return "http://loopvid.mooo.com/videos/" + base; + return "http://kastden.org/_loopvid_media/lv/" + base; case 'gd': return "https://docs.google.com/uc?export=download&id=" + base; case 'gh': @@ -12100,6 +12112,10 @@ return "https://i.imgur.com/" + base; case 'ky': return "https://kiyo.me/" + base; + case 'mf': + return "https://d.maxfile.ro/" + base; + case 'pc': + return "http://a.pomf.cat/" + base; case 'fc': return "//i.4cdn.org/" + base + ".webm"; case 'gc': @@ -12124,7 +12140,7 @@ preload: 'auto' }); type = el.canPlayType('audio/ogg') ? 'ogg' : 'mp3'; - el.src = "http://clyp.it/" + a.dataset.uid + "." + type; + el.src = "https://clyp.it/" + a.dataset.uid + "." + type; return el; } }, { @@ -12143,7 +12159,8 @@ return $.el('video', { controls: true, preload: 'auto', - src: a.dataset.href + src: a.dataset.href, + loop: /^https?:\/\/i\.4cdn\.org\//.test(a.dataset.href) }); } } @@ -12170,16 +12187,22 @@ return Embedding.init(); }, node: function() { - var k, len1, link, links; + var k, len1, len2, link, links, q, ref; if (this.isClone) { return Embedding.events(this); } if (!Linkify.regString.test(this.info.comment)) { return; } + ref = $$('a[href^="http://i.4cdn.org/"], a[href^="https://i.4cdn.org/"]', this.nodes.comment); + for (k = 0, len1 = ref.length; k < len1; k++) { + link = ref[k]; + $.addClass(link, 'linkify'); + Embedding.process(link, this); + } links = Linkify.process(this.nodes.comment); - for (k = 0, len1 = links.length; k < len1; k++) { - link = links[k]; + for (q = 0, len2 = links.length; q < len2; q++) { + link = links[q]; Embedding.process(link, this); } }, @@ -12190,9 +12213,9 @@ return Linkify.process(this.nodes.comment); }, process: function(node) { - var data, end, endNode, i, index, length, links, result, saved, snapshot, space, test, word; - test = /[^\s'"]+/g; - space = /[\s'"]/; + var data, end, endNode, i, index, length, links, ref, ref1, result, saved, snapshot, space, test, word; + test = /[^\s"]+/g; + space = /[\s"]/; snapshot = $.X('.//br|.//text()', node); i = 0; links = []; @@ -12209,7 +12232,11 @@ test.lastIndex = 0; while ((saved = snapshot.snapshotItem(i++))) { if (saved.nodeName === 'BR') { - break; + if (/^(https?:\/\/)?[a-z0-9\-\.]+$/i.test(word) && ((ref = snapshot.snapshotItem(i)) != null ? (ref1 = ref.data) != null ? ref1.match(/^(\.[a-z0-9\-]+)*\//i) : void 0 : void 0)) { + continue; + } else { + break; + } } endNode = saved; data = saved.data; @@ -12238,7 +12265,7 @@ } return links; }, - regString: /((https?|mailto|git|magnet|ftp|irc):([a-z\d%\/?])|([-a-z\d]+[.])+(aero|asia|biz|cat|com|coop|dance|info|int|jobs|mobi|moe|museum|name|net|org|post|pro|tel|travel|xxx|xyz|edu|gov|mil|[a-z]{2})([:\/]|(?![^\s'"]))|[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}|[-\w\d.@]+@[a-z\d.-]+\.[a-z\d])/i, + regString: /((https?|mailto|git|magnet|ftp|irc):([a-z\d%\/?])|([-a-z\d]+[.])+(aero|asia|biz|cat|com|coop|dance|info|int|jobs|mobi|moe|museum|name|net|org|post|pro|tel|travel|xxx|xyz|edu|gov|mil|[a-z]{2})([:\/]|(?![^\s"]))|[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}|[-\w\d.@]+@[a-z\d.-]+\.[a-z\d])/i, makeRange: function(startNode, endNode, startOffset, endOffset) { var range; range = document.createRange(); @@ -12247,7 +12274,7 @@ return range; }, makeLink: function(range) { - var a, i, t, text; + var a, encodedDomain, i, t, text; text = range.toString(); i = text.search(Linkify.regString); if (i > 0) { @@ -12278,6 +12305,15 @@ if (!/((mailto|magnet):|.+:\/\/)/.test(text)) { text = (/@/.test(text) ? 'mailto:' : 'http://') + text; } + if (encodedDomain = text.match(/^(https?:\/\/[^\/]*%[0-9a-f]{2})(.*)$/i)) { + text = encodedDomain[1].replace(/%([0-9a-f]{2})/ig, function(x, y) { + if (y === '25') { + return x; + } else { + return String.fromCharCode(parseInt(y, 16)); + } + }) + encodedDomain[2]; + } a = $.el('a', { className: 'linkify', rel: 'nofollow noreferrer', @@ -14814,7 +14850,7 @@ ref = $$(selector); for (k = 0, len1 = ref.length; k < len1; k++) { link = ref[k]; - switch (link.pathname) { + switch (link.pathname.replace(/\/+/g, '/')) { case "/" + g.BOARD + "/": if (Conf['JSON Navigation']) { link.textContent = 'Index'; @@ -14881,7 +14917,7 @@ ref = $$('a:not([data-only])', Header.boardList).concat($$('a', Header.bottomBoardList)); for (k = 0, len1 = ref.length; k < len1; k++) { a = ref[k]; - if (((ref1 = a.hostname) !== 'boards.4chan.org' && ref1 !== 'catalog.neet.tv' && ref1 !== '4index.gropes.us') || !(board = a.pathname.split('/')[1]) || (board === 'f' || board === 'status' || board === '4chan') || a.pathname.split('/')[2] === 'archive' || $.hasClass(a, 'external')) { + if (((ref1 = a.hostname) !== 'boards.4chan.org' && ref1 !== 'catalog.neet.tv') || !(board = a.pathname.split('/')[1]) || (board === 'f' || board === 'status' || board === '4chan') || a.pathname.split('/')[2] === 'archive' || $.hasClass(a, 'external')) { continue; } a.href = useCatalog ? CatalogLinks.catalog(board) : "/" + board + "/"; @@ -14894,7 +14930,7 @@ board = g.BOARD.ID; } if (Conf['External Catalog'] && (board === 'a' || board === 'c' || board === 'g' || board === 'biz' || board === 'k' || board === 'm' || board === 'o' || board === 'p' || board === 'v' || board === 'vg' || board === 'vr' || board === 'w' || board === 'wg' || board === 'cm' || board === '3' || board === 'adv' || board === 'an' || board === 'asp' || board === 'cgl' || board === 'ck' || board === 'co' || board === 'diy' || board === 'fa' || board === 'fit' || board === 'gd' || board === 'int' || board === 'jp' || board === 'lit' || board === 'mlp' || board === 'mu' || board === 'n' || board === 'out' || board === 'po' || board === 'sci' || board === 'sp' || board === 'tg' || board === 'toy' || board === 'trv' || board === 'tv' || board === 'vp' || board === 'wsg' || board === 'x' || board === 'f' || board === 'pol' || board === 's4s' || board === 'lgbt')) { - return "http://catalog.neet.tv/" + board; + return "http://catalog.neet.tv/" + board + "/"; } else if (Conf['JSON Navigation'] && Conf['Use 4chan X Catalog']) { if (g.BOARD.ID === board && g.VIEW === 'index') { return '#catalog'; @@ -14985,7 +15021,7 @@ return; } a.textContent = "Post No." + post + " Loading..."; - return $.cache("//a.4cdn.org" + (a.pathname.split('/').splice(0, 4).join('/')) + ".json", function() { + return $.cache("//a.4cdn.org" + (a.pathname.split(/\/+/).splice(0, 4).join('/')) + ".json", function() { return ExpandComment.parse(this, a, post); }); }, @@ -15031,9 +15067,9 @@ continue; } if (href[0] === '#') { - quote.href = "" + (a.pathname.split('/').splice(0, 4).join('/')) + href; + quote.href = "" + (a.pathname.split(/\/+/).splice(0, 4).join('/')) + href; } else { - quote.href = (a.pathname.split('/').splice(0, 3).join('/')) + "/" + href; + quote.href = (a.pathname.split(/\/+/).splice(0, 3).join('/')) + "/" + href; } } post.nodes.shortComment = comment; @@ -16886,7 +16922,7 @@ return $.on(ta, 'change', $.cb.value); }, advanced: function(section) { - var aa, applyCSS, archBoards, archive, boardID, boardOptions, boardSelect, boards, customCSS, files, i, input, inputs, interval, item, items, k, len1, len2, len3, len4, len5, len6, len7, name, o, q, ref, ref1, ref2, ref3, ref4, ref5, ref6, row, rows, software, ta, table, u, uid, v, warning, withCredentials, y, z; + var aa, ab, applyCSS, archBoards, archive, boardID, boardOptions, boardSelect, boards, customCSS, files, i, input, inputs, interval, item, items, k, len1, len2, len3, len4, len5, len6, len7, name, o, q, ref, ref1, ref2, ref3, ref4, ref5, ref6, row, rows, software, ta, table, u, uid, v, warning, withCredentials, z; $.extend(section, { innerHTML: "
Archiver
404 Redirect is disabled.
Thread redirectionPost fetchingFile redirection
Captcha Language
Choose from list of language codes. Leave blank to autoselect.
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
Archive link: g-archive
Internal archive link: g-expired
Title link: g-title
Board link (Replace with title when on that board): g-replace
Full text link: g-full
Custom text link: g-text:"Install Gentoo"
Index-only link: g-index
Catalog-only link: g-catalog
External link: external-text:"Google","http://www.google.com"
Combinations are possible: g-index-text:"Technology Index"
Full board list toggle: toggle-all

[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:"Piracy"]
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
Literal %: %%
Quote Backlinks formatting is disabled.
:
File Info Formatting is disabled.
:
Link: %l (truncated), %L (untruncated), %T (4chan filename)
Filename: %n (truncated), %N (untruncated), %t (4chan filename)
Spoiler indicator: %p
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
Resolution: %r (Displays 'PDF' for PDF files)
Tag: %g
Literal %: %%
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.
Thread Updater is disabled.
Interval: seconds
Custom Cooldown Time
Seconds:
" }); @@ -16966,8 +17002,8 @@ for (boardID in archBoards) { o = archBoards[boardID]; ref4 = ['thread', 'post', 'file']; - for (y = 0, len5 = ref4.length; y < len5; y++) { - item = ref4[y]; + for (z = 0, len5 = ref4.length; z < len5; z++) { + item = ref4[z]; i = o[item][0].length ? 1 : 0; o[item][i].push([null, 'disabled']); o[item] = o[item][0].concat(o[item][1]); @@ -16976,8 +17012,8 @@ rows = []; boardOptions = []; ref5 = Object.keys(archBoards).sort(); - for (z = 0, len6 = ref5.length; z < len6; z++) { - boardID = ref5[z]; + for (aa = 0, len6 = ref5.length; aa < len6; aa++) { + boardID = ref5[aa]; row = $.el('tr', { className: "board-" + boardID }); @@ -16989,8 +17025,8 @@ })); o = archBoards[boardID]; ref6 = ['thread', 'post', 'file']; - for (aa = 0, len7 = ref6.length; aa < len7; aa++) { - item = ref6[aa]; + for (ab = 0, len7 = ref6.length; ab < len7; ab++) { + item = ref6[ab]; $.add(row, Settings.addArchiveCell(boardID, o, item)); } rows.push(row); @@ -17197,7 +17233,7 @@ } g.threads = new SimpleDict(); g.posts = new SimpleDict(); - pathname = location.pathname.split('/'); + pathname = location.pathname.split(/\/+/); g.BOARD = new Board(pathname[1]); if ((ref = g.BOARD.ID) === 'z' || ref === 'fk') { return; @@ -17331,7 +17367,7 @@ }), function() { var pathname, ref1, video; if (Conf['404 Redirect'] && ((ref1 = d.title) === '4chan - Temporarily Offline' || ref1 === '4chan - 404 Not Found')) { - pathname = location.pathname.split('/'); + pathname = location.pathname.split(/\/+/); return Redirect.navigate('file', { boardID: g.BOARD.ID, filename: pathname[pathname.length - 1] @@ -17350,11 +17386,19 @@ }); return; } - if (Conf['Normalize URL'] && g.VIEW === 'thread') { - pathname = location.pathname.split('/'); - if (pathname[2] !== 'thread' || pathname.length > 4) { - pathname[2] = 'thread'; - history.replaceState(null, '', pathname.slice(0, 4).join('/') + location.hash); + if (Conf['Normalize URL']) { + pathname = location.pathname.split(/\/+/); + switch (g.VIEW) { + case 'thread': + pathname[2] = 'thread'; + pathname = pathname.slice(0, 4); + break; + case 'index': + pathname = pathname.slice(0, 3); + } + pathname = pathname.join('/'); + if (location.pathname !== pathname) { + history.replaceState(history.state, '', location.protocol + "//" + location.host + pathname + location.hash); } } ref1 = Main.features; diff --git a/builds/4chan-X.zip b/builds/4chan-X.zip index 09bf20381..cc84ce63f 100644 Binary files a/builds/4chan-X.zip and b/builds/4chan-X.zip differ diff --git a/builds/updates-beta.xml b/builds/updates-beta.xml index 098df14e7..f96c81115 100644 --- a/builds/updates-beta.xml +++ b/builds/updates-beta.xml @@ -1,7 +1,7 @@ - + diff --git a/builds/updates.xml b/builds/updates.xml index 5c91f1947..4ff8eb444 100644 --- a/builds/updates.xml +++ b/builds/updates.xml @@ -1,7 +1,7 @@ - + diff --git a/package.json b/package.json index c2fb2fcd8..493531eb6 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,8 @@ "meta": { "name": "4chan X", "fork": "ccd0", - "version": "1.11.11.5", - "date": "2015-10-03T18:58:44.123Z", + "version": "1.11.12.0", + "date": "2015-10-05T00:29:15.918Z", "page": "https://www.4chan-x.net/", "downloads": "https://www.4chan-x.net/builds/", "oldVersions": "https://raw.githubusercontent.com/ccd0/4chan-x/",