diff --git a/CHANGELOG.md b/CHANGELOG.md index f52fb804a..bba4a6e5a 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ Sometimes the changelog has notes (not comprehensive) acknowledging people's wor The links to individual versions below are to copies of the script with the update URL removed. If you want automatic updates, install the script from the links on the [main page](https://github.com/ccd0/4chan-x). +### v1.10.7 + +**v1.10.7.0** *(2015-03-29)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.7.0/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.7.0/builds/4chan-X-noupdate.crx "Chromium version")] +- Based on v1.10.6.7. +- Fix excessive loading of thumbnails in index. +- Refactoring (of HTML generation code) and minor bugfixes. + ### v1.10.6 **v1.10.6.7** *(2015-03-26)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.6.7/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.6.7/builds/4chan-X-noupdate.crx "Chromium version")] diff --git a/builds/4chan-X-beta.crx b/builds/4chan-X-beta.crx index 880b34143..989a7af03 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 4ecbcb8fa..e3b85be55 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.10.6.7 +// @version 1.10.7.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 fb94b8f3e..7732135db 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.10.6.7 +// @version 1.10.7.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -395,11 +395,8 @@ doc = d.documentElement; g = { - VERSION: '1.10.6.7', + VERSION: '1.10.7.0', NAMESPACE: '4chan X.', - NAME: '4chan X', - FAQ: 'https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions', - CHANGELOG: 'https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md', boards: {} }; @@ -422,6 +419,16 @@ }; })(); + E.cat = function(templates) { + var html, k, len1, x; + html = ''; + for (k = 0, len1 = templates.length; k < len1; k++) { + x = templates[k]; + html += x.innerHTML; + } + return html; + }; + $ = function(selector, root) { if (root == null) { root = d.body; @@ -486,7 +493,7 @@ } blockedURLs[url] = true; message = $.el('div', { - innerHTML: E(g.NAME) + " was blocked from loading the following URL:

[More info]" + innerHTML: "4chan X was blocked from loading the following URL:

[More info]" }); $('span', message).textContent = (/^\/\//.test(url) ? location.protocol : '') + url; return new Notice('error', message, 30, function() { @@ -1348,7 +1355,7 @@ if (!(fileEl = $('.file', this.nodes.post))) { return; } - if (!(link = $('.fileText > a', fileEl))) { + if (!(link = $('.fileText > a, .fileText-original > a', fileEl))) { return; } if (!(info = (ref = link.nextSibling) != null ? ref.textContent.match(/\(([\d.]+ [KMG]?B).*\)/) : void 0)) { @@ -1371,7 +1378,7 @@ size *= 1024; } this.file.sizeInBytes = size; - if ((thumb = $('img[data-md5]', fileEl))) { + if ((thumb = $('.fileThumb > [data-md5]', fileEl))) { return $.extend(this.file, { thumb: thumb, thumbURL: location.protocol + "//i.4cdn.org/" + this.board + "/" + (link.href.match(/(\d+)\./)[1]) + "s.jpg", @@ -1484,7 +1491,7 @@ extend(Clone, superClass); function Clone(origin1, context1, contractThumb) { - var file, info, inline, inlined, k, key, len1, len2, len3, nodes, post, q, ref, ref1, ref2, ref3, root, u, val; + var file, info, inline, inlined, k, key, len1, len2, len3, nodes, post, q, ref, ref1, ref2, ref3, ref4, root, u, val; this.origin = origin1; this.context = context1; ref = ['ID', 'fullID', 'board', 'thread', 'info', 'quotes', 'isReply']; @@ -1553,12 +1560,17 @@ } file = $('.file', post); this.file.text = file.firstElementChild; + this.file.link = $('.fileText > a, .fileText-original', file); this.file.thumb = $('.fileThumb > [data-md5]', file); this.file.fullImage = $('.full-image', file); this.file.videoControls = $('.video-controls', this.file.text); if (this.file.videoThumb) { this.file.thumb.muted = true; } + if ((ref4 = this.file.thumb) != null ? ref4.dataset.src : void 0) { + this.file.thumb.src = this.file.thumb.dataset.src; + this.file.thumb.removeAttribute('data-src'); + } if (this.file.thumb && contractThumb) { ImageExpand.contract(this); } @@ -2217,37 +2229,22 @@ results1 = []; for (j = q = 0, len2 = ref.length; q < len2; j = ++q) { text2 = ref[j]; - if (j % 2 === 1) { - results1.push({ - innerHTML: "" + E(text2) + "" - }); - } else { - results1.push({ - innerHTML: E(text2) - }); - } + results1.push({ + innerHTML: (j % 2 ? "" + E(text2) + "" : E(text2)) + }); } return results1; })(); text = { - innerHTML: text.map(function(x) { - return x.innerHTML; - }).join('') + innerHTML: (greentext ? "" + E.cat(text) + "" : E.cat(text)) }; - if (greentext) { - text = { - innerHTML: "" + text.innerHTML + "" - }; - } results.push(text); } } return results; }).call(this); comment = { - innerHTML: comment.map(function(x) { - return x.innerHTML; - }).join('') + innerHTML: E.cat(comment) }; this.threadID = +data.thread_num; o = { @@ -2994,7 +2991,7 @@ return; } el = $.el('span', { - innerHTML: E(g.NAME) + " needs your permission to show desktop notifications. [FAQ]
or " + innerHTML: "4chan X needs your permission to show desktop notifications. [FAQ]
or " }); ref = $$('button', el), authorize = ref[0], disable = ref[1]; $.on(authorize, 'click', function() { @@ -3917,9 +3914,13 @@ return Index.sortedNodes.slice(offset, offset + nodesPerPage); }, buildStructure: function(nodes) { - var k, len1, node; + var k, len1, node, thumb; for (k = 0, len1 = nodes.length; k < len1; k++) { node = nodes[k]; + if (thumb = $('img[data-src]', node)) { + thumb.src = thumb.dataset.src; + thumb.removeAttribute('data-src'); + } $.add(Index.root, [node, $.el('hr')]); } if (doc.contains(Index.root)) { @@ -4015,6 +4016,14 @@ return filename; } }, + spoilerThumb: function(boardID) { + var spoilerRange; + if (spoilerRange = Build.spoilerRange[boardID]) { + return Build.staticPath + "spoiler-" + boardID + (Math.floor(1 + spoilerRange * Math.random())) + ".png"; + } else { + return Build.staticPath + "spoiler.png"; + } + }, sameThread: function(boardID, threadID) { return g.VIEW === 'thread' && g.BOARD.ID === boardID && g.THREADID === +threadID; }, @@ -4025,7 +4034,7 @@ return "/" + boardID + "/thread/" + threadID + "#p" + postID; } }, - postFromObject: function(data, boardID) { + postFromObject: function(data, boardID, suppressThumb) { var o; o = { postID: data.no, @@ -4069,179 +4078,62 @@ tag: data.tag }; } - return Build.post(o); + return Build.post(o, suppressThumb); }, - post: function(o) { + post: function(o, suppressThumb) { /* This function contains code from 4chan-JS (https://github.com/4chan/4chan-JS). @license: https://github.com/4chan/4chan-JS/blob/master/LICENSE */ - var boardID, capcode, capcodeClass, capcodeIcon, capcodeStart, comment, container, date, dateUTC, desktop2, email, emailField, emailProcessed, file, fileBlock, fileCont, fileDims, fileLink, fileSize, fileText, fileThumb, flag, flagCode, flagName, gifIcon, highlightPost, href, icons, isOP, k, len1, match, message, name, nameBlock, nameClass, postID, postInfo, postLink, quote, quoteLink, ref, replyLink, shortFilename, spoilerRange, staticPath, subject, subjectField, threadID, tripcode, tripcodeField, type, typeLC, uniqueID, userID, wholePost; + var boardID, capcode, capcodeDescription, capcodeLC, capcodeLong, capcodePlural, capcodeText, capcodeUC, comment, container, date, dateUTC, email, file, fileBlock, fileDims, fileSize, fileThumb, flagCode, flagName, gifIcon, href, isOP, k, len1, match, name, postClass, postID, postInfo, postLink, quote, quoteLink, ref, shortFilename, staticPath, subject, threadID, tripcode, uniqueID, wholePost; postID = o.postID, threadID = o.threadID, boardID = o.boardID, name = o.name, capcode = o.capcode, tripcode = o.tripcode, uniqueID = o.uniqueID, email = o.email, subject = o.subject, flagCode = o.flagCode, flagName = o.flagName, date = o.date, dateUTC = o.dateUTC, comment = o.comment, file = o.file; name || (name = ''); subject || (subject = ''); isOP = postID === threadID; staticPath = Build.staticPath, gifIcon = Build.gifIcon; - /* Name Block */ - switch (capcode) { - case 'admin': - case 'admin_highlight': - capcodeClass = ' capcodeAdmin'; - capcodeStart = { - innerHTML: " ## Admin" - }; - capcodeIcon = { - innerHTML: " \"Admin" - }; - break; - case 'mod': - capcodeClass = ' capcodeMod'; - capcodeStart = { - innerHTML: " ## Mod" - }; - capcodeIcon = { - innerHTML: " \"Mod" - }; - break; - case 'developer': - capcodeClass = ' capcodeDeveloper'; - capcodeStart = { - innerHTML: " ## Developer" - }; - capcodeIcon = { - innerHTML: " \"Developer" - }; - break; - case 'manager': - capcodeClass = ' capcodeManager'; - capcodeStart = { - innerHTML: " ## Manager" - }; - capcodeIcon = { - innerHTML: " \"Manager" - }; - break; - case 'admin_emeritus': - capcodeClass = ' capcodeAdmin'; - capcodeStart = { - innerHTML: " ## Admin Emeritus" - }; - capcodeIcon = { - innerHTML: " \"Admin" - }; - break; - default: - capcodeClass = ''; - capcodeStart = { - innerHTML: "" - }; - capcodeIcon = isOP && boardID === 'f' ? { - innerHTML: "" - } : { - innerHTML: " " - }; - } - nameClass = capcode ? ' capcode' : ''; - tripcodeField = tripcode ? { - innerHTML: " " + E(tripcode) + "" - } : { - innerHTML: "" - }; - emailField = { - innerHTML: "" + E(name) + "" + tripcodeField.innerHTML + capcodeStart.innerHTML - }; - if (email) { - emailProcessed = encodeURIComponent(email).replace(/%40/g, '@'); - emailField = { - innerHTML: "" + emailField.innerHTML + "" - }; - } - userID = !capcode && uniqueID ? { - innerHTML: " (ID: " + E(uniqueID) + ")" - } : { - innerHTML: "" - }; - flag = !flagCode ? { - innerHTML: "" - } : { - innerHTML: " " - }; - nameBlock = { - innerHTML: "" + emailField.innerHTML + capcodeIcon.innerHTML + userID.innerHTML + flag.innerHTML + " " - }; - /* Post Info */ - subjectField = isOP || boardID === 'f' ? { - innerHTML: "" + E(subject) + " " - } : { - innerHTML: "" - }; - desktop2 = isOP && boardID === 'f' ? '' : ' desktop'; + if (capcode) { + capcodeLC = capcode.split('_')[0]; + capcodeUC = capcodeLC[0].toUpperCase() + capcodeLC.slice(1); + capcodeText = capcodeUC; + capcodeLong = { + 'Admin': 'Administrator', + 'Mod': 'Moderator' + }[capcodeUC] || capcodeUC; + capcodePlural = capcodeLong + "s"; + capcodeDescription = "a 4chan " + capcodeLong; + if (capcode === 'admin_emeritus') { + capcodeText = 'Admin Emeritus'; + capcodePlural = 'the Administrator Emeritus'; + capcodeDescription = "4chan's founding Administrator"; + } + } postLink = Build.postURL(boardID, threadID, postID); quoteLink = Build.sameThread(boardID, threadID) ? "javascript:quote('" + (+postID) + "');" : "/" + boardID + "/thread/" + threadID + "#q" + postID; - icons = (function() { - var k, len1, ref, results; - ref = ['Sticky', 'Closed', 'Archived']; - results = []; - for (k = 0, len1 = ref.length; k < len1; k++) { - type = ref[k]; - if (!(o["is" + type] && !(type === 'Closed' && o.isArchived))) { - continue; - } - typeLC = type.toLowerCase(); - results.push({ - innerHTML: " \""" - }); - } - return results; - })(); - replyLink = isOP && g.VIEW === 'index' ? { - innerHTML: "   [Reply]" - } : { - innerHTML: "" - }; postInfo = { - innerHTML: "
" + subjectField.innerHTML + nameBlock.innerHTML + "" + E(date) + " No." + E(postID) + "" + icons.map(function(x) { - return x.innerHTML; - }).join('') + replyLink.innerHTML + "
" + innerHTML: "
" + (isOP || boardID === "f" ? "" + E(subject) + " " : "") + "" + (email ? "" : "") + "" + E(name) + "" + (tripcode ? " " + E(tripcode) + "" : "") + (capcode ? " ## " + E(capcodeText) + "" : "") + (email ? "" : "") + (boardID === "f" && isOP || capcode ? "" : " ") + (capcode ? " \""" : "") + (uniqueID && !capcode ? " (ID: " + E(uniqueID) + ")" : "") + (flagCode ? " " : "") + " " + E(date) + " No." + E(postID) + "" + (o.isSticky ? " \"Sticky\"" : "") + (o.isClosed && !o.isArchived ? " \"Closed\"" : "") + (o.isArchived ? " \"Archived\"" : "") + (isOP && g.VIEW === "index" ? "   [Reply]" : "") + "
" }; /* File Info */ - fileCont = (file != null ? file.isDeleted : void 0) ? { - innerHTML: "\"File" - } : file && boardID === 'f' ? { - innerHTML: "
File: " + E(file.name) + "-(" + E($.bytesToString(file.size)) + ", " + E(file.width) + "x" + E(file.height) + ", " + E(file.tag) + ")
" - } : file ? (file.isSpoiler ? (shortFilename = 'Spoiler Image', (spoilerRange = Build.spoilerRange[boardID]) ? fileThumb = staticPath + "spoiler-" + boardID + (Math.floor(1 + spoilerRange * Math.random())) + ".png" : fileThumb = staticPath + "spoiler.png", file.twidth = file.theight = 100) : (shortFilename = Build.shortFilename(file.name, !isOP), fileThumb = file.turl), fileSize = $.bytesToString(file.size), fileDims = file.url.slice(-4) === '.pdf' ? 'PDF' : file.width + "x" + file.height, fileLink = file.isSpoiler || file.name === shortFilename ? { - innerHTML: "" + E(shortFilename) + "" - } : { - innerHTML: "" + E(shortFilename) + "" - }, fileText = file.isSpoiler ? { - innerHTML: "
File: " + fileLink.innerHTML + " (" + E(fileSize) + ", " + E(fileDims) + ")
" - } : { - innerHTML: "
File: " + fileLink.innerHTML + " (" + E(fileSize) + ", " + E(fileDims) + ")
" - }, { - innerHTML: fileText.innerHTML + "\""" - }) : void 0; - fileBlock = file ? { - innerHTML: "
" + fileCont.innerHTML + "
" - } : { - innerHTML: "" + if (file && !file.isDeleted) { + shortFilename = Build.shortFilename(file.name); + fileSize = $.bytesToString(file.size); + fileDims = file.url.slice(-4) === '.pdf' ? 'PDF' : file.width + "x" + file.height; + fileThumb = file.isSpoiler ? Build.spoilerThumb(boardID) : file.turl; + } + fileBlock = { + innerHTML: (file ? "
" + (file.isDeleted ? "\"File" : (boardID === "f" ? "
File: " + E(file.name) + "-(" + E(fileSize) + ", " + E(fileDims) + ", " + E(file.tag) + ")
" : "
File: " + (file.isSpoiler ? "Spoiler Image" : E(shortFilename)) + " (" + E(fileSize) + ", " + E(fileDims) + ")
")) + "
" : "") }; /* Whole Post */ - highlightPost = capcode === 'admin_highlight' ? ' highlightPost' : ''; - message = { - innerHTML: "
" + comment.innerHTML + "
" - }; - wholePost = isOP ? { - innerHTML: "
" + fileBlock.innerHTML + postInfo.innerHTML + message.innerHTML + "
" - } : { - innerHTML: "
>>
" + postInfo.innerHTML + fileBlock.innerHTML + message.innerHTML + "
" + postClass = isOP ? 'op' : 'reply'; + wholePost = { + innerHTML: (!isOP ? "
>>
" : "") + "
" + (isOP ? fileBlock.innerHTML + postInfo.innerHTML : postInfo.innerHTML + fileBlock.innerHTML) + "
" + comment.innerHTML + "
" }; container = $.el('div', { - className: "postContainer " + (isOP ? 'op' : 'reply') + "Container", + className: "postContainer " + postClass + "Container", id: "pc" + postID }); $.extend(container, wholePost); @@ -4292,7 +4184,7 @@ }, excerptThread: function(board, data, OP) { var files, nodes, posts, ref; - nodes = [OP ? OP.nodes.root : Build.postFromObject(data, board.ID)]; + nodes = [OP ? OP.nodes.root : Build.postFromObject(data, board.ID, true)]; if (data.omitted_posts || !Conf['Show Replies'] && data.replies) { ref = Conf['Show Replies'] ? [ data.omitted_posts, data.images - data.last_replies.filter(function(data) { @@ -4307,7 +4199,7 @@ return Build.postFromObject(data, board.ID); }, catalogThread: function(thread) { - var br, cc, comment, data, exif, fileCount, gifIcon, href, imgClass, k, len1, len2, len3, len4, pageCount, postCount, pp, q, quote, ref, ref1, ref2, ref3, ref4, root, spoilerRange, src, staticPath, subject, thumb, u, w; + var br, cc, comment, data, exif, fileCount, gifIcon, href, imgClass, k, len1, len2, len3, len4, pageCount, postCount, pp, q, quote, ref, ref1, ref2, ref3, ref4, root, spoilerRange, src, staticPath, u, w; staticPath = Build.staticPath, gifIcon = Build.gifIcon; data = Index.liveThreadData[Index.liveThreadIDs.indexOf(thread.ID)]; if (data.spoiler && !Conf['Reveal Spoiler Thumbnails']) { @@ -4326,19 +4218,9 @@ src = staticPath + "nofile.png"; imgClass = 'no-file'; } - thumb = imgClass ? { - innerHTML: "" - } : { - innerHTML: "" - }; postCount = data.replies + 1; fileCount = data.images + !!data.ext; pageCount = Math.floor(Index.liveThreadIDs.indexOf(thread.ID) / Index.threadsNumPerPage) + 1; - subject = thread.OP.info.subject ? { - innerHTML: "
" + E(thread.OP.info.subject) + "
" - } : { - innerHTML: "" - }; comment = { innerHTML: data.com || '' }; @@ -4346,7 +4228,7 @@ className: 'catalog-thread' }); $.extend(root, { - innerHTML: "" + thumb.innerHTML + "
" + E(postCount) + " / " + E(fileCount) + " / " + E(pageCount) + "
" + subject.innerHTML + "
" + comment.innerHTML + "
" + innerHTML: "
" + E(postCount) + " / " + E(fileCount) + " / " + E(pageCount) + "
" + (thread.OP.info.subject ? "
" + E(thread.OP.info.subject) + "
" : "") + "
" + comment.innerHTML + "
" }); root.dataset.fullID = thread.fullID; if (thread.OP.highlights) { @@ -5912,7 +5794,7 @@ href: 'javascript:;' }); $.extend(a, { - innerHTML: "" + innerHTML: "" }); a.dataset.fullID = thread.fullID; $.on(a, 'click', ThreadHiding.toggle); @@ -6853,7 +6735,7 @@ className: "qr-link-container" }); $.extend(link, { - innerHTML: "" + E((g.VIEW === "thread") ? "Reply to Thread" : "Start a Thread") + "" + innerHTML: "" + (g.VIEW === "thread" ? "Reply to Thread" : "Start a Thread") + "" }); QR.link = link.firstElementChild; $.on(link.firstChild, 'click', function() { @@ -7315,7 +7197,7 @@ var dialog, event, i, items, m, match_max, match_min, name, node, nodes, ref, rules, save, setNode; QR.nodes = nodes = { el: dialog = UI.dialog('qr', 'top: 50px; right: 0px;', { - innerHTML: "
×
+
No selected file
" + innerHTML: "
×
+
No selected file
" }) }; setNode = function(name, query) { @@ -7544,7 +7426,7 @@ QR.cooldown.auto = false; QR.status(); return QR.error($.el('span', { - innerHTML: "4chan X encountered an error while posting. [Banned?] [More info]" + innerHTML: "4chan X encountered an error while posting. [Banned?] [More info]" })); } }; @@ -7593,7 +7475,7 @@ return QR.status(); }, response: function() { - var URL, _, ban, err, h1, isReply, m, open, post, postID, postsCount, ref, ref1, req, resDoc, threadID; + var URL, _, ban, err, h1, isReply, lastPostToThread, m, open, post, postID, postsCount, ref, ref1, req, resDoc, threadID; req = QR.req; delete QR.req; post = QR.posts[0]; @@ -7661,6 +7543,16 @@ }); postsCount = QR.posts.length - 1; QR.cooldown.auto = postsCount && isReply; + lastPostToThread = !((function() { + var k, len1, p, ref2; + ref2 = QR.posts.slice(1); + for (k = 0, len1 = ref2.length; k < len1; k++) { + p = ref2[k]; + if (p.thread === post.thread) { + return true; + } + } + })()); if (!(Conf['Persistent QR'] || postsCount)) { QR.close(); } else { @@ -7668,7 +7560,7 @@ QR.captcha.setup(d.activeElement === QR.nodes.status); } QR.cooldown.add(req.uploadEndTime, threadID, postID); - URL = threadID === postID ? window.location.origin + "/" + g.BOARD + "/thread/" + threadID : g.VIEW === 'index' && !QR.cooldown.auto && Conf['Open Post in New Tab'] ? window.location.origin + "/" + g.BOARD + "/thread/" + threadID + "#p" + postID : void 0; + URL = threadID === postID ? window.location.origin + "/" + g.BOARD + "/thread/" + threadID : g.VIEW === 'index' && lastPostToThread && Conf['Open Post in New Tab'] ? window.location.origin + "/" + g.BOARD + "/thread/" + threadID + "#p" + postID : void 0; if (URL) { open = Conf['Open Post in New Tab'] || postsCount ? function() { return $.open(URL); @@ -10292,7 +10184,7 @@ preload: 'none', loop: true, muted: true, - poster: thumb.src, + poster: thumb.src || thumb.dataset.src, textContent: thumb.alt, className: thumb.className }); @@ -10319,7 +10211,7 @@ return; } type = (match = URL.match(/\.([^.]+)$/)[1].toUpperCase()) === 'JPEG' ? 'JPG' : match; - replace = Conf["Replace " + type] && !/spoiler/.test(thumb.src); + replace = Conf["Replace " + type] && !/spoiler/.test(thumb.src || thumb.dataset.src); if (!(replace || Conf['prefetch'])) { return; } @@ -10352,7 +10244,8 @@ clone = ref1[q]; clone.file.thumb.src = URL; } - return thumb.src = URL; + thumb.src = URL; + return thumb.removeAttribute('data-src'); }); } return el.src = URL; @@ -10497,7 +10390,11 @@ thumb = this.file.thumb; thumb.removeAttribute('style'); thumb.style.maxHeight = thumb.style.maxWidth = this.isReply ? '125px' : '250px'; - return thumb.src = this.file.thumbURL; + if (thumb.src) { + return thumb.src = this.file.thumbURL; + } else { + return thumb.dataset.src = this.file.thumbURL; + } } }; @@ -11905,19 +11802,13 @@ return; } statsHTML = { - innerHTML: "? / ?" + innerHTML: "? / ?" + (Conf["IP Count in Stats"] ? " / ?" : "") + (Conf["Page Count in Stats"] ? " / ?" : "") }; statsTitle = 'Posts / Files'; if (Conf['IP Count in Stats']) { - statsHTML = { - innerHTML: statsHTML.innerHTML + " / ?" - }; statsTitle += ' / IPs'; } if (Conf['Page Count in Stats']) { - statsHTML = { - innerHTML: statsHTML.innerHTML + " / ?" - }; statsTitle += ' / Page'; } if (Conf['Updater and Stats in Header']) { @@ -14335,9 +14226,7 @@ return ''; }); return $.extend(outputNode, { - innerHTML: output.map(function(x) { - return x.innerHTML; - }).join('') + innerHTML: E.cat(output) }); }, formatters: { @@ -14381,15 +14270,9 @@ }; }, p: function() { - if (this.file.isSpoiler) { - return { - innerHTML: "Spoiler, " - }; - } else { - return { - innerHTML: "" - }; - } + return { + innerHTML: (this.file.isSpoiler ? "Spoiler, " : "") + }; }, s: function() { return { @@ -15441,9 +15324,8 @@ className: 'dialog' }); $.extend(dialog, { - innerHTML: "
" + innerHTML: "
" }); - $('a[href$="/CHANGELOG.md"]', dialog).textContent = g.VERSION; Settings.overlay = overlay = $.el('div', { id: 'overlay' }); @@ -15774,7 +15656,7 @@ filter: function(section) { var select; $.extend(section, { - innerHTML: "
" + innerHTML: "
" }); select = $('select', section); $.on(select, 'change', Settings.selectFilter); @@ -15798,7 +15680,7 @@ return; } $.extend(div, { - innerHTML: "
Filter is disabled.

Use regular expressions, one per line.
Lines starting with a # will be ignored.
For example, /weeaboo/i will filter posts containing the string \`weeaboo\`, case-insensitive.
MD5 filtering uses exact string matching, not regular expressions.

Note: If you're using the native catalog rather than 4chan X's catalog, 4chan X's filters do not apply there.
The native catalog has its own separate filter list.

" + innerHTML: "
Filter is disabled.

Use regular expressions, one per line.
Lines starting with a # will be ignored.
For example, /weeaboo/i will filter posts containing the string \`weeaboo\`, case-insensitive.
MD5 filtering uses exact string matching, not regular expressions.

Note: If you're using the native catalog rather than 4chan X's catalog, 4chan X's filters do not apply there.
The native catalog has its own separate filter list.

" }); return $('.warning', div).hidden = Conf['Filter']; }, @@ -15817,7 +15699,7 @@ advanced: function(section) { var aa, applyCSS, archBoards, 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, w, warning, withCredentials, y, z; $.extend(section, { - innerHTML: "
Archiver
404 Redirect is disabled.
Thread redirectionPost fetchingFile redirection
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)
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:
" + innerHTML: "
Archiver
404 Redirect is disabled.
Thread redirectionPost fetchingFile redirection
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)
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:
" }); ref = $$('.warning', section); for (k = 0, len1 = ref.length; k < len1; k++) { @@ -16044,7 +15926,7 @@ keybinds: function(section) { var arr, input, inputs, items, key, ref, tbody, tr; $.extend(section, { - innerHTML: "
Keybinds are disabled.
Allowed keys: a-z, 0-9, Ctrl, Shift, Alt, Meta, Enter, Esc, Up, Down, Right, Left.
Press Backspace to disable a keybind.
ActionsKeybinds
" + innerHTML: "
Keybinds are disabled.
Allowed keys: a-z, 0-9, Ctrl, Shift, Alt, Meta, Enter, Esc, Up, Down, Right, Left.
Press Backspace to disable a keybind.
ActionsKeybinds
" }); $('.warning', section).hidden = Conf['Keybinds']; tbody = $('tbody', section); @@ -16312,7 +16194,7 @@ } if (previousversion) { el = $.el('span', { - innerHTML: E(g.NAME) + " has been updated to version " + E(g.VERSION) + "." + innerHTML: "4chan X has been updated to version " + E(g.VERSION) + "." }); new Notice('info', el, 15); } else { diff --git a/builds/4chan-X-noupdate.crx b/builds/4chan-X-noupdate.crx index 1737f7e10..a241de59e 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 0021a0c05..5be2d4f7c 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.10.6.7 +// @version 1.10.7.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -394,11 +394,8 @@ doc = d.documentElement; g = { - VERSION: '1.10.6.7', + VERSION: '1.10.7.0', NAMESPACE: '4chan X.', - NAME: '4chan X', - FAQ: 'https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions', - CHANGELOG: 'https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md', boards: {} }; @@ -421,6 +418,16 @@ }; })(); + E.cat = function(templates) { + var html, k, len1, x; + html = ''; + for (k = 0, len1 = templates.length; k < len1; k++) { + x = templates[k]; + html += x.innerHTML; + } + return html; + }; + $ = function(selector, root) { if (root == null) { root = d.body; @@ -485,7 +492,7 @@ } blockedURLs[url] = true; message = $.el('div', { - innerHTML: E(g.NAME) + " was blocked from loading the following URL:

[More info]" + innerHTML: "4chan X was blocked from loading the following URL:

[More info]" }); $('span', message).textContent = (/^\/\//.test(url) ? location.protocol : '') + url; return new Notice('error', message, 30, function() { @@ -1347,7 +1354,7 @@ if (!(fileEl = $('.file', this.nodes.post))) { return; } - if (!(link = $('.fileText > a', fileEl))) { + if (!(link = $('.fileText > a, .fileText-original > a', fileEl))) { return; } if (!(info = (ref = link.nextSibling) != null ? ref.textContent.match(/\(([\d.]+ [KMG]?B).*\)/) : void 0)) { @@ -1370,7 +1377,7 @@ size *= 1024; } this.file.sizeInBytes = size; - if ((thumb = $('img[data-md5]', fileEl))) { + if ((thumb = $('.fileThumb > [data-md5]', fileEl))) { return $.extend(this.file, { thumb: thumb, thumbURL: location.protocol + "//i.4cdn.org/" + this.board + "/" + (link.href.match(/(\d+)\./)[1]) + "s.jpg", @@ -1483,7 +1490,7 @@ extend(Clone, superClass); function Clone(origin1, context1, contractThumb) { - var file, info, inline, inlined, k, key, len1, len2, len3, nodes, post, q, ref, ref1, ref2, ref3, root, u, val; + var file, info, inline, inlined, k, key, len1, len2, len3, nodes, post, q, ref, ref1, ref2, ref3, ref4, root, u, val; this.origin = origin1; this.context = context1; ref = ['ID', 'fullID', 'board', 'thread', 'info', 'quotes', 'isReply']; @@ -1552,12 +1559,17 @@ } file = $('.file', post); this.file.text = file.firstElementChild; + this.file.link = $('.fileText > a, .fileText-original', file); this.file.thumb = $('.fileThumb > [data-md5]', file); this.file.fullImage = $('.full-image', file); this.file.videoControls = $('.video-controls', this.file.text); if (this.file.videoThumb) { this.file.thumb.muted = true; } + if ((ref4 = this.file.thumb) != null ? ref4.dataset.src : void 0) { + this.file.thumb.src = this.file.thumb.dataset.src; + this.file.thumb.removeAttribute('data-src'); + } if (this.file.thumb && contractThumb) { ImageExpand.contract(this); } @@ -2216,37 +2228,22 @@ results1 = []; for (j = q = 0, len2 = ref.length; q < len2; j = ++q) { text2 = ref[j]; - if (j % 2 === 1) { - results1.push({ - innerHTML: "" + E(text2) + "" - }); - } else { - results1.push({ - innerHTML: E(text2) - }); - } + results1.push({ + innerHTML: (j % 2 ? "" + E(text2) + "" : E(text2)) + }); } return results1; })(); text = { - innerHTML: text.map(function(x) { - return x.innerHTML; - }).join('') + innerHTML: (greentext ? "" + E.cat(text) + "" : E.cat(text)) }; - if (greentext) { - text = { - innerHTML: "" + text.innerHTML + "" - }; - } results.push(text); } } return results; }).call(this); comment = { - innerHTML: comment.map(function(x) { - return x.innerHTML; - }).join('') + innerHTML: E.cat(comment) }; this.threadID = +data.thread_num; o = { @@ -2993,7 +2990,7 @@ return; } el = $.el('span', { - innerHTML: E(g.NAME) + " needs your permission to show desktop notifications. [FAQ]
or " + innerHTML: "4chan X needs your permission to show desktop notifications. [FAQ]
or " }); ref = $$('button', el), authorize = ref[0], disable = ref[1]; $.on(authorize, 'click', function() { @@ -3916,9 +3913,13 @@ return Index.sortedNodes.slice(offset, offset + nodesPerPage); }, buildStructure: function(nodes) { - var k, len1, node; + var k, len1, node, thumb; for (k = 0, len1 = nodes.length; k < len1; k++) { node = nodes[k]; + if (thumb = $('img[data-src]', node)) { + thumb.src = thumb.dataset.src; + thumb.removeAttribute('data-src'); + } $.add(Index.root, [node, $.el('hr')]); } if (doc.contains(Index.root)) { @@ -4014,6 +4015,14 @@ return filename; } }, + spoilerThumb: function(boardID) { + var spoilerRange; + if (spoilerRange = Build.spoilerRange[boardID]) { + return Build.staticPath + "spoiler-" + boardID + (Math.floor(1 + spoilerRange * Math.random())) + ".png"; + } else { + return Build.staticPath + "spoiler.png"; + } + }, sameThread: function(boardID, threadID) { return g.VIEW === 'thread' && g.BOARD.ID === boardID && g.THREADID === +threadID; }, @@ -4024,7 +4033,7 @@ return "/" + boardID + "/thread/" + threadID + "#p" + postID; } }, - postFromObject: function(data, boardID) { + postFromObject: function(data, boardID, suppressThumb) { var o; o = { postID: data.no, @@ -4068,179 +4077,62 @@ tag: data.tag }; } - return Build.post(o); + return Build.post(o, suppressThumb); }, - post: function(o) { + post: function(o, suppressThumb) { /* This function contains code from 4chan-JS (https://github.com/4chan/4chan-JS). @license: https://github.com/4chan/4chan-JS/blob/master/LICENSE */ - var boardID, capcode, capcodeClass, capcodeIcon, capcodeStart, comment, container, date, dateUTC, desktop2, email, emailField, emailProcessed, file, fileBlock, fileCont, fileDims, fileLink, fileSize, fileText, fileThumb, flag, flagCode, flagName, gifIcon, highlightPost, href, icons, isOP, k, len1, match, message, name, nameBlock, nameClass, postID, postInfo, postLink, quote, quoteLink, ref, replyLink, shortFilename, spoilerRange, staticPath, subject, subjectField, threadID, tripcode, tripcodeField, type, typeLC, uniqueID, userID, wholePost; + var boardID, capcode, capcodeDescription, capcodeLC, capcodeLong, capcodePlural, capcodeText, capcodeUC, comment, container, date, dateUTC, email, file, fileBlock, fileDims, fileSize, fileThumb, flagCode, flagName, gifIcon, href, isOP, k, len1, match, name, postClass, postID, postInfo, postLink, quote, quoteLink, ref, shortFilename, staticPath, subject, threadID, tripcode, uniqueID, wholePost; postID = o.postID, threadID = o.threadID, boardID = o.boardID, name = o.name, capcode = o.capcode, tripcode = o.tripcode, uniqueID = o.uniqueID, email = o.email, subject = o.subject, flagCode = o.flagCode, flagName = o.flagName, date = o.date, dateUTC = o.dateUTC, comment = o.comment, file = o.file; name || (name = ''); subject || (subject = ''); isOP = postID === threadID; staticPath = Build.staticPath, gifIcon = Build.gifIcon; - /* Name Block */ - switch (capcode) { - case 'admin': - case 'admin_highlight': - capcodeClass = ' capcodeAdmin'; - capcodeStart = { - innerHTML: " ## Admin" - }; - capcodeIcon = { - innerHTML: " \"Admin" - }; - break; - case 'mod': - capcodeClass = ' capcodeMod'; - capcodeStart = { - innerHTML: " ## Mod" - }; - capcodeIcon = { - innerHTML: " \"Mod" - }; - break; - case 'developer': - capcodeClass = ' capcodeDeveloper'; - capcodeStart = { - innerHTML: " ## Developer" - }; - capcodeIcon = { - innerHTML: " \"Developer" - }; - break; - case 'manager': - capcodeClass = ' capcodeManager'; - capcodeStart = { - innerHTML: " ## Manager" - }; - capcodeIcon = { - innerHTML: " \"Manager" - }; - break; - case 'admin_emeritus': - capcodeClass = ' capcodeAdmin'; - capcodeStart = { - innerHTML: " ## Admin Emeritus" - }; - capcodeIcon = { - innerHTML: " \"Admin" - }; - break; - default: - capcodeClass = ''; - capcodeStart = { - innerHTML: "" - }; - capcodeIcon = isOP && boardID === 'f' ? { - innerHTML: "" - } : { - innerHTML: " " - }; - } - nameClass = capcode ? ' capcode' : ''; - tripcodeField = tripcode ? { - innerHTML: " " + E(tripcode) + "" - } : { - innerHTML: "" - }; - emailField = { - innerHTML: "" + E(name) + "" + tripcodeField.innerHTML + capcodeStart.innerHTML - }; - if (email) { - emailProcessed = encodeURIComponent(email).replace(/%40/g, '@'); - emailField = { - innerHTML: "" + emailField.innerHTML + "" - }; - } - userID = !capcode && uniqueID ? { - innerHTML: " (ID: " + E(uniqueID) + ")" - } : { - innerHTML: "" - }; - flag = !flagCode ? { - innerHTML: "" - } : { - innerHTML: " " - }; - nameBlock = { - innerHTML: "" + emailField.innerHTML + capcodeIcon.innerHTML + userID.innerHTML + flag.innerHTML + " " - }; - /* Post Info */ - subjectField = isOP || boardID === 'f' ? { - innerHTML: "" + E(subject) + " " - } : { - innerHTML: "" - }; - desktop2 = isOP && boardID === 'f' ? '' : ' desktop'; + if (capcode) { + capcodeLC = capcode.split('_')[0]; + capcodeUC = capcodeLC[0].toUpperCase() + capcodeLC.slice(1); + capcodeText = capcodeUC; + capcodeLong = { + 'Admin': 'Administrator', + 'Mod': 'Moderator' + }[capcodeUC] || capcodeUC; + capcodePlural = capcodeLong + "s"; + capcodeDescription = "a 4chan " + capcodeLong; + if (capcode === 'admin_emeritus') { + capcodeText = 'Admin Emeritus'; + capcodePlural = 'the Administrator Emeritus'; + capcodeDescription = "4chan's founding Administrator"; + } + } postLink = Build.postURL(boardID, threadID, postID); quoteLink = Build.sameThread(boardID, threadID) ? "javascript:quote('" + (+postID) + "');" : "/" + boardID + "/thread/" + threadID + "#q" + postID; - icons = (function() { - var k, len1, ref, results; - ref = ['Sticky', 'Closed', 'Archived']; - results = []; - for (k = 0, len1 = ref.length; k < len1; k++) { - type = ref[k]; - if (!(o["is" + type] && !(type === 'Closed' && o.isArchived))) { - continue; - } - typeLC = type.toLowerCase(); - results.push({ - innerHTML: " \""" - }); - } - return results; - })(); - replyLink = isOP && g.VIEW === 'index' ? { - innerHTML: "   [Reply]" - } : { - innerHTML: "" - }; postInfo = { - innerHTML: "
" + subjectField.innerHTML + nameBlock.innerHTML + "" + E(date) + " No." + E(postID) + "" + icons.map(function(x) { - return x.innerHTML; - }).join('') + replyLink.innerHTML + "
" + innerHTML: "
" + (isOP || boardID === "f" ? "" + E(subject) + " " : "") + "" + (email ? "" : "") + "" + E(name) + "" + (tripcode ? " " + E(tripcode) + "" : "") + (capcode ? " ## " + E(capcodeText) + "" : "") + (email ? "" : "") + (boardID === "f" && isOP || capcode ? "" : " ") + (capcode ? " \""" : "") + (uniqueID && !capcode ? " (ID: " + E(uniqueID) + ")" : "") + (flagCode ? " " : "") + " " + E(date) + " No." + E(postID) + "" + (o.isSticky ? " \"Sticky\"" : "") + (o.isClosed && !o.isArchived ? " \"Closed\"" : "") + (o.isArchived ? " \"Archived\"" : "") + (isOP && g.VIEW === "index" ? "   [Reply]" : "") + "
" }; /* File Info */ - fileCont = (file != null ? file.isDeleted : void 0) ? { - innerHTML: "\"File" - } : file && boardID === 'f' ? { - innerHTML: "
File: " + E(file.name) + "-(" + E($.bytesToString(file.size)) + ", " + E(file.width) + "x" + E(file.height) + ", " + E(file.tag) + ")
" - } : file ? (file.isSpoiler ? (shortFilename = 'Spoiler Image', (spoilerRange = Build.spoilerRange[boardID]) ? fileThumb = staticPath + "spoiler-" + boardID + (Math.floor(1 + spoilerRange * Math.random())) + ".png" : fileThumb = staticPath + "spoiler.png", file.twidth = file.theight = 100) : (shortFilename = Build.shortFilename(file.name, !isOP), fileThumb = file.turl), fileSize = $.bytesToString(file.size), fileDims = file.url.slice(-4) === '.pdf' ? 'PDF' : file.width + "x" + file.height, fileLink = file.isSpoiler || file.name === shortFilename ? { - innerHTML: "" + E(shortFilename) + "" - } : { - innerHTML: "" + E(shortFilename) + "" - }, fileText = file.isSpoiler ? { - innerHTML: "
File: " + fileLink.innerHTML + " (" + E(fileSize) + ", " + E(fileDims) + ")
" - } : { - innerHTML: "
File: " + fileLink.innerHTML + " (" + E(fileSize) + ", " + E(fileDims) + ")
" - }, { - innerHTML: fileText.innerHTML + "\""" - }) : void 0; - fileBlock = file ? { - innerHTML: "
" + fileCont.innerHTML + "
" - } : { - innerHTML: "" + if (file && !file.isDeleted) { + shortFilename = Build.shortFilename(file.name); + fileSize = $.bytesToString(file.size); + fileDims = file.url.slice(-4) === '.pdf' ? 'PDF' : file.width + "x" + file.height; + fileThumb = file.isSpoiler ? Build.spoilerThumb(boardID) : file.turl; + } + fileBlock = { + innerHTML: (file ? "
" + (file.isDeleted ? "\"File" : (boardID === "f" ? "
File: " + E(file.name) + "-(" + E(fileSize) + ", " + E(fileDims) + ", " + E(file.tag) + ")
" : "
File: " + (file.isSpoiler ? "Spoiler Image" : E(shortFilename)) + " (" + E(fileSize) + ", " + E(fileDims) + ")
")) + "
" : "") }; /* Whole Post */ - highlightPost = capcode === 'admin_highlight' ? ' highlightPost' : ''; - message = { - innerHTML: "
" + comment.innerHTML + "
" - }; - wholePost = isOP ? { - innerHTML: "
" + fileBlock.innerHTML + postInfo.innerHTML + message.innerHTML + "
" - } : { - innerHTML: "
>>
" + postInfo.innerHTML + fileBlock.innerHTML + message.innerHTML + "
" + postClass = isOP ? 'op' : 'reply'; + wholePost = { + innerHTML: (!isOP ? "
>>
" : "") + "
" + (isOP ? fileBlock.innerHTML + postInfo.innerHTML : postInfo.innerHTML + fileBlock.innerHTML) + "
" + comment.innerHTML + "
" }; container = $.el('div', { - className: "postContainer " + (isOP ? 'op' : 'reply') + "Container", + className: "postContainer " + postClass + "Container", id: "pc" + postID }); $.extend(container, wholePost); @@ -4291,7 +4183,7 @@ }, excerptThread: function(board, data, OP) { var files, nodes, posts, ref; - nodes = [OP ? OP.nodes.root : Build.postFromObject(data, board.ID)]; + nodes = [OP ? OP.nodes.root : Build.postFromObject(data, board.ID, true)]; if (data.omitted_posts || !Conf['Show Replies'] && data.replies) { ref = Conf['Show Replies'] ? [ data.omitted_posts, data.images - data.last_replies.filter(function(data) { @@ -4306,7 +4198,7 @@ return Build.postFromObject(data, board.ID); }, catalogThread: function(thread) { - var br, cc, comment, data, exif, fileCount, gifIcon, href, imgClass, k, len1, len2, len3, len4, pageCount, postCount, pp, q, quote, ref, ref1, ref2, ref3, ref4, root, spoilerRange, src, staticPath, subject, thumb, u, w; + var br, cc, comment, data, exif, fileCount, gifIcon, href, imgClass, k, len1, len2, len3, len4, pageCount, postCount, pp, q, quote, ref, ref1, ref2, ref3, ref4, root, spoilerRange, src, staticPath, u, w; staticPath = Build.staticPath, gifIcon = Build.gifIcon; data = Index.liveThreadData[Index.liveThreadIDs.indexOf(thread.ID)]; if (data.spoiler && !Conf['Reveal Spoiler Thumbnails']) { @@ -4325,19 +4217,9 @@ src = staticPath + "nofile.png"; imgClass = 'no-file'; } - thumb = imgClass ? { - innerHTML: "" - } : { - innerHTML: "" - }; postCount = data.replies + 1; fileCount = data.images + !!data.ext; pageCount = Math.floor(Index.liveThreadIDs.indexOf(thread.ID) / Index.threadsNumPerPage) + 1; - subject = thread.OP.info.subject ? { - innerHTML: "
" + E(thread.OP.info.subject) + "
" - } : { - innerHTML: "" - }; comment = { innerHTML: data.com || '' }; @@ -4345,7 +4227,7 @@ className: 'catalog-thread' }); $.extend(root, { - innerHTML: "" + thumb.innerHTML + "
" + E(postCount) + " / " + E(fileCount) + " / " + E(pageCount) + "
" + subject.innerHTML + "
" + comment.innerHTML + "
" + innerHTML: "
" + E(postCount) + " / " + E(fileCount) + " / " + E(pageCount) + "
" + (thread.OP.info.subject ? "
" + E(thread.OP.info.subject) + "
" : "") + "
" + comment.innerHTML + "
" }); root.dataset.fullID = thread.fullID; if (thread.OP.highlights) { @@ -5911,7 +5793,7 @@ href: 'javascript:;' }); $.extend(a, { - innerHTML: "" + innerHTML: "" }); a.dataset.fullID = thread.fullID; $.on(a, 'click', ThreadHiding.toggle); @@ -6852,7 +6734,7 @@ className: "qr-link-container" }); $.extend(link, { - innerHTML: "" + E((g.VIEW === "thread") ? "Reply to Thread" : "Start a Thread") + "" + innerHTML: "" + (g.VIEW === "thread" ? "Reply to Thread" : "Start a Thread") + "" }); QR.link = link.firstElementChild; $.on(link.firstChild, 'click', function() { @@ -7314,7 +7196,7 @@ var dialog, event, i, items, m, match_max, match_min, name, node, nodes, ref, rules, save, setNode; QR.nodes = nodes = { el: dialog = UI.dialog('qr', 'top: 50px; right: 0px;', { - innerHTML: "
×
+
No selected file
" + innerHTML: "
×
+
No selected file
" }) }; setNode = function(name, query) { @@ -7543,7 +7425,7 @@ QR.cooldown.auto = false; QR.status(); return QR.error($.el('span', { - innerHTML: "4chan X encountered an error while posting. [Banned?] [More info]" + innerHTML: "4chan X encountered an error while posting. [Banned?] [More info]" })); } }; @@ -7592,7 +7474,7 @@ return QR.status(); }, response: function() { - var URL, _, ban, err, h1, isReply, m, open, post, postID, postsCount, ref, ref1, req, resDoc, threadID; + var URL, _, ban, err, h1, isReply, lastPostToThread, m, open, post, postID, postsCount, ref, ref1, req, resDoc, threadID; req = QR.req; delete QR.req; post = QR.posts[0]; @@ -7660,6 +7542,16 @@ }); postsCount = QR.posts.length - 1; QR.cooldown.auto = postsCount && isReply; + lastPostToThread = !((function() { + var k, len1, p, ref2; + ref2 = QR.posts.slice(1); + for (k = 0, len1 = ref2.length; k < len1; k++) { + p = ref2[k]; + if (p.thread === post.thread) { + return true; + } + } + })()); if (!(Conf['Persistent QR'] || postsCount)) { QR.close(); } else { @@ -7667,7 +7559,7 @@ QR.captcha.setup(d.activeElement === QR.nodes.status); } QR.cooldown.add(req.uploadEndTime, threadID, postID); - URL = threadID === postID ? window.location.origin + "/" + g.BOARD + "/thread/" + threadID : g.VIEW === 'index' && !QR.cooldown.auto && Conf['Open Post in New Tab'] ? window.location.origin + "/" + g.BOARD + "/thread/" + threadID + "#p" + postID : void 0; + URL = threadID === postID ? window.location.origin + "/" + g.BOARD + "/thread/" + threadID : g.VIEW === 'index' && lastPostToThread && Conf['Open Post in New Tab'] ? window.location.origin + "/" + g.BOARD + "/thread/" + threadID + "#p" + postID : void 0; if (URL) { open = Conf['Open Post in New Tab'] || postsCount ? function() { return $.open(URL); @@ -10291,7 +10183,7 @@ preload: 'none', loop: true, muted: true, - poster: thumb.src, + poster: thumb.src || thumb.dataset.src, textContent: thumb.alt, className: thumb.className }); @@ -10318,7 +10210,7 @@ return; } type = (match = URL.match(/\.([^.]+)$/)[1].toUpperCase()) === 'JPEG' ? 'JPG' : match; - replace = Conf["Replace " + type] && !/spoiler/.test(thumb.src); + replace = Conf["Replace " + type] && !/spoiler/.test(thumb.src || thumb.dataset.src); if (!(replace || Conf['prefetch'])) { return; } @@ -10351,7 +10243,8 @@ clone = ref1[q]; clone.file.thumb.src = URL; } - return thumb.src = URL; + thumb.src = URL; + return thumb.removeAttribute('data-src'); }); } return el.src = URL; @@ -10496,7 +10389,11 @@ thumb = this.file.thumb; thumb.removeAttribute('style'); thumb.style.maxHeight = thumb.style.maxWidth = this.isReply ? '125px' : '250px'; - return thumb.src = this.file.thumbURL; + if (thumb.src) { + return thumb.src = this.file.thumbURL; + } else { + return thumb.dataset.src = this.file.thumbURL; + } } }; @@ -11904,19 +11801,13 @@ return; } statsHTML = { - innerHTML: "? / ?" + innerHTML: "? / ?" + (Conf["IP Count in Stats"] ? " / ?" : "") + (Conf["Page Count in Stats"] ? " / ?" : "") }; statsTitle = 'Posts / Files'; if (Conf['IP Count in Stats']) { - statsHTML = { - innerHTML: statsHTML.innerHTML + " / ?" - }; statsTitle += ' / IPs'; } if (Conf['Page Count in Stats']) { - statsHTML = { - innerHTML: statsHTML.innerHTML + " / ?" - }; statsTitle += ' / Page'; } if (Conf['Updater and Stats in Header']) { @@ -14334,9 +14225,7 @@ return ''; }); return $.extend(outputNode, { - innerHTML: output.map(function(x) { - return x.innerHTML; - }).join('') + innerHTML: E.cat(output) }); }, formatters: { @@ -14380,15 +14269,9 @@ }; }, p: function() { - if (this.file.isSpoiler) { - return { - innerHTML: "Spoiler, " - }; - } else { - return { - innerHTML: "" - }; - } + return { + innerHTML: (this.file.isSpoiler ? "Spoiler, " : "") + }; }, s: function() { return { @@ -15440,9 +15323,8 @@ className: 'dialog' }); $.extend(dialog, { - innerHTML: "
" + innerHTML: "
" }); - $('a[href$="/CHANGELOG.md"]', dialog).textContent = g.VERSION; Settings.overlay = overlay = $.el('div', { id: 'overlay' }); @@ -15773,7 +15655,7 @@ filter: function(section) { var select; $.extend(section, { - innerHTML: "
" + innerHTML: "
" }); select = $('select', section); $.on(select, 'change', Settings.selectFilter); @@ -15797,7 +15679,7 @@ return; } $.extend(div, { - innerHTML: "
Filter is disabled.

Use regular expressions, one per line.
Lines starting with a # will be ignored.
For example, /weeaboo/i will filter posts containing the string \`weeaboo\`, case-insensitive.
MD5 filtering uses exact string matching, not regular expressions.

Note: If you're using the native catalog rather than 4chan X's catalog, 4chan X's filters do not apply there.
The native catalog has its own separate filter list.

" + innerHTML: "
Filter is disabled.

Use regular expressions, one per line.
Lines starting with a # will be ignored.
For example, /weeaboo/i will filter posts containing the string \`weeaboo\`, case-insensitive.
MD5 filtering uses exact string matching, not regular expressions.

Note: If you're using the native catalog rather than 4chan X's catalog, 4chan X's filters do not apply there.
The native catalog has its own separate filter list.

" }); return $('.warning', div).hidden = Conf['Filter']; }, @@ -15816,7 +15698,7 @@ advanced: function(section) { var aa, applyCSS, archBoards, 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, w, warning, withCredentials, y, z; $.extend(section, { - innerHTML: "
Archiver
404 Redirect is disabled.
Thread redirectionPost fetchingFile redirection
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)
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:
" + innerHTML: "
Archiver
404 Redirect is disabled.
Thread redirectionPost fetchingFile redirection
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)
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:
" }); ref = $$('.warning', section); for (k = 0, len1 = ref.length; k < len1; k++) { @@ -16043,7 +15925,7 @@ keybinds: function(section) { var arr, input, inputs, items, key, ref, tbody, tr; $.extend(section, { - innerHTML: "
Keybinds are disabled.
Allowed keys: a-z, 0-9, Ctrl, Shift, Alt, Meta, Enter, Esc, Up, Down, Right, Left.
Press Backspace to disable a keybind.
ActionsKeybinds
" + innerHTML: "
Keybinds are disabled.
Allowed keys: a-z, 0-9, Ctrl, Shift, Alt, Meta, Enter, Esc, Up, Down, Right, Left.
Press Backspace to disable a keybind.
ActionsKeybinds
" }); $('.warning', section).hidden = Conf['Keybinds']; tbody = $('tbody', section); @@ -16311,7 +16193,7 @@ } if (previousversion) { el = $.el('span', { - innerHTML: E(g.NAME) + " has been updated to version " + E(g.VERSION) + "." + innerHTML: "4chan X has been updated to version " + E(g.VERSION) + "." }); new Notice('info', el, 15); } else { diff --git a/builds/4chan-X.crx b/builds/4chan-X.crx index eca3efeda..0d8880b09 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 d4b7e7599..c80076a03 100644 --- a/builds/4chan-X.meta.js +++ b/builds/4chan-X.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.10.6.7 +// @version 1.10.7.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index f3e6650df..189ae515f 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.10.6.7 +// @version 1.10.7.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -395,11 +395,8 @@ doc = d.documentElement; g = { - VERSION: '1.10.6.7', + VERSION: '1.10.7.0', NAMESPACE: '4chan X.', - NAME: '4chan X', - FAQ: 'https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions', - CHANGELOG: 'https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md', boards: {} }; @@ -422,6 +419,16 @@ }; })(); + E.cat = function(templates) { + var html, k, len1, x; + html = ''; + for (k = 0, len1 = templates.length; k < len1; k++) { + x = templates[k]; + html += x.innerHTML; + } + return html; + }; + $ = function(selector, root) { if (root == null) { root = d.body; @@ -486,7 +493,7 @@ } blockedURLs[url] = true; message = $.el('div', { - innerHTML: E(g.NAME) + " was blocked from loading the following URL:

[More info]" + innerHTML: "4chan X was blocked from loading the following URL:

[More info]" }); $('span', message).textContent = (/^\/\//.test(url) ? location.protocol : '') + url; return new Notice('error', message, 30, function() { @@ -1348,7 +1355,7 @@ if (!(fileEl = $('.file', this.nodes.post))) { return; } - if (!(link = $('.fileText > a', fileEl))) { + if (!(link = $('.fileText > a, .fileText-original > a', fileEl))) { return; } if (!(info = (ref = link.nextSibling) != null ? ref.textContent.match(/\(([\d.]+ [KMG]?B).*\)/) : void 0)) { @@ -1371,7 +1378,7 @@ size *= 1024; } this.file.sizeInBytes = size; - if ((thumb = $('img[data-md5]', fileEl))) { + if ((thumb = $('.fileThumb > [data-md5]', fileEl))) { return $.extend(this.file, { thumb: thumb, thumbURL: location.protocol + "//i.4cdn.org/" + this.board + "/" + (link.href.match(/(\d+)\./)[1]) + "s.jpg", @@ -1484,7 +1491,7 @@ extend(Clone, superClass); function Clone(origin1, context1, contractThumb) { - var file, info, inline, inlined, k, key, len1, len2, len3, nodes, post, q, ref, ref1, ref2, ref3, root, u, val; + var file, info, inline, inlined, k, key, len1, len2, len3, nodes, post, q, ref, ref1, ref2, ref3, ref4, root, u, val; this.origin = origin1; this.context = context1; ref = ['ID', 'fullID', 'board', 'thread', 'info', 'quotes', 'isReply']; @@ -1553,12 +1560,17 @@ } file = $('.file', post); this.file.text = file.firstElementChild; + this.file.link = $('.fileText > a, .fileText-original', file); this.file.thumb = $('.fileThumb > [data-md5]', file); this.file.fullImage = $('.full-image', file); this.file.videoControls = $('.video-controls', this.file.text); if (this.file.videoThumb) { this.file.thumb.muted = true; } + if ((ref4 = this.file.thumb) != null ? ref4.dataset.src : void 0) { + this.file.thumb.src = this.file.thumb.dataset.src; + this.file.thumb.removeAttribute('data-src'); + } if (this.file.thumb && contractThumb) { ImageExpand.contract(this); } @@ -2217,37 +2229,22 @@ results1 = []; for (j = q = 0, len2 = ref.length; q < len2; j = ++q) { text2 = ref[j]; - if (j % 2 === 1) { - results1.push({ - innerHTML: "" + E(text2) + "" - }); - } else { - results1.push({ - innerHTML: E(text2) - }); - } + results1.push({ + innerHTML: (j % 2 ? "" + E(text2) + "" : E(text2)) + }); } return results1; })(); text = { - innerHTML: text.map(function(x) { - return x.innerHTML; - }).join('') + innerHTML: (greentext ? "" + E.cat(text) + "" : E.cat(text)) }; - if (greentext) { - text = { - innerHTML: "" + text.innerHTML + "" - }; - } results.push(text); } } return results; }).call(this); comment = { - innerHTML: comment.map(function(x) { - return x.innerHTML; - }).join('') + innerHTML: E.cat(comment) }; this.threadID = +data.thread_num; o = { @@ -2994,7 +2991,7 @@ return; } el = $.el('span', { - innerHTML: E(g.NAME) + " needs your permission to show desktop notifications. [FAQ]
or " + innerHTML: "4chan X needs your permission to show desktop notifications. [FAQ]
or " }); ref = $$('button', el), authorize = ref[0], disable = ref[1]; $.on(authorize, 'click', function() { @@ -3917,9 +3914,13 @@ return Index.sortedNodes.slice(offset, offset + nodesPerPage); }, buildStructure: function(nodes) { - var k, len1, node; + var k, len1, node, thumb; for (k = 0, len1 = nodes.length; k < len1; k++) { node = nodes[k]; + if (thumb = $('img[data-src]', node)) { + thumb.src = thumb.dataset.src; + thumb.removeAttribute('data-src'); + } $.add(Index.root, [node, $.el('hr')]); } if (doc.contains(Index.root)) { @@ -4015,6 +4016,14 @@ return filename; } }, + spoilerThumb: function(boardID) { + var spoilerRange; + if (spoilerRange = Build.spoilerRange[boardID]) { + return Build.staticPath + "spoiler-" + boardID + (Math.floor(1 + spoilerRange * Math.random())) + ".png"; + } else { + return Build.staticPath + "spoiler.png"; + } + }, sameThread: function(boardID, threadID) { return g.VIEW === 'thread' && g.BOARD.ID === boardID && g.THREADID === +threadID; }, @@ -4025,7 +4034,7 @@ return "/" + boardID + "/thread/" + threadID + "#p" + postID; } }, - postFromObject: function(data, boardID) { + postFromObject: function(data, boardID, suppressThumb) { var o; o = { postID: data.no, @@ -4069,179 +4078,62 @@ tag: data.tag }; } - return Build.post(o); + return Build.post(o, suppressThumb); }, - post: function(o) { + post: function(o, suppressThumb) { /* This function contains code from 4chan-JS (https://github.com/4chan/4chan-JS). @license: https://github.com/4chan/4chan-JS/blob/master/LICENSE */ - var boardID, capcode, capcodeClass, capcodeIcon, capcodeStart, comment, container, date, dateUTC, desktop2, email, emailField, emailProcessed, file, fileBlock, fileCont, fileDims, fileLink, fileSize, fileText, fileThumb, flag, flagCode, flagName, gifIcon, highlightPost, href, icons, isOP, k, len1, match, message, name, nameBlock, nameClass, postID, postInfo, postLink, quote, quoteLink, ref, replyLink, shortFilename, spoilerRange, staticPath, subject, subjectField, threadID, tripcode, tripcodeField, type, typeLC, uniqueID, userID, wholePost; + var boardID, capcode, capcodeDescription, capcodeLC, capcodeLong, capcodePlural, capcodeText, capcodeUC, comment, container, date, dateUTC, email, file, fileBlock, fileDims, fileSize, fileThumb, flagCode, flagName, gifIcon, href, isOP, k, len1, match, name, postClass, postID, postInfo, postLink, quote, quoteLink, ref, shortFilename, staticPath, subject, threadID, tripcode, uniqueID, wholePost; postID = o.postID, threadID = o.threadID, boardID = o.boardID, name = o.name, capcode = o.capcode, tripcode = o.tripcode, uniqueID = o.uniqueID, email = o.email, subject = o.subject, flagCode = o.flagCode, flagName = o.flagName, date = o.date, dateUTC = o.dateUTC, comment = o.comment, file = o.file; name || (name = ''); subject || (subject = ''); isOP = postID === threadID; staticPath = Build.staticPath, gifIcon = Build.gifIcon; - /* Name Block */ - switch (capcode) { - case 'admin': - case 'admin_highlight': - capcodeClass = ' capcodeAdmin'; - capcodeStart = { - innerHTML: " ## Admin" - }; - capcodeIcon = { - innerHTML: " \"Admin" - }; - break; - case 'mod': - capcodeClass = ' capcodeMod'; - capcodeStart = { - innerHTML: " ## Mod" - }; - capcodeIcon = { - innerHTML: " \"Mod" - }; - break; - case 'developer': - capcodeClass = ' capcodeDeveloper'; - capcodeStart = { - innerHTML: " ## Developer" - }; - capcodeIcon = { - innerHTML: " \"Developer" - }; - break; - case 'manager': - capcodeClass = ' capcodeManager'; - capcodeStart = { - innerHTML: " ## Manager" - }; - capcodeIcon = { - innerHTML: " \"Manager" - }; - break; - case 'admin_emeritus': - capcodeClass = ' capcodeAdmin'; - capcodeStart = { - innerHTML: " ## Admin Emeritus" - }; - capcodeIcon = { - innerHTML: " \"Admin" - }; - break; - default: - capcodeClass = ''; - capcodeStart = { - innerHTML: "" - }; - capcodeIcon = isOP && boardID === 'f' ? { - innerHTML: "" - } : { - innerHTML: " " - }; - } - nameClass = capcode ? ' capcode' : ''; - tripcodeField = tripcode ? { - innerHTML: " " + E(tripcode) + "" - } : { - innerHTML: "" - }; - emailField = { - innerHTML: "" + E(name) + "" + tripcodeField.innerHTML + capcodeStart.innerHTML - }; - if (email) { - emailProcessed = encodeURIComponent(email).replace(/%40/g, '@'); - emailField = { - innerHTML: "" + emailField.innerHTML + "" - }; - } - userID = !capcode && uniqueID ? { - innerHTML: " (ID: " + E(uniqueID) + ")" - } : { - innerHTML: "" - }; - flag = !flagCode ? { - innerHTML: "" - } : { - innerHTML: " " - }; - nameBlock = { - innerHTML: "" + emailField.innerHTML + capcodeIcon.innerHTML + userID.innerHTML + flag.innerHTML + " " - }; - /* Post Info */ - subjectField = isOP || boardID === 'f' ? { - innerHTML: "" + E(subject) + " " - } : { - innerHTML: "" - }; - desktop2 = isOP && boardID === 'f' ? '' : ' desktop'; + if (capcode) { + capcodeLC = capcode.split('_')[0]; + capcodeUC = capcodeLC[0].toUpperCase() + capcodeLC.slice(1); + capcodeText = capcodeUC; + capcodeLong = { + 'Admin': 'Administrator', + 'Mod': 'Moderator' + }[capcodeUC] || capcodeUC; + capcodePlural = capcodeLong + "s"; + capcodeDescription = "a 4chan " + capcodeLong; + if (capcode === 'admin_emeritus') { + capcodeText = 'Admin Emeritus'; + capcodePlural = 'the Administrator Emeritus'; + capcodeDescription = "4chan's founding Administrator"; + } + } postLink = Build.postURL(boardID, threadID, postID); quoteLink = Build.sameThread(boardID, threadID) ? "javascript:quote('" + (+postID) + "');" : "/" + boardID + "/thread/" + threadID + "#q" + postID; - icons = (function() { - var k, len1, ref, results; - ref = ['Sticky', 'Closed', 'Archived']; - results = []; - for (k = 0, len1 = ref.length; k < len1; k++) { - type = ref[k]; - if (!(o["is" + type] && !(type === 'Closed' && o.isArchived))) { - continue; - } - typeLC = type.toLowerCase(); - results.push({ - innerHTML: " \""" - }); - } - return results; - })(); - replyLink = isOP && g.VIEW === 'index' ? { - innerHTML: "   [Reply]" - } : { - innerHTML: "" - }; postInfo = { - innerHTML: "
" + subjectField.innerHTML + nameBlock.innerHTML + "" + E(date) + " No." + E(postID) + "" + icons.map(function(x) { - return x.innerHTML; - }).join('') + replyLink.innerHTML + "
" + innerHTML: "
" + (isOP || boardID === "f" ? "" + E(subject) + " " : "") + "" + (email ? "" : "") + "" + E(name) + "" + (tripcode ? " " + E(tripcode) + "" : "") + (capcode ? " ## " + E(capcodeText) + "" : "") + (email ? "" : "") + (boardID === "f" && isOP || capcode ? "" : " ") + (capcode ? " \""" : "") + (uniqueID && !capcode ? " (ID: " + E(uniqueID) + ")" : "") + (flagCode ? " " : "") + " " + E(date) + " No." + E(postID) + "" + (o.isSticky ? " \"Sticky\"" : "") + (o.isClosed && !o.isArchived ? " \"Closed\"" : "") + (o.isArchived ? " \"Archived\"" : "") + (isOP && g.VIEW === "index" ? "   [Reply]" : "") + "
" }; /* File Info */ - fileCont = (file != null ? file.isDeleted : void 0) ? { - innerHTML: "\"File" - } : file && boardID === 'f' ? { - innerHTML: "
File: " + E(file.name) + "-(" + E($.bytesToString(file.size)) + ", " + E(file.width) + "x" + E(file.height) + ", " + E(file.tag) + ")
" - } : file ? (file.isSpoiler ? (shortFilename = 'Spoiler Image', (spoilerRange = Build.spoilerRange[boardID]) ? fileThumb = staticPath + "spoiler-" + boardID + (Math.floor(1 + spoilerRange * Math.random())) + ".png" : fileThumb = staticPath + "spoiler.png", file.twidth = file.theight = 100) : (shortFilename = Build.shortFilename(file.name, !isOP), fileThumb = file.turl), fileSize = $.bytesToString(file.size), fileDims = file.url.slice(-4) === '.pdf' ? 'PDF' : file.width + "x" + file.height, fileLink = file.isSpoiler || file.name === shortFilename ? { - innerHTML: "" + E(shortFilename) + "" - } : { - innerHTML: "" + E(shortFilename) + "" - }, fileText = file.isSpoiler ? { - innerHTML: "
File: " + fileLink.innerHTML + " (" + E(fileSize) + ", " + E(fileDims) + ")
" - } : { - innerHTML: "
File: " + fileLink.innerHTML + " (" + E(fileSize) + ", " + E(fileDims) + ")
" - }, { - innerHTML: fileText.innerHTML + "\""" - }) : void 0; - fileBlock = file ? { - innerHTML: "
" + fileCont.innerHTML + "
" - } : { - innerHTML: "" + if (file && !file.isDeleted) { + shortFilename = Build.shortFilename(file.name); + fileSize = $.bytesToString(file.size); + fileDims = file.url.slice(-4) === '.pdf' ? 'PDF' : file.width + "x" + file.height; + fileThumb = file.isSpoiler ? Build.spoilerThumb(boardID) : file.turl; + } + fileBlock = { + innerHTML: (file ? "
" + (file.isDeleted ? "\"File" : (boardID === "f" ? "
File: " + E(file.name) + "-(" + E(fileSize) + ", " + E(fileDims) + ", " + E(file.tag) + ")
" : "
File: " + (file.isSpoiler ? "Spoiler Image" : E(shortFilename)) + " (" + E(fileSize) + ", " + E(fileDims) + ")
")) + "
" : "") }; /* Whole Post */ - highlightPost = capcode === 'admin_highlight' ? ' highlightPost' : ''; - message = { - innerHTML: "
" + comment.innerHTML + "
" - }; - wholePost = isOP ? { - innerHTML: "
" + fileBlock.innerHTML + postInfo.innerHTML + message.innerHTML + "
" - } : { - innerHTML: "
>>
" + postInfo.innerHTML + fileBlock.innerHTML + message.innerHTML + "
" + postClass = isOP ? 'op' : 'reply'; + wholePost = { + innerHTML: (!isOP ? "
>>
" : "") + "
" + (isOP ? fileBlock.innerHTML + postInfo.innerHTML : postInfo.innerHTML + fileBlock.innerHTML) + "
" + comment.innerHTML + "
" }; container = $.el('div', { - className: "postContainer " + (isOP ? 'op' : 'reply') + "Container", + className: "postContainer " + postClass + "Container", id: "pc" + postID }); $.extend(container, wholePost); @@ -4292,7 +4184,7 @@ }, excerptThread: function(board, data, OP) { var files, nodes, posts, ref; - nodes = [OP ? OP.nodes.root : Build.postFromObject(data, board.ID)]; + nodes = [OP ? OP.nodes.root : Build.postFromObject(data, board.ID, true)]; if (data.omitted_posts || !Conf['Show Replies'] && data.replies) { ref = Conf['Show Replies'] ? [ data.omitted_posts, data.images - data.last_replies.filter(function(data) { @@ -4307,7 +4199,7 @@ return Build.postFromObject(data, board.ID); }, catalogThread: function(thread) { - var br, cc, comment, data, exif, fileCount, gifIcon, href, imgClass, k, len1, len2, len3, len4, pageCount, postCount, pp, q, quote, ref, ref1, ref2, ref3, ref4, root, spoilerRange, src, staticPath, subject, thumb, u, w; + var br, cc, comment, data, exif, fileCount, gifIcon, href, imgClass, k, len1, len2, len3, len4, pageCount, postCount, pp, q, quote, ref, ref1, ref2, ref3, ref4, root, spoilerRange, src, staticPath, u, w; staticPath = Build.staticPath, gifIcon = Build.gifIcon; data = Index.liveThreadData[Index.liveThreadIDs.indexOf(thread.ID)]; if (data.spoiler && !Conf['Reveal Spoiler Thumbnails']) { @@ -4326,19 +4218,9 @@ src = staticPath + "nofile.png"; imgClass = 'no-file'; } - thumb = imgClass ? { - innerHTML: "" - } : { - innerHTML: "" - }; postCount = data.replies + 1; fileCount = data.images + !!data.ext; pageCount = Math.floor(Index.liveThreadIDs.indexOf(thread.ID) / Index.threadsNumPerPage) + 1; - subject = thread.OP.info.subject ? { - innerHTML: "
" + E(thread.OP.info.subject) + "
" - } : { - innerHTML: "" - }; comment = { innerHTML: data.com || '' }; @@ -4346,7 +4228,7 @@ className: 'catalog-thread' }); $.extend(root, { - innerHTML: "" + thumb.innerHTML + "
" + E(postCount) + " / " + E(fileCount) + " / " + E(pageCount) + "
" + subject.innerHTML + "
" + comment.innerHTML + "
" + innerHTML: "
" + E(postCount) + " / " + E(fileCount) + " / " + E(pageCount) + "
" + (thread.OP.info.subject ? "
" + E(thread.OP.info.subject) + "
" : "") + "
" + comment.innerHTML + "
" }); root.dataset.fullID = thread.fullID; if (thread.OP.highlights) { @@ -5912,7 +5794,7 @@ href: 'javascript:;' }); $.extend(a, { - innerHTML: "" + innerHTML: "" }); a.dataset.fullID = thread.fullID; $.on(a, 'click', ThreadHiding.toggle); @@ -6853,7 +6735,7 @@ className: "qr-link-container" }); $.extend(link, { - innerHTML: "" + E((g.VIEW === "thread") ? "Reply to Thread" : "Start a Thread") + "" + innerHTML: "" + (g.VIEW === "thread" ? "Reply to Thread" : "Start a Thread") + "" }); QR.link = link.firstElementChild; $.on(link.firstChild, 'click', function() { @@ -7315,7 +7197,7 @@ var dialog, event, i, items, m, match_max, match_min, name, node, nodes, ref, rules, save, setNode; QR.nodes = nodes = { el: dialog = UI.dialog('qr', 'top: 50px; right: 0px;', { - innerHTML: "
×
+
No selected file
" + innerHTML: "
×
+
No selected file
" }) }; setNode = function(name, query) { @@ -7544,7 +7426,7 @@ QR.cooldown.auto = false; QR.status(); return QR.error($.el('span', { - innerHTML: "4chan X encountered an error while posting. [Banned?] [More info]" + innerHTML: "4chan X encountered an error while posting. [Banned?] [More info]" })); } }; @@ -7593,7 +7475,7 @@ return QR.status(); }, response: function() { - var URL, _, ban, err, h1, isReply, m, open, post, postID, postsCount, ref, ref1, req, resDoc, threadID; + var URL, _, ban, err, h1, isReply, lastPostToThread, m, open, post, postID, postsCount, ref, ref1, req, resDoc, threadID; req = QR.req; delete QR.req; post = QR.posts[0]; @@ -7661,6 +7543,16 @@ }); postsCount = QR.posts.length - 1; QR.cooldown.auto = postsCount && isReply; + lastPostToThread = !((function() { + var k, len1, p, ref2; + ref2 = QR.posts.slice(1); + for (k = 0, len1 = ref2.length; k < len1; k++) { + p = ref2[k]; + if (p.thread === post.thread) { + return true; + } + } + })()); if (!(Conf['Persistent QR'] || postsCount)) { QR.close(); } else { @@ -7668,7 +7560,7 @@ QR.captcha.setup(d.activeElement === QR.nodes.status); } QR.cooldown.add(req.uploadEndTime, threadID, postID); - URL = threadID === postID ? window.location.origin + "/" + g.BOARD + "/thread/" + threadID : g.VIEW === 'index' && !QR.cooldown.auto && Conf['Open Post in New Tab'] ? window.location.origin + "/" + g.BOARD + "/thread/" + threadID + "#p" + postID : void 0; + URL = threadID === postID ? window.location.origin + "/" + g.BOARD + "/thread/" + threadID : g.VIEW === 'index' && lastPostToThread && Conf['Open Post in New Tab'] ? window.location.origin + "/" + g.BOARD + "/thread/" + threadID + "#p" + postID : void 0; if (URL) { open = Conf['Open Post in New Tab'] || postsCount ? function() { return $.open(URL); @@ -10292,7 +10184,7 @@ preload: 'none', loop: true, muted: true, - poster: thumb.src, + poster: thumb.src || thumb.dataset.src, textContent: thumb.alt, className: thumb.className }); @@ -10319,7 +10211,7 @@ return; } type = (match = URL.match(/\.([^.]+)$/)[1].toUpperCase()) === 'JPEG' ? 'JPG' : match; - replace = Conf["Replace " + type] && !/spoiler/.test(thumb.src); + replace = Conf["Replace " + type] && !/spoiler/.test(thumb.src || thumb.dataset.src); if (!(replace || Conf['prefetch'])) { return; } @@ -10352,7 +10244,8 @@ clone = ref1[q]; clone.file.thumb.src = URL; } - return thumb.src = URL; + thumb.src = URL; + return thumb.removeAttribute('data-src'); }); } return el.src = URL; @@ -10497,7 +10390,11 @@ thumb = this.file.thumb; thumb.removeAttribute('style'); thumb.style.maxHeight = thumb.style.maxWidth = this.isReply ? '125px' : '250px'; - return thumb.src = this.file.thumbURL; + if (thumb.src) { + return thumb.src = this.file.thumbURL; + } else { + return thumb.dataset.src = this.file.thumbURL; + } } }; @@ -11905,19 +11802,13 @@ return; } statsHTML = { - innerHTML: "? / ?" + innerHTML: "? / ?" + (Conf["IP Count in Stats"] ? " / ?" : "") + (Conf["Page Count in Stats"] ? " / ?" : "") }; statsTitle = 'Posts / Files'; if (Conf['IP Count in Stats']) { - statsHTML = { - innerHTML: statsHTML.innerHTML + " / ?" - }; statsTitle += ' / IPs'; } if (Conf['Page Count in Stats']) { - statsHTML = { - innerHTML: statsHTML.innerHTML + " / ?" - }; statsTitle += ' / Page'; } if (Conf['Updater and Stats in Header']) { @@ -14335,9 +14226,7 @@ return ''; }); return $.extend(outputNode, { - innerHTML: output.map(function(x) { - return x.innerHTML; - }).join('') + innerHTML: E.cat(output) }); }, formatters: { @@ -14381,15 +14270,9 @@ }; }, p: function() { - if (this.file.isSpoiler) { - return { - innerHTML: "Spoiler, " - }; - } else { - return { - innerHTML: "" - }; - } + return { + innerHTML: (this.file.isSpoiler ? "Spoiler, " : "") + }; }, s: function() { return { @@ -15441,9 +15324,8 @@ className: 'dialog' }); $.extend(dialog, { - innerHTML: "
" + innerHTML: "
" }); - $('a[href$="/CHANGELOG.md"]', dialog).textContent = g.VERSION; Settings.overlay = overlay = $.el('div', { id: 'overlay' }); @@ -15774,7 +15656,7 @@ filter: function(section) { var select; $.extend(section, { - innerHTML: "
" + innerHTML: "
" }); select = $('select', section); $.on(select, 'change', Settings.selectFilter); @@ -15798,7 +15680,7 @@ return; } $.extend(div, { - innerHTML: "
Filter is disabled.

Use regular expressions, one per line.
Lines starting with a # will be ignored.
For example, /weeaboo/i will filter posts containing the string \`weeaboo\`, case-insensitive.
MD5 filtering uses exact string matching, not regular expressions.

Note: If you're using the native catalog rather than 4chan X's catalog, 4chan X's filters do not apply there.
The native catalog has its own separate filter list.

" + innerHTML: "
Filter is disabled.

Use regular expressions, one per line.
Lines starting with a # will be ignored.
For example, /weeaboo/i will filter posts containing the string \`weeaboo\`, case-insensitive.
MD5 filtering uses exact string matching, not regular expressions.

Note: If you're using the native catalog rather than 4chan X's catalog, 4chan X's filters do not apply there.
The native catalog has its own separate filter list.

" }); return $('.warning', div).hidden = Conf['Filter']; }, @@ -15817,7 +15699,7 @@ advanced: function(section) { var aa, applyCSS, archBoards, 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, w, warning, withCredentials, y, z; $.extend(section, { - innerHTML: "
Archiver
404 Redirect is disabled.
Thread redirectionPost fetchingFile redirection
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)
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:
" + innerHTML: "
Archiver
404 Redirect is disabled.
Thread redirectionPost fetchingFile redirection
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)
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:
" }); ref = $$('.warning', section); for (k = 0, len1 = ref.length; k < len1; k++) { @@ -16044,7 +15926,7 @@ keybinds: function(section) { var arr, input, inputs, items, key, ref, tbody, tr; $.extend(section, { - innerHTML: "
Keybinds are disabled.
Allowed keys: a-z, 0-9, Ctrl, Shift, Alt, Meta, Enter, Esc, Up, Down, Right, Left.
Press Backspace to disable a keybind.
ActionsKeybinds
" + innerHTML: "
Keybinds are disabled.
Allowed keys: a-z, 0-9, Ctrl, Shift, Alt, Meta, Enter, Esc, Up, Down, Right, Left.
Press Backspace to disable a keybind.
ActionsKeybinds
" }); $('.warning', section).hidden = Conf['Keybinds']; tbody = $('tbody', section); @@ -16312,7 +16194,7 @@ } if (previousversion) { el = $.el('span', { - innerHTML: E(g.NAME) + " has been updated to version " + E(g.VERSION) + "." + innerHTML: "4chan X has been updated to version " + E(g.VERSION) + "." }); new Notice('info', el, 15); } else { diff --git a/builds/4chan-X.zip b/builds/4chan-X.zip index a56177bb9..f5c23ff12 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 070236a2c..c1274a8b0 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 e65a76975..64244344e 100644 --- a/builds/updates.xml +++ b/builds/updates.xml @@ -1,7 +1,7 @@ - + diff --git a/package.json b/package.json index 098223a95..dd60320ff 100755 --- a/package.json +++ b/package.json @@ -3,8 +3,8 @@ "description": "Cross-browser userscript for maximum lurking on 4chan.", "meta": { "name": "4chan X", - "version": "1.10.6.7", - "date": "2015-03-27T02:03:38.514Z", + "version": "1.10.7.0", + "date": "2015-03-29T21:58:51.453Z", "repo": "https://github.com/ccd0/4chan-x/", "page": "https://github.com/ccd0/4chan-x", "downloads": "https://ccd0.github.io/4chan-x/builds/",