diff --git a/CHANGELOG.md b/CHANGELOG.md index e91ae2b58..b1e203470 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ The links to individual versions below are to copies of the script with the upda ### v1.10.11 +**v1.10.11.2** *(2015-04-25)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.11.2/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.11.2/builds/4chan-X-noupdate.crx "Chromium version")] +- Posts hidden by filtering are no longer counted as unread posts in the thread watcher. +- Add Flash tag (`%g`) to File Info Formatting. +- Fix subject not being displayed in old non-OP posts loaded from the archives. + **v1.10.11.1** *(2015-04-24)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.11.1/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.10.11.1/builds/4chan-X-noupdate.crx "Chromium version")] - Merge v1.10.10.3: Fix original post form not showing when JS is disabled. diff --git a/builds/4chan-X-beta.crx b/builds/4chan-X-beta.crx index 2b8231c04..7560aa1cf 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 436e671dc..9418befbc 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.11.1 +// @version 1.10.11.2 // @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 2044b92ee..4d1c3907c 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.11.1 +// @version 1.10.11.2 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -100,11 +100,8 @@ * audio/beep.wav from http://freesound.org/people/pierrecartoons1979/sounds/90112/ * cc-by-nc-3.0 * -* 4chan/4chan-JS (https://github.com/4chan/4chan-JS) -* Copyright (c) 2012-2013, 4chan LLC -* All rights reserved. -* -* license: https://github.com/4chan/4chan-JS/blob/master/LICENSE +* Font Awesome by Dave Gandy (http://fontawesome.io) +* license: http://fontawesome.io/license/ */ 'use strict'; @@ -327,7 +324,7 @@ }, time: '%m/%d/%y(%a)%H:%M:%S', backlink: '>>%id', - fileInfo: '%l (%p%s, %r)', + fileInfo: '%l (%p%s, %r%g)', favicon: 'ferongr', usercss: '', hotkeys: { @@ -399,7 +396,7 @@ doc = d.documentElement; g = { - VERSION: '1.10.11.1', + VERSION: '1.10.11.2', NAMESPACE: '4chan X.', boards: {} }; @@ -1245,7 +1242,7 @@ this.info.nameBlock = Conf['Anonymize'] ? 'Anonymous' : this.nodes.nameBlock.textContent.trim(); if (subject = $('.subject', info)) { this.nodes.subject = subject; - this.info.subject = subject.textContent; + this.info.subject = subject.textContent || void 0; } if (name = $('.name', info)) { this.nodes.name = name; @@ -1362,7 +1359,7 @@ }; Post.prototype.parseFile = function() { - var fileEl, fileText, info, link, ref, ref1, size, thumb, unit; + var fileEl, fileText, info, link, m, ref, ref1, ref2, size, thumb, unit; if (!(fileEl = $('.file', this.nodes.post))) { return; } @@ -1376,12 +1373,13 @@ this.file = { text: fileText, link: link, - URL: link.href, + url: link.href, name: fileText.title || link.title || link.textContent, size: info[1], isImage: /(jpg|png|gif)$/i.test(link.href), isVideo: /webm$/i.test(link.href), - dimensions: (ref1 = info[0].match(/\d+x\d+/)) != null ? ref1[0] : void 0 + dimensions: (ref1 = info[0].match(/\d+x\d+/)) != null ? ref1[0] : void 0, + tag: (ref2 = info[0].match(/, ([a-z]+)\)/i)) != null ? ref2[1] : void 0 }; size = +this.file.size.match(/[\d.]+/)[0]; unit = ['B', 'KB', 'MB', 'GB'].indexOf(this.file.size.match(/\w+$/)[0]); @@ -1392,7 +1390,7 @@ 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", + thumbURL: (m = link.href.match(/\d+(?=\.\w+$)/)) ? location.protocol + "//i.4cdn.org/" + this.board + "/" + m[0] + "s.jpg" : void 0, MD5: thumb.dataset.md5, isSpoiler: $.hasClass(thumb.parentNode, 'imgspoiler') }); @@ -2262,41 +2260,49 @@ postID: this.postID, threadID: this.threadID, boardID: this.boardID, - name: data.name, + isReply: this.postID !== this.threadID + }; + o.info = { + subject: data.title, + email: data.email, + name: data.name || '', + tripcode: data.trip, capcode: (function() { switch (data.capcode) { case 'M': - return 'mod'; + return 'Mod'; case 'A': - return 'admin'; + return 'Admin'; case 'D': - return 'developer'; + return 'Developer'; } })(), - tripcode: data.trip, uniqueID: data.poster_hash, - email: data.email || '', - subject: data.title, flagCode: data.poster_country, - flagName: data.poster_country_name, - date: data.fourchan_date, + flag: data.poster_country_name, dateUTC: data.timestamp, - comment: comment + dateText: data.fourchan_date, + commentHTML: comment }; + if (o.info.capcode) { + delete o.info.uniqueID; + } if ((ref = data.media) != null ? ref.media_filename : void 0) { o.file = { name: data.media.media_filename, - timestamp: data.media.media_orig, - url: data.media.media_link || data.media.remote_media_link || ("//i.4cdn.org/" + this.boardID + "/" + (encodeURIComponent(data.media[this.boardID === 'f' ? 'media_filename' : 'media_orig']))), + url: data.media.media_link || data.media.remote_media_link || (location.protocol + "//i.4cdn.org/" + this.boardID + "/" + (encodeURIComponent(data.media[this.boardID === 'f' ? 'media_filename' : 'media_orig']))), height: data.media.media_h, width: data.media.media_w, MD5: data.media.media_hash, - size: data.media.media_size, - turl: data.media.thumb_link || ("//i.4cdn.org/" + this.boardID + "/" + data.media.preview_orig), + size: $.bytesToString(data.media.media_size), + thumbURL: data.media.thumb_link || (location.protocol + "//i.4cdn.org/" + this.boardID + "/" + data.media.preview_orig), theight: data.media.preview_h, twidth: data.media.preview_w, isSpoiler: data.media.spoiler === '1' }; + if (!/\.pdf$/.test(o.file.url)) { + o.file.dimensions = o.file.width + "x" + o.file.height; + } if (this.boardID === 'f') { o.file.tag = JSON.parse(data.media.exif).Tag; } @@ -2306,7 +2312,7 @@ post = new Post(Build.post(o), thread, board); post.kill(); if (post.file) { - post.file.thumbURL = o.file.turl; + post.file.thumbURL = o.file.thumbURL; } post.isFetchedQuote = true; Main.callbackNodes(Post, [post]); @@ -4013,13 +4019,14 @@ if (text == null) { return text; } - return text.replace(/<[^>]*>/g, '').replace(/&(amp|#039|quot|lt|gt);/g, function(c) { + return text.replace(/<[^>]*>/g, '').replace(/&(amp|#039|quot|lt|gt|#44);/g, function(c) { return { '&': '&', ''': "'", '"': '"', '<': '<', - '>': '>' + '>': '>', + ',': ',' }[c]; }); }, @@ -4051,112 +4058,121 @@ return "/" + boardID + "/thread/" + threadID + "#p" + postID; } }, - postFromObject: function(data, boardID, suppressThumb) { + parseJSON: function(data, boardID) { var o; o = { postID: data.no, threadID: data.resto || data.no, boardID: boardID, - name: Build.unescape(data.name), - capcode: data.capcode, - tripcode: data.trip, - uniqueID: data.id, - email: Build.unescape(data.email), - subject: Build.unescape(data.sub), - flagCode: data.country, - flagName: Build.unescape(data.country_name), - date: data.now, - dateUTC: data.time, - comment: { - innerHTML: data.com || '' - }, + isReply: !!data.resto, isSticky: !!data.sticky, isClosed: !!data.closed, - isArchived: !!data.archived + isArchived: !!data.archived, + fileDeleted: !!data.filedeleted }; - if (data.filedeleted) { - o.file = { - isDeleted: true - }; - } else if (data.ext) { + o.info = { + subject: Build.unescape(data.sub), + email: Build.unescape(data.email), + name: Build.unescape(data.name) || '', + tripcode: data.trip, + uniqueID: data.id, + flagCode: data.country, + flag: Build.unescape(data.country_name), + dateUTC: data.time, + dateText: data.now, + commentHTML: { + innerHTML: data.com || '' + } + }; + if (data.capcode) { + o.info.capcode = data.capcode.replace(/_highlight$/, '').replace(/_/g, ' ').replace(/\b\w/g, function(c) { + return c.toUpperCase(); + }); + o.capcodeHighlight = /_highlight$/.test(data.capcode); + delete o.info.uniqueID; + } + if (data.ext) { o.file = { name: (Build.unescape(data.filename)) + data.ext, - timestamp: "" + data.tim + data.ext, - url: boardID === 'f' ? "//i.4cdn.org/" + boardID + "/" + (encodeURIComponent(data.filename)) + data.ext : "//i.4cdn.org/" + boardID + "/" + data.tim + data.ext, + url: boardID === 'f' ? location.protocol + "//i.4cdn.org/" + boardID + "/" + (encodeURIComponent(data.filename)) + data.ext : location.protocol + "//i.4cdn.org/" + boardID + "/" + data.tim + data.ext, height: data.h, width: data.w, MD5: data.md5, - size: data.fsize, - turl: "//i.4cdn.org/" + boardID + "/" + data.tim + "s.jpg", + size: $.bytesToString(data.fsize), + thumbURL: location.protocol + "//i.4cdn.org/" + boardID + "/" + data.tim + "s.jpg", theight: data.tn_h, twidth: data.tn_w, isSpoiler: !!data.spoiler, - isDeleted: false, tag: data.tag }; + if (!/\.pdf$/.test(o.file.url)) { + o.file.dimensions = o.file.width + "x" + o.file.height; + } } + return o; + }, + parseComment: function(o) { + var html; + html = o.info.commentHTML.innerHTML.replace(//gi, '\n').replace(/\n\nRolled [^<]*<\/b>/i, '').replace(/]*>/g, ''); + return o.info.comment = Build.unescape(html); + }, + postFromObject: function(data, boardID, suppressThumb) { + var o; + o = Build.parseJSON(data, boardID); return Build.post(o, suppressThumb); }, 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, 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; + var boardID, capcode, capcodeDescription, capcodeLC, capcodeLong, capcodePlural, capcodeUC, commentHTML, container, dateText, dateUTC, email, file, fileBlock, fileThumb, fileURL, flag, flagCode, gifIcon, href, k, len1, match, name, postClass, postID, postInfo, postLink, protocol, quote, quoteLink, ref, ref1, shortFilename, staticPath, subject, threadID, tripcode, uniqueID, wholePost; + postID = o.postID, threadID = o.threadID, boardID = o.boardID, file = o.file; + ref = o.info, subject = ref.subject, email = ref.email, name = ref.name, tripcode = ref.tripcode, capcode = ref.capcode, uniqueID = ref.uniqueID, flagCode = ref.flagCode, flag = ref.flag, dateUTC = ref.dateUTC, dateText = ref.dateText, commentHTML = ref.commentHTML; staticPath = Build.staticPath, gifIcon = Build.gifIcon; /* Post Info */ 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'; + capcodeUC = capcode.split(' ')[0]; + capcodeLC = capcodeUC.toLowerCase(); + if (capcode === 'Admin Emeritus') { capcodePlural = 'the Administrator Emeritus'; capcodeDescription = "4chan's founding Administrator"; + } else { + capcodeLong = { + 'Admin': 'Administrator', + 'Mod': 'Moderator' + }[capcode] || capcode; + capcodePlural = capcodeLong + "s"; + capcodeDescription = "a 4chan " + capcodeLong; } } postLink = Build.postURL(boardID, threadID, postID); quoteLink = Build.sameThread(boardID, threadID) ? "javascript:quote('" + (+postID) + "');" : "/" + boardID + "/thread/" + threadID + "#q" + postID; postInfo = { - 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]" : "") + "
" + innerHTML: "
" + (!o.isReply || boardID === "f" || subject ? "" + E(subject || "") + " " : "") + "" + (email ? "" : "") + "" + E(name) + "" + (tripcode ? " " + E(tripcode) + "" : "") + (capcode ? " ## " + E(capcode) + "" : "") + (email ? "" : "") + (boardID === "f" && !o.isReply || capcode ? "" : " ") + (capcode ? " \""" : "") + (uniqueID && !capcode ? " (ID: " + E(uniqueID) + ")" : "") + (flagCode ? " " : "") + " " + E(dateText) + " No." + E(postID) + "" + (o.isSticky ? " \"Sticky\"" : "") + (o.isClosed && !o.isArchived ? " \"Closed\"" : "") + (o.isArchived ? " \"Archived\"" : "") + (!o.isReply && g.VIEW === "index" ? "   [Reply]" : "") + "
" }; /* File Info */ - if (file && !file.isDeleted) { + if (file) { + protocol = /^https?:(?=\/\/i\.4cdn\.org\/)/; + fileURL = file.url.replace(protocol, ''); 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; + fileThumb = file.isSpoiler ? Build.spoilerThumb(boardID) : file.thumbURL.replace(protocol, ''); } 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) + ")
")) + "
" : "") + innerHTML: (file ? "
" + (boardID === "f" ? "
File: " + E(file.name) + "-(" + E(file.size) + ", " + E(file.dimensions) + ", " + E(file.tag) + ")
" : "
File: " + (file.isSpoiler ? "Spoiler Image" : E(shortFilename)) + " (" + E(file.size) + ", " + E(file.dimensions || "PDF") + ")
") + "
" : (o.fileDeleted ? "
\"File
" : "")) }; /* Whole Post */ - postClass = isOP ? 'op' : 'reply'; + postClass = o.isReply ? 'reply' : 'op'; wholePost = { - innerHTML: (!isOP ? "
>>
" : "") + "
" + (isOP ? fileBlock.innerHTML + postInfo.innerHTML : postInfo.innerHTML + fileBlock.innerHTML) + "
" + comment.innerHTML + "
" + innerHTML: (o.isReply ? "
>>
" : "") + "
" + (o.isReply ? postInfo.innerHTML + fileBlock.innerHTML : fileBlock.innerHTML + postInfo.innerHTML) + "
" + commentHTML.innerHTML + "
" }; container = $.el('div', { className: "postContainer " + postClass + "Container", id: "pc" + postID }); $.extend(container, wholePost); - ref = $$('.quotelink', container); - for (k = 0, len1 = ref.length; k < len1; k++) { - quote = ref[k]; + ref1 = $$('.quotelink', container); + for (k = 0, len1 = ref1.length; k < len1; k++) { + quote = ref1[k]; href = quote.getAttribute('href'); if ((href[0] === '#') && !(Build.sameThread(boardID, threadID))) { quote.href = ("/" + boardID + "/thread/" + threadID) + href; @@ -5112,6 +5128,23 @@ } } }, + isHidden: function(post) { + var filter, k, key, len1, ref, result, value; + for (key in Filter.filters) { + if ((value = Filter[key](post)) != null) { + ref = Filter.filters[key]; + for (k = 0, len1 = ref.length; k < len1; k++) { + filter = ref[k]; + if (result = filter(value, post.isReply)) { + if (result.hide) { + return true; + } + } + } + } + } + return false; + }, name: function(post) { return post.info.name; }, @@ -5125,10 +5158,11 @@ return post.info.capcode; }, subject: function(post) { - return post.info.subject || void 0; + return post.info.subject; }, comment: function(post) { - return post.info.comment; + var ref; + return (ref = post.info.comment) != null ? ref : Build.parseComment(post); }, flag: function(post) { return post.info.flag; @@ -9289,7 +9323,7 @@ Gallery.fullIDs[post.fullID] = true; thumb = $.el('a', { className: 'gal-thumb', - href: post.file.URL, + href: post.file.url, target: '_blank', title: post.file.name }); @@ -9641,7 +9675,7 @@ }, error: function(file, post, delay, cb) { var URL, redirect, src, timeoutID; - src = post.file.URL.split('/'); + src = post.file.url.split('/'); URL = Redirect.to('file', { boardID: post.board.ID, filename: src[src.length - 1] @@ -9691,7 +9725,7 @@ post.kill(true); return redirect(); } else { - return URL = post.file.URL; + return URL = post.file.url; } } }); @@ -9886,7 +9920,7 @@ if (file.videoControls) { $.rm(file.videoControls); } - file.thumb.parentNode.href = file.URL; + file.thumb.parentNode.href = file.url; file.thumb.parentNode.target = '_blank'; ref = ['isExpanding', 'isExpanded', 'videoControls', 'wasPlaying', 'scrollIntoView']; for (k = 0, len1 = ref.length; k < len1; k++) { @@ -9953,7 +9987,7 @@ el = file.fullImage = $.el((isVideo ? 'video' : 'img')); el.dataset.fullID = post.fullID; $.on(el, 'error', ImageExpand.error); - el.src = src || file.URL; + el.src = src || file.url; } el.className = 'full-image'; $.after(thumb, el); @@ -10182,7 +10216,7 @@ el = $.el((isVideo ? 'video' : 'img')); el.dataset.fullID = post.fullID; $.on(el, 'error', error); - el.src = file.URL; + el.src = file.url; } if (Conf['Restart when Opened']) { ImageCommon.rewind(el); @@ -10313,22 +10347,22 @@ attr = ref[k]; video.style[attr] = thumb.style[attr]; } - video.src = file.URL; + video.src = file.url; $.replace(thumb, video); file.thumb = video; return file.videoThumb = true; }, prefetch: function(post) { - var URL, clone, el, file, isImage, isVideo, k, len1, match, ref, replace, thumb, type; + var clone, el, file, isImage, isVideo, k, len1, match, ref, replace, thumb, type, url; file = post.file; if (!file) { return; } - isImage = file.isImage, isVideo = file.isVideo, thumb = file.thumb, URL = file.URL; + isImage = file.isImage, isVideo = file.isVideo, thumb = file.thumb, url = file.url; if (file.isPrefetched || !(isImage || isVideo) || post.isHidden || post.thread.isHidden) { return; } - type = (match = URL.match(/\.([^.]+)$/)[1].toUpperCase()) === 'JPEG' ? 'JPG' : match; + type = (match = url.match(/\.([^.]+)$/)[1].toUpperCase()) === 'JPEG' ? 'JPG' : match; replace = Conf["Replace " + type] && !/spoiler/.test(thumb.src || thumb.dataset.src); if (!(replace || Conf['prefetch'])) { return; @@ -10360,13 +10394,13 @@ ref1 = post.clones; for (q = 0, len2 = ref1.length; q < len2; q++) { clone = ref1[q]; - clone.file.thumb.src = URL; + clone.file.thumb.src = url; } - thumb.src = URL; + thumb.src = url; return thumb.removeAttribute('data-src'); }); } - return el.src = URL; + return el.src = url; }, toggle: function() { if (Conf['prefetch'] = this.checked) { @@ -10408,7 +10442,7 @@ }, node: function() { var el; - if (!(this.file && /webm$/i.test(this.file.URL))) { + if (!(this.file && /webm$/i.test(this.file.url))) { return; } if (this.isClone) { @@ -10429,7 +10463,7 @@ load: function() { $.rmClass(this.parentNode, 'error'); $.addClass(this.parentNode, 'loading'); - return CrossOrigin.binary(Get.postFromNode(this).file.URL, (function(_this) { + return CrossOrigin.binary(Get.postFromNode(this).file.url, (function(_this) { return function(data) { var output, title; $.rmClass(_this.parentNode, 'loading'); @@ -10563,15 +10597,15 @@ } } parts['text'] || (parts['text'] = ((ref1 = parts['url'].match(/(\w+)\.\w+\//)) != null ? ref1[1] : void 0) || '?'); - ext = post.file.URL.match(/[^.]*$/)[0]; + ext = post.file.url.match(/[^.]*$/)[0]; skip = false; for (key in parts) { parts[key] = parts[key].replace(/%(T?URL|IMG|MD5|board|name|%|semi)/g, function(parameter) { var type; type = { '%TURL': post.file.thumbURL, - '%URL': post.file.URL, - '%IMG': ext === 'gif' || ext === 'jpg' || ext === 'png' ? post.file.URL : post.file.thumbURL, + '%URL': post.file.url, + '%IMG': ext === 'gif' || ext === 'jpg' || ext === 'png' ? post.file.url : post.file.thumbURL, '%MD5': post.file.MD5, '%board': post.board.ID, '%name': post.file.name, @@ -11716,7 +11750,7 @@ if (!file) { return false; } - a.href = file.URL; + a.href = file.url; a.download = file.name; return true; } @@ -12797,6 +12831,9 @@ }) : void 0) { continue; } + if (Filter.isHidden(Build.parseJSON(postObj, boardID))) { + continue; + } unread++; if (!(QR.db && postObj.com)) { continue; @@ -14368,22 +14405,22 @@ formatters: { t: function() { return { - innerHTML: E(this.file.URL.match(/[^/]*$/)[0]) + innerHTML: E(this.file.url.match(/[^/]*$/)[0]) }; }, T: function() { return { - innerHTML: "" + FileInfo.formatters.t.call(this).innerHTML + "" + innerHTML: "" + FileInfo.formatters.t.call(this).innerHTML + "" }; }, l: function() { return { - innerHTML: "" + FileInfo.formatters.n.call(this).innerHTML + "" + innerHTML: "" + FileInfo.formatters.n.call(this).innerHTML + "" }; }, L: function() { return { - innerHTML: "" + FileInfo.formatters.N.call(this).innerHTML + "" + innerHTML: "" + FileInfo.formatters.N.call(this).innerHTML + "" }; }, n: function() { @@ -14435,6 +14472,11 @@ innerHTML: E(this.file.dimensions || "PDF") }; }, + g: function() { + return { + innerHTML: (this.file.tag ? ", " + E(this.file.tag) : "") + }; + }, '%': function() { return { innerHTML: "%" @@ -15892,7 +15934,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.

    You can use these settings with each item, separate them with semicolons:
  • Possible items are: name, options (or equivalently email), subject and password.
  • Wrap values of items with quotes, like this: options:"sage".
  • Force values as defaults with the always keyword, for example: options:"sage";always.
  • Select specific boards for an item, separated with commas, for example: options:"sage";boards:jp;always.
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)
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.

    You can use these settings with each item, separate them with semicolons:
  • Possible items are: name, options (or equivalently email), subject and password.
  • Wrap values of items with quotes, like this: options:"sage".
  • Force values as defaults with the always keyword, for example: options:"sage";always.
  • Select specific boards for an item, separated with commas, for example: options:"sage";boards:jp;always.
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++) { @@ -16082,13 +16124,15 @@ data = { isReply: true, file: { - URL: '//i.4cdn.org/g/1334437723720.jpg', + url: '//i.4cdn.org/g/1334437723720.jpg', name: 'd9bb2efc98dd0df141a94399ff5880b7.jpg', size: '276 KB', sizeInBytes: 276 * 1024, dimensions: '1280x720', isImage: true, - isSpoiler: true + isVideo: false, + isSpoiler: true, + tag: 'Loop' } }; return FileInfo.format(this.value, data, this.nextElementSibling); @@ -18403,6 +18447,7 @@ " background: linear-gradient(to bottom, #F8F8F8, #DCDCDC) no-repeat;\n" + " border: 1px solid #BBB;\n" + " border-radius: 2px;\n" + +" height: 100%;\n" + "}\n" + "#qr-file-button {\n" + " width: 15%;\n" + diff --git a/builds/4chan-X-noupdate.crx b/builds/4chan-X-noupdate.crx index e2a5bfd2a..c77066a0a 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 831d8bd32..5b538cc82 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.11.1 +// @version 1.10.11.2 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -99,11 +99,8 @@ * audio/beep.wav from http://freesound.org/people/pierrecartoons1979/sounds/90112/ * cc-by-nc-3.0 * -* 4chan/4chan-JS (https://github.com/4chan/4chan-JS) -* Copyright (c) 2012-2013, 4chan LLC -* All rights reserved. -* -* license: https://github.com/4chan/4chan-JS/blob/master/LICENSE +* Font Awesome by Dave Gandy (http://fontawesome.io) +* license: http://fontawesome.io/license/ */ 'use strict'; @@ -326,7 +323,7 @@ }, time: '%m/%d/%y(%a)%H:%M:%S', backlink: '>>%id', - fileInfo: '%l (%p%s, %r)', + fileInfo: '%l (%p%s, %r%g)', favicon: 'ferongr', usercss: '', hotkeys: { @@ -398,7 +395,7 @@ doc = d.documentElement; g = { - VERSION: '1.10.11.1', + VERSION: '1.10.11.2', NAMESPACE: '4chan X.', boards: {} }; @@ -1244,7 +1241,7 @@ this.info.nameBlock = Conf['Anonymize'] ? 'Anonymous' : this.nodes.nameBlock.textContent.trim(); if (subject = $('.subject', info)) { this.nodes.subject = subject; - this.info.subject = subject.textContent; + this.info.subject = subject.textContent || void 0; } if (name = $('.name', info)) { this.nodes.name = name; @@ -1361,7 +1358,7 @@ }; Post.prototype.parseFile = function() { - var fileEl, fileText, info, link, ref, ref1, size, thumb, unit; + var fileEl, fileText, info, link, m, ref, ref1, ref2, size, thumb, unit; if (!(fileEl = $('.file', this.nodes.post))) { return; } @@ -1375,12 +1372,13 @@ this.file = { text: fileText, link: link, - URL: link.href, + url: link.href, name: fileText.title || link.title || link.textContent, size: info[1], isImage: /(jpg|png|gif)$/i.test(link.href), isVideo: /webm$/i.test(link.href), - dimensions: (ref1 = info[0].match(/\d+x\d+/)) != null ? ref1[0] : void 0 + dimensions: (ref1 = info[0].match(/\d+x\d+/)) != null ? ref1[0] : void 0, + tag: (ref2 = info[0].match(/, ([a-z]+)\)/i)) != null ? ref2[1] : void 0 }; size = +this.file.size.match(/[\d.]+/)[0]; unit = ['B', 'KB', 'MB', 'GB'].indexOf(this.file.size.match(/\w+$/)[0]); @@ -1391,7 +1389,7 @@ 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", + thumbURL: (m = link.href.match(/\d+(?=\.\w+$)/)) ? location.protocol + "//i.4cdn.org/" + this.board + "/" + m[0] + "s.jpg" : void 0, MD5: thumb.dataset.md5, isSpoiler: $.hasClass(thumb.parentNode, 'imgspoiler') }); @@ -2261,41 +2259,49 @@ postID: this.postID, threadID: this.threadID, boardID: this.boardID, - name: data.name, + isReply: this.postID !== this.threadID + }; + o.info = { + subject: data.title, + email: data.email, + name: data.name || '', + tripcode: data.trip, capcode: (function() { switch (data.capcode) { case 'M': - return 'mod'; + return 'Mod'; case 'A': - return 'admin'; + return 'Admin'; case 'D': - return 'developer'; + return 'Developer'; } })(), - tripcode: data.trip, uniqueID: data.poster_hash, - email: data.email || '', - subject: data.title, flagCode: data.poster_country, - flagName: data.poster_country_name, - date: data.fourchan_date, + flag: data.poster_country_name, dateUTC: data.timestamp, - comment: comment + dateText: data.fourchan_date, + commentHTML: comment }; + if (o.info.capcode) { + delete o.info.uniqueID; + } if ((ref = data.media) != null ? ref.media_filename : void 0) { o.file = { name: data.media.media_filename, - timestamp: data.media.media_orig, - url: data.media.media_link || data.media.remote_media_link || ("//i.4cdn.org/" + this.boardID + "/" + (encodeURIComponent(data.media[this.boardID === 'f' ? 'media_filename' : 'media_orig']))), + url: data.media.media_link || data.media.remote_media_link || (location.protocol + "//i.4cdn.org/" + this.boardID + "/" + (encodeURIComponent(data.media[this.boardID === 'f' ? 'media_filename' : 'media_orig']))), height: data.media.media_h, width: data.media.media_w, MD5: data.media.media_hash, - size: data.media.media_size, - turl: data.media.thumb_link || ("//i.4cdn.org/" + this.boardID + "/" + data.media.preview_orig), + size: $.bytesToString(data.media.media_size), + thumbURL: data.media.thumb_link || (location.protocol + "//i.4cdn.org/" + this.boardID + "/" + data.media.preview_orig), theight: data.media.preview_h, twidth: data.media.preview_w, isSpoiler: data.media.spoiler === '1' }; + if (!/\.pdf$/.test(o.file.url)) { + o.file.dimensions = o.file.width + "x" + o.file.height; + } if (this.boardID === 'f') { o.file.tag = JSON.parse(data.media.exif).Tag; } @@ -2305,7 +2311,7 @@ post = new Post(Build.post(o), thread, board); post.kill(); if (post.file) { - post.file.thumbURL = o.file.turl; + post.file.thumbURL = o.file.thumbURL; } post.isFetchedQuote = true; Main.callbackNodes(Post, [post]); @@ -4012,13 +4018,14 @@ if (text == null) { return text; } - return text.replace(/<[^>]*>/g, '').replace(/&(amp|#039|quot|lt|gt);/g, function(c) { + return text.replace(/<[^>]*>/g, '').replace(/&(amp|#039|quot|lt|gt|#44);/g, function(c) { return { '&': '&', ''': "'", '"': '"', '<': '<', - '>': '>' + '>': '>', + ',': ',' }[c]; }); }, @@ -4050,112 +4057,121 @@ return "/" + boardID + "/thread/" + threadID + "#p" + postID; } }, - postFromObject: function(data, boardID, suppressThumb) { + parseJSON: function(data, boardID) { var o; o = { postID: data.no, threadID: data.resto || data.no, boardID: boardID, - name: Build.unescape(data.name), - capcode: data.capcode, - tripcode: data.trip, - uniqueID: data.id, - email: Build.unescape(data.email), - subject: Build.unescape(data.sub), - flagCode: data.country, - flagName: Build.unescape(data.country_name), - date: data.now, - dateUTC: data.time, - comment: { - innerHTML: data.com || '' - }, + isReply: !!data.resto, isSticky: !!data.sticky, isClosed: !!data.closed, - isArchived: !!data.archived + isArchived: !!data.archived, + fileDeleted: !!data.filedeleted }; - if (data.filedeleted) { - o.file = { - isDeleted: true - }; - } else if (data.ext) { + o.info = { + subject: Build.unescape(data.sub), + email: Build.unescape(data.email), + name: Build.unescape(data.name) || '', + tripcode: data.trip, + uniqueID: data.id, + flagCode: data.country, + flag: Build.unescape(data.country_name), + dateUTC: data.time, + dateText: data.now, + commentHTML: { + innerHTML: data.com || '' + } + }; + if (data.capcode) { + o.info.capcode = data.capcode.replace(/_highlight$/, '').replace(/_/g, ' ').replace(/\b\w/g, function(c) { + return c.toUpperCase(); + }); + o.capcodeHighlight = /_highlight$/.test(data.capcode); + delete o.info.uniqueID; + } + if (data.ext) { o.file = { name: (Build.unescape(data.filename)) + data.ext, - timestamp: "" + data.tim + data.ext, - url: boardID === 'f' ? "//i.4cdn.org/" + boardID + "/" + (encodeURIComponent(data.filename)) + data.ext : "//i.4cdn.org/" + boardID + "/" + data.tim + data.ext, + url: boardID === 'f' ? location.protocol + "//i.4cdn.org/" + boardID + "/" + (encodeURIComponent(data.filename)) + data.ext : location.protocol + "//i.4cdn.org/" + boardID + "/" + data.tim + data.ext, height: data.h, width: data.w, MD5: data.md5, - size: data.fsize, - turl: "//i.4cdn.org/" + boardID + "/" + data.tim + "s.jpg", + size: $.bytesToString(data.fsize), + thumbURL: location.protocol + "//i.4cdn.org/" + boardID + "/" + data.tim + "s.jpg", theight: data.tn_h, twidth: data.tn_w, isSpoiler: !!data.spoiler, - isDeleted: false, tag: data.tag }; + if (!/\.pdf$/.test(o.file.url)) { + o.file.dimensions = o.file.width + "x" + o.file.height; + } } + return o; + }, + parseComment: function(o) { + var html; + html = o.info.commentHTML.innerHTML.replace(//gi, '\n').replace(/\n\nRolled [^<]*<\/b>/i, '').replace(/]*>/g, ''); + return o.info.comment = Build.unescape(html); + }, + postFromObject: function(data, boardID, suppressThumb) { + var o; + o = Build.parseJSON(data, boardID); return Build.post(o, suppressThumb); }, 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, 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; + var boardID, capcode, capcodeDescription, capcodeLC, capcodeLong, capcodePlural, capcodeUC, commentHTML, container, dateText, dateUTC, email, file, fileBlock, fileThumb, fileURL, flag, flagCode, gifIcon, href, k, len1, match, name, postClass, postID, postInfo, postLink, protocol, quote, quoteLink, ref, ref1, shortFilename, staticPath, subject, threadID, tripcode, uniqueID, wholePost; + postID = o.postID, threadID = o.threadID, boardID = o.boardID, file = o.file; + ref = o.info, subject = ref.subject, email = ref.email, name = ref.name, tripcode = ref.tripcode, capcode = ref.capcode, uniqueID = ref.uniqueID, flagCode = ref.flagCode, flag = ref.flag, dateUTC = ref.dateUTC, dateText = ref.dateText, commentHTML = ref.commentHTML; staticPath = Build.staticPath, gifIcon = Build.gifIcon; /* Post Info */ 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'; + capcodeUC = capcode.split(' ')[0]; + capcodeLC = capcodeUC.toLowerCase(); + if (capcode === 'Admin Emeritus') { capcodePlural = 'the Administrator Emeritus'; capcodeDescription = "4chan's founding Administrator"; + } else { + capcodeLong = { + 'Admin': 'Administrator', + 'Mod': 'Moderator' + }[capcode] || capcode; + capcodePlural = capcodeLong + "s"; + capcodeDescription = "a 4chan " + capcodeLong; } } postLink = Build.postURL(boardID, threadID, postID); quoteLink = Build.sameThread(boardID, threadID) ? "javascript:quote('" + (+postID) + "');" : "/" + boardID + "/thread/" + threadID + "#q" + postID; postInfo = { - 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]" : "") + "
" + innerHTML: "
" + (!o.isReply || boardID === "f" || subject ? "" + E(subject || "") + " " : "") + "" + (email ? "" : "") + "" + E(name) + "" + (tripcode ? " " + E(tripcode) + "" : "") + (capcode ? " ## " + E(capcode) + "" : "") + (email ? "" : "") + (boardID === "f" && !o.isReply || capcode ? "" : " ") + (capcode ? " \""" : "") + (uniqueID && !capcode ? " (ID: " + E(uniqueID) + ")" : "") + (flagCode ? " " : "") + " " + E(dateText) + " No." + E(postID) + "" + (o.isSticky ? " \"Sticky\"" : "") + (o.isClosed && !o.isArchived ? " \"Closed\"" : "") + (o.isArchived ? " \"Archived\"" : "") + (!o.isReply && g.VIEW === "index" ? "   [Reply]" : "") + "
" }; /* File Info */ - if (file && !file.isDeleted) { + if (file) { + protocol = /^https?:(?=\/\/i\.4cdn\.org\/)/; + fileURL = file.url.replace(protocol, ''); 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; + fileThumb = file.isSpoiler ? Build.spoilerThumb(boardID) : file.thumbURL.replace(protocol, ''); } 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) + ")
")) + "
" : "") + innerHTML: (file ? "
" + (boardID === "f" ? "
File: " + E(file.name) + "-(" + E(file.size) + ", " + E(file.dimensions) + ", " + E(file.tag) + ")
" : "
File: " + (file.isSpoiler ? "Spoiler Image" : E(shortFilename)) + " (" + E(file.size) + ", " + E(file.dimensions || "PDF") + ")
") + "
" : (o.fileDeleted ? "
\"File
" : "")) }; /* Whole Post */ - postClass = isOP ? 'op' : 'reply'; + postClass = o.isReply ? 'reply' : 'op'; wholePost = { - innerHTML: (!isOP ? "
>>
" : "") + "
" + (isOP ? fileBlock.innerHTML + postInfo.innerHTML : postInfo.innerHTML + fileBlock.innerHTML) + "
" + comment.innerHTML + "
" + innerHTML: (o.isReply ? "
>>
" : "") + "
" + (o.isReply ? postInfo.innerHTML + fileBlock.innerHTML : fileBlock.innerHTML + postInfo.innerHTML) + "
" + commentHTML.innerHTML + "
" }; container = $.el('div', { className: "postContainer " + postClass + "Container", id: "pc" + postID }); $.extend(container, wholePost); - ref = $$('.quotelink', container); - for (k = 0, len1 = ref.length; k < len1; k++) { - quote = ref[k]; + ref1 = $$('.quotelink', container); + for (k = 0, len1 = ref1.length; k < len1; k++) { + quote = ref1[k]; href = quote.getAttribute('href'); if ((href[0] === '#') && !(Build.sameThread(boardID, threadID))) { quote.href = ("/" + boardID + "/thread/" + threadID) + href; @@ -5111,6 +5127,23 @@ } } }, + isHidden: function(post) { + var filter, k, key, len1, ref, result, value; + for (key in Filter.filters) { + if ((value = Filter[key](post)) != null) { + ref = Filter.filters[key]; + for (k = 0, len1 = ref.length; k < len1; k++) { + filter = ref[k]; + if (result = filter(value, post.isReply)) { + if (result.hide) { + return true; + } + } + } + } + } + return false; + }, name: function(post) { return post.info.name; }, @@ -5124,10 +5157,11 @@ return post.info.capcode; }, subject: function(post) { - return post.info.subject || void 0; + return post.info.subject; }, comment: function(post) { - return post.info.comment; + var ref; + return (ref = post.info.comment) != null ? ref : Build.parseComment(post); }, flag: function(post) { return post.info.flag; @@ -9288,7 +9322,7 @@ Gallery.fullIDs[post.fullID] = true; thumb = $.el('a', { className: 'gal-thumb', - href: post.file.URL, + href: post.file.url, target: '_blank', title: post.file.name }); @@ -9640,7 +9674,7 @@ }, error: function(file, post, delay, cb) { var URL, redirect, src, timeoutID; - src = post.file.URL.split('/'); + src = post.file.url.split('/'); URL = Redirect.to('file', { boardID: post.board.ID, filename: src[src.length - 1] @@ -9690,7 +9724,7 @@ post.kill(true); return redirect(); } else { - return URL = post.file.URL; + return URL = post.file.url; } } }); @@ -9885,7 +9919,7 @@ if (file.videoControls) { $.rm(file.videoControls); } - file.thumb.parentNode.href = file.URL; + file.thumb.parentNode.href = file.url; file.thumb.parentNode.target = '_blank'; ref = ['isExpanding', 'isExpanded', 'videoControls', 'wasPlaying', 'scrollIntoView']; for (k = 0, len1 = ref.length; k < len1; k++) { @@ -9952,7 +9986,7 @@ el = file.fullImage = $.el((isVideo ? 'video' : 'img')); el.dataset.fullID = post.fullID; $.on(el, 'error', ImageExpand.error); - el.src = src || file.URL; + el.src = src || file.url; } el.className = 'full-image'; $.after(thumb, el); @@ -10181,7 +10215,7 @@ el = $.el((isVideo ? 'video' : 'img')); el.dataset.fullID = post.fullID; $.on(el, 'error', error); - el.src = file.URL; + el.src = file.url; } if (Conf['Restart when Opened']) { ImageCommon.rewind(el); @@ -10312,22 +10346,22 @@ attr = ref[k]; video.style[attr] = thumb.style[attr]; } - video.src = file.URL; + video.src = file.url; $.replace(thumb, video); file.thumb = video; return file.videoThumb = true; }, prefetch: function(post) { - var URL, clone, el, file, isImage, isVideo, k, len1, match, ref, replace, thumb, type; + var clone, el, file, isImage, isVideo, k, len1, match, ref, replace, thumb, type, url; file = post.file; if (!file) { return; } - isImage = file.isImage, isVideo = file.isVideo, thumb = file.thumb, URL = file.URL; + isImage = file.isImage, isVideo = file.isVideo, thumb = file.thumb, url = file.url; if (file.isPrefetched || !(isImage || isVideo) || post.isHidden || post.thread.isHidden) { return; } - type = (match = URL.match(/\.([^.]+)$/)[1].toUpperCase()) === 'JPEG' ? 'JPG' : match; + type = (match = url.match(/\.([^.]+)$/)[1].toUpperCase()) === 'JPEG' ? 'JPG' : match; replace = Conf["Replace " + type] && !/spoiler/.test(thumb.src || thumb.dataset.src); if (!(replace || Conf['prefetch'])) { return; @@ -10359,13 +10393,13 @@ ref1 = post.clones; for (q = 0, len2 = ref1.length; q < len2; q++) { clone = ref1[q]; - clone.file.thumb.src = URL; + clone.file.thumb.src = url; } - thumb.src = URL; + thumb.src = url; return thumb.removeAttribute('data-src'); }); } - return el.src = URL; + return el.src = url; }, toggle: function() { if (Conf['prefetch'] = this.checked) { @@ -10407,7 +10441,7 @@ }, node: function() { var el; - if (!(this.file && /webm$/i.test(this.file.URL))) { + if (!(this.file && /webm$/i.test(this.file.url))) { return; } if (this.isClone) { @@ -10428,7 +10462,7 @@ load: function() { $.rmClass(this.parentNode, 'error'); $.addClass(this.parentNode, 'loading'); - return CrossOrigin.binary(Get.postFromNode(this).file.URL, (function(_this) { + return CrossOrigin.binary(Get.postFromNode(this).file.url, (function(_this) { return function(data) { var output, title; $.rmClass(_this.parentNode, 'loading'); @@ -10562,15 +10596,15 @@ } } parts['text'] || (parts['text'] = ((ref1 = parts['url'].match(/(\w+)\.\w+\//)) != null ? ref1[1] : void 0) || '?'); - ext = post.file.URL.match(/[^.]*$/)[0]; + ext = post.file.url.match(/[^.]*$/)[0]; skip = false; for (key in parts) { parts[key] = parts[key].replace(/%(T?URL|IMG|MD5|board|name|%|semi)/g, function(parameter) { var type; type = { '%TURL': post.file.thumbURL, - '%URL': post.file.URL, - '%IMG': ext === 'gif' || ext === 'jpg' || ext === 'png' ? post.file.URL : post.file.thumbURL, + '%URL': post.file.url, + '%IMG': ext === 'gif' || ext === 'jpg' || ext === 'png' ? post.file.url : post.file.thumbURL, '%MD5': post.file.MD5, '%board': post.board.ID, '%name': post.file.name, @@ -11715,7 +11749,7 @@ if (!file) { return false; } - a.href = file.URL; + a.href = file.url; a.download = file.name; return true; } @@ -12796,6 +12830,9 @@ }) : void 0) { continue; } + if (Filter.isHidden(Build.parseJSON(postObj, boardID))) { + continue; + } unread++; if (!(QR.db && postObj.com)) { continue; @@ -14367,22 +14404,22 @@ formatters: { t: function() { return { - innerHTML: E(this.file.URL.match(/[^/]*$/)[0]) + innerHTML: E(this.file.url.match(/[^/]*$/)[0]) }; }, T: function() { return { - innerHTML: "" + FileInfo.formatters.t.call(this).innerHTML + "" + innerHTML: "" + FileInfo.formatters.t.call(this).innerHTML + "" }; }, l: function() { return { - innerHTML: "" + FileInfo.formatters.n.call(this).innerHTML + "" + innerHTML: "" + FileInfo.formatters.n.call(this).innerHTML + "" }; }, L: function() { return { - innerHTML: "" + FileInfo.formatters.N.call(this).innerHTML + "" + innerHTML: "" + FileInfo.formatters.N.call(this).innerHTML + "" }; }, n: function() { @@ -14434,6 +14471,11 @@ innerHTML: E(this.file.dimensions || "PDF") }; }, + g: function() { + return { + innerHTML: (this.file.tag ? ", " + E(this.file.tag) : "") + }; + }, '%': function() { return { innerHTML: "%" @@ -15891,7 +15933,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.
:
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.

    You can use these settings with each item, separate them with semicolons:
  • Possible items are: name, options (or equivalently email), subject and password.
  • Wrap values of items with quotes, like this: options:"sage".
  • Force values as defaults with the always keyword, for example: options:"sage";always.
  • Select specific boards for an item, separated with commas, for example: options:"sage";boards:jp;always.
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.
:
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.

    You can use these settings with each item, separate them with semicolons:
  • Possible items are: name, options (or equivalently email), subject and password.
  • Wrap values of items with quotes, like this: options:"sage".
  • Force values as defaults with the always keyword, for example: options:"sage";always.
  • Select specific boards for an item, separated with commas, for example: options:"sage";boards:jp;always.
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++) { @@ -16081,13 +16123,15 @@ data = { isReply: true, file: { - URL: '//i.4cdn.org/g/1334437723720.jpg', + url: '//i.4cdn.org/g/1334437723720.jpg', name: 'd9bb2efc98dd0df141a94399ff5880b7.jpg', size: '276 KB', sizeInBytes: 276 * 1024, dimensions: '1280x720', isImage: true, - isSpoiler: true + isVideo: false, + isSpoiler: true, + tag: 'Loop' } }; return FileInfo.format(this.value, data, this.nextElementSibling); @@ -18402,6 +18446,7 @@ " background: linear-gradient(to bottom, #F8F8F8, #DCDCDC) no-repeat;\n" + " border: 1px solid #BBB;\n" + " border-radius: 2px;\n" + +" height: 100%;\n" + "}\n" + "#qr-file-button {\n" + " width: 15%;\n" + diff --git a/builds/4chan-X.crx b/builds/4chan-X.crx index 412704a12..013c83cdd 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 384f8bbc0..f8d341e28 100644 --- a/builds/4chan-X.meta.js +++ b/builds/4chan-X.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.10.11.1 +// @version 1.10.11.2 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index b0fe5afb7..5d546f1b5 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.11.1 +// @version 1.10.11.2 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -100,11 +100,8 @@ * audio/beep.wav from http://freesound.org/people/pierrecartoons1979/sounds/90112/ * cc-by-nc-3.0 * -* 4chan/4chan-JS (https://github.com/4chan/4chan-JS) -* Copyright (c) 2012-2013, 4chan LLC -* All rights reserved. -* -* license: https://github.com/4chan/4chan-JS/blob/master/LICENSE +* Font Awesome by Dave Gandy (http://fontawesome.io) +* license: http://fontawesome.io/license/ */ 'use strict'; @@ -327,7 +324,7 @@ }, time: '%m/%d/%y(%a)%H:%M:%S', backlink: '>>%id', - fileInfo: '%l (%p%s, %r)', + fileInfo: '%l (%p%s, %r%g)', favicon: 'ferongr', usercss: '', hotkeys: { @@ -399,7 +396,7 @@ doc = d.documentElement; g = { - VERSION: '1.10.11.1', + VERSION: '1.10.11.2', NAMESPACE: '4chan X.', boards: {} }; @@ -1245,7 +1242,7 @@ this.info.nameBlock = Conf['Anonymize'] ? 'Anonymous' : this.nodes.nameBlock.textContent.trim(); if (subject = $('.subject', info)) { this.nodes.subject = subject; - this.info.subject = subject.textContent; + this.info.subject = subject.textContent || void 0; } if (name = $('.name', info)) { this.nodes.name = name; @@ -1362,7 +1359,7 @@ }; Post.prototype.parseFile = function() { - var fileEl, fileText, info, link, ref, ref1, size, thumb, unit; + var fileEl, fileText, info, link, m, ref, ref1, ref2, size, thumb, unit; if (!(fileEl = $('.file', this.nodes.post))) { return; } @@ -1376,12 +1373,13 @@ this.file = { text: fileText, link: link, - URL: link.href, + url: link.href, name: fileText.title || link.title || link.textContent, size: info[1], isImage: /(jpg|png|gif)$/i.test(link.href), isVideo: /webm$/i.test(link.href), - dimensions: (ref1 = info[0].match(/\d+x\d+/)) != null ? ref1[0] : void 0 + dimensions: (ref1 = info[0].match(/\d+x\d+/)) != null ? ref1[0] : void 0, + tag: (ref2 = info[0].match(/, ([a-z]+)\)/i)) != null ? ref2[1] : void 0 }; size = +this.file.size.match(/[\d.]+/)[0]; unit = ['B', 'KB', 'MB', 'GB'].indexOf(this.file.size.match(/\w+$/)[0]); @@ -1392,7 +1390,7 @@ 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", + thumbURL: (m = link.href.match(/\d+(?=\.\w+$)/)) ? location.protocol + "//i.4cdn.org/" + this.board + "/" + m[0] + "s.jpg" : void 0, MD5: thumb.dataset.md5, isSpoiler: $.hasClass(thumb.parentNode, 'imgspoiler') }); @@ -2262,41 +2260,49 @@ postID: this.postID, threadID: this.threadID, boardID: this.boardID, - name: data.name, + isReply: this.postID !== this.threadID + }; + o.info = { + subject: data.title, + email: data.email, + name: data.name || '', + tripcode: data.trip, capcode: (function() { switch (data.capcode) { case 'M': - return 'mod'; + return 'Mod'; case 'A': - return 'admin'; + return 'Admin'; case 'D': - return 'developer'; + return 'Developer'; } })(), - tripcode: data.trip, uniqueID: data.poster_hash, - email: data.email || '', - subject: data.title, flagCode: data.poster_country, - flagName: data.poster_country_name, - date: data.fourchan_date, + flag: data.poster_country_name, dateUTC: data.timestamp, - comment: comment + dateText: data.fourchan_date, + commentHTML: comment }; + if (o.info.capcode) { + delete o.info.uniqueID; + } if ((ref = data.media) != null ? ref.media_filename : void 0) { o.file = { name: data.media.media_filename, - timestamp: data.media.media_orig, - url: data.media.media_link || data.media.remote_media_link || ("//i.4cdn.org/" + this.boardID + "/" + (encodeURIComponent(data.media[this.boardID === 'f' ? 'media_filename' : 'media_orig']))), + url: data.media.media_link || data.media.remote_media_link || (location.protocol + "//i.4cdn.org/" + this.boardID + "/" + (encodeURIComponent(data.media[this.boardID === 'f' ? 'media_filename' : 'media_orig']))), height: data.media.media_h, width: data.media.media_w, MD5: data.media.media_hash, - size: data.media.media_size, - turl: data.media.thumb_link || ("//i.4cdn.org/" + this.boardID + "/" + data.media.preview_orig), + size: $.bytesToString(data.media.media_size), + thumbURL: data.media.thumb_link || (location.protocol + "//i.4cdn.org/" + this.boardID + "/" + data.media.preview_orig), theight: data.media.preview_h, twidth: data.media.preview_w, isSpoiler: data.media.spoiler === '1' }; + if (!/\.pdf$/.test(o.file.url)) { + o.file.dimensions = o.file.width + "x" + o.file.height; + } if (this.boardID === 'f') { o.file.tag = JSON.parse(data.media.exif).Tag; } @@ -2306,7 +2312,7 @@ post = new Post(Build.post(o), thread, board); post.kill(); if (post.file) { - post.file.thumbURL = o.file.turl; + post.file.thumbURL = o.file.thumbURL; } post.isFetchedQuote = true; Main.callbackNodes(Post, [post]); @@ -4013,13 +4019,14 @@ if (text == null) { return text; } - return text.replace(/<[^>]*>/g, '').replace(/&(amp|#039|quot|lt|gt);/g, function(c) { + return text.replace(/<[^>]*>/g, '').replace(/&(amp|#039|quot|lt|gt|#44);/g, function(c) { return { '&': '&', ''': "'", '"': '"', '<': '<', - '>': '>' + '>': '>', + ',': ',' }[c]; }); }, @@ -4051,112 +4058,121 @@ return "/" + boardID + "/thread/" + threadID + "#p" + postID; } }, - postFromObject: function(data, boardID, suppressThumb) { + parseJSON: function(data, boardID) { var o; o = { postID: data.no, threadID: data.resto || data.no, boardID: boardID, - name: Build.unescape(data.name), - capcode: data.capcode, - tripcode: data.trip, - uniqueID: data.id, - email: Build.unescape(data.email), - subject: Build.unescape(data.sub), - flagCode: data.country, - flagName: Build.unescape(data.country_name), - date: data.now, - dateUTC: data.time, - comment: { - innerHTML: data.com || '' - }, + isReply: !!data.resto, isSticky: !!data.sticky, isClosed: !!data.closed, - isArchived: !!data.archived + isArchived: !!data.archived, + fileDeleted: !!data.filedeleted }; - if (data.filedeleted) { - o.file = { - isDeleted: true - }; - } else if (data.ext) { + o.info = { + subject: Build.unescape(data.sub), + email: Build.unescape(data.email), + name: Build.unescape(data.name) || '', + tripcode: data.trip, + uniqueID: data.id, + flagCode: data.country, + flag: Build.unescape(data.country_name), + dateUTC: data.time, + dateText: data.now, + commentHTML: { + innerHTML: data.com || '' + } + }; + if (data.capcode) { + o.info.capcode = data.capcode.replace(/_highlight$/, '').replace(/_/g, ' ').replace(/\b\w/g, function(c) { + return c.toUpperCase(); + }); + o.capcodeHighlight = /_highlight$/.test(data.capcode); + delete o.info.uniqueID; + } + if (data.ext) { o.file = { name: (Build.unescape(data.filename)) + data.ext, - timestamp: "" + data.tim + data.ext, - url: boardID === 'f' ? "//i.4cdn.org/" + boardID + "/" + (encodeURIComponent(data.filename)) + data.ext : "//i.4cdn.org/" + boardID + "/" + data.tim + data.ext, + url: boardID === 'f' ? location.protocol + "//i.4cdn.org/" + boardID + "/" + (encodeURIComponent(data.filename)) + data.ext : location.protocol + "//i.4cdn.org/" + boardID + "/" + data.tim + data.ext, height: data.h, width: data.w, MD5: data.md5, - size: data.fsize, - turl: "//i.4cdn.org/" + boardID + "/" + data.tim + "s.jpg", + size: $.bytesToString(data.fsize), + thumbURL: location.protocol + "//i.4cdn.org/" + boardID + "/" + data.tim + "s.jpg", theight: data.tn_h, twidth: data.tn_w, isSpoiler: !!data.spoiler, - isDeleted: false, tag: data.tag }; + if (!/\.pdf$/.test(o.file.url)) { + o.file.dimensions = o.file.width + "x" + o.file.height; + } } + return o; + }, + parseComment: function(o) { + var html; + html = o.info.commentHTML.innerHTML.replace(//gi, '\n').replace(/\n\nRolled [^<]*<\/b>/i, '').replace(/]*>/g, ''); + return o.info.comment = Build.unescape(html); + }, + postFromObject: function(data, boardID, suppressThumb) { + var o; + o = Build.parseJSON(data, boardID); return Build.post(o, suppressThumb); }, 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, 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; + var boardID, capcode, capcodeDescription, capcodeLC, capcodeLong, capcodePlural, capcodeUC, commentHTML, container, dateText, dateUTC, email, file, fileBlock, fileThumb, fileURL, flag, flagCode, gifIcon, href, k, len1, match, name, postClass, postID, postInfo, postLink, protocol, quote, quoteLink, ref, ref1, shortFilename, staticPath, subject, threadID, tripcode, uniqueID, wholePost; + postID = o.postID, threadID = o.threadID, boardID = o.boardID, file = o.file; + ref = o.info, subject = ref.subject, email = ref.email, name = ref.name, tripcode = ref.tripcode, capcode = ref.capcode, uniqueID = ref.uniqueID, flagCode = ref.flagCode, flag = ref.flag, dateUTC = ref.dateUTC, dateText = ref.dateText, commentHTML = ref.commentHTML; staticPath = Build.staticPath, gifIcon = Build.gifIcon; /* Post Info */ 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'; + capcodeUC = capcode.split(' ')[0]; + capcodeLC = capcodeUC.toLowerCase(); + if (capcode === 'Admin Emeritus') { capcodePlural = 'the Administrator Emeritus'; capcodeDescription = "4chan's founding Administrator"; + } else { + capcodeLong = { + 'Admin': 'Administrator', + 'Mod': 'Moderator' + }[capcode] || capcode; + capcodePlural = capcodeLong + "s"; + capcodeDescription = "a 4chan " + capcodeLong; } } postLink = Build.postURL(boardID, threadID, postID); quoteLink = Build.sameThread(boardID, threadID) ? "javascript:quote('" + (+postID) + "');" : "/" + boardID + "/thread/" + threadID + "#q" + postID; postInfo = { - 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]" : "") + "
" + innerHTML: "
" + (!o.isReply || boardID === "f" || subject ? "" + E(subject || "") + " " : "") + "" + (email ? "" : "") + "" + E(name) + "" + (tripcode ? " " + E(tripcode) + "" : "") + (capcode ? " ## " + E(capcode) + "" : "") + (email ? "" : "") + (boardID === "f" && !o.isReply || capcode ? "" : " ") + (capcode ? " \""" : "") + (uniqueID && !capcode ? " (ID: " + E(uniqueID) + ")" : "") + (flagCode ? " " : "") + " " + E(dateText) + " No." + E(postID) + "" + (o.isSticky ? " \"Sticky\"" : "") + (o.isClosed && !o.isArchived ? " \"Closed\"" : "") + (o.isArchived ? " \"Archived\"" : "") + (!o.isReply && g.VIEW === "index" ? "   [Reply]" : "") + "
" }; /* File Info */ - if (file && !file.isDeleted) { + if (file) { + protocol = /^https?:(?=\/\/i\.4cdn\.org\/)/; + fileURL = file.url.replace(protocol, ''); 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; + fileThumb = file.isSpoiler ? Build.spoilerThumb(boardID) : file.thumbURL.replace(protocol, ''); } 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) + ")
")) + "
" : "") + innerHTML: (file ? "
" + (boardID === "f" ? "
File: " + E(file.name) + "-(" + E(file.size) + ", " + E(file.dimensions) + ", " + E(file.tag) + ")
" : "
File: " + (file.isSpoiler ? "Spoiler Image" : E(shortFilename)) + " (" + E(file.size) + ", " + E(file.dimensions || "PDF") + ")
") + "
" : (o.fileDeleted ? "
\"File
" : "")) }; /* Whole Post */ - postClass = isOP ? 'op' : 'reply'; + postClass = o.isReply ? 'reply' : 'op'; wholePost = { - innerHTML: (!isOP ? "
>>
" : "") + "
" + (isOP ? fileBlock.innerHTML + postInfo.innerHTML : postInfo.innerHTML + fileBlock.innerHTML) + "
" + comment.innerHTML + "
" + innerHTML: (o.isReply ? "
>>
" : "") + "
" + (o.isReply ? postInfo.innerHTML + fileBlock.innerHTML : fileBlock.innerHTML + postInfo.innerHTML) + "
" + commentHTML.innerHTML + "
" }; container = $.el('div', { className: "postContainer " + postClass + "Container", id: "pc" + postID }); $.extend(container, wholePost); - ref = $$('.quotelink', container); - for (k = 0, len1 = ref.length; k < len1; k++) { - quote = ref[k]; + ref1 = $$('.quotelink', container); + for (k = 0, len1 = ref1.length; k < len1; k++) { + quote = ref1[k]; href = quote.getAttribute('href'); if ((href[0] === '#') && !(Build.sameThread(boardID, threadID))) { quote.href = ("/" + boardID + "/thread/" + threadID) + href; @@ -5112,6 +5128,23 @@ } } }, + isHidden: function(post) { + var filter, k, key, len1, ref, result, value; + for (key in Filter.filters) { + if ((value = Filter[key](post)) != null) { + ref = Filter.filters[key]; + for (k = 0, len1 = ref.length; k < len1; k++) { + filter = ref[k]; + if (result = filter(value, post.isReply)) { + if (result.hide) { + return true; + } + } + } + } + } + return false; + }, name: function(post) { return post.info.name; }, @@ -5125,10 +5158,11 @@ return post.info.capcode; }, subject: function(post) { - return post.info.subject || void 0; + return post.info.subject; }, comment: function(post) { - return post.info.comment; + var ref; + return (ref = post.info.comment) != null ? ref : Build.parseComment(post); }, flag: function(post) { return post.info.flag; @@ -9289,7 +9323,7 @@ Gallery.fullIDs[post.fullID] = true; thumb = $.el('a', { className: 'gal-thumb', - href: post.file.URL, + href: post.file.url, target: '_blank', title: post.file.name }); @@ -9641,7 +9675,7 @@ }, error: function(file, post, delay, cb) { var URL, redirect, src, timeoutID; - src = post.file.URL.split('/'); + src = post.file.url.split('/'); URL = Redirect.to('file', { boardID: post.board.ID, filename: src[src.length - 1] @@ -9691,7 +9725,7 @@ post.kill(true); return redirect(); } else { - return URL = post.file.URL; + return URL = post.file.url; } } }); @@ -9886,7 +9920,7 @@ if (file.videoControls) { $.rm(file.videoControls); } - file.thumb.parentNode.href = file.URL; + file.thumb.parentNode.href = file.url; file.thumb.parentNode.target = '_blank'; ref = ['isExpanding', 'isExpanded', 'videoControls', 'wasPlaying', 'scrollIntoView']; for (k = 0, len1 = ref.length; k < len1; k++) { @@ -9953,7 +9987,7 @@ el = file.fullImage = $.el((isVideo ? 'video' : 'img')); el.dataset.fullID = post.fullID; $.on(el, 'error', ImageExpand.error); - el.src = src || file.URL; + el.src = src || file.url; } el.className = 'full-image'; $.after(thumb, el); @@ -10182,7 +10216,7 @@ el = $.el((isVideo ? 'video' : 'img')); el.dataset.fullID = post.fullID; $.on(el, 'error', error); - el.src = file.URL; + el.src = file.url; } if (Conf['Restart when Opened']) { ImageCommon.rewind(el); @@ -10313,22 +10347,22 @@ attr = ref[k]; video.style[attr] = thumb.style[attr]; } - video.src = file.URL; + video.src = file.url; $.replace(thumb, video); file.thumb = video; return file.videoThumb = true; }, prefetch: function(post) { - var URL, clone, el, file, isImage, isVideo, k, len1, match, ref, replace, thumb, type; + var clone, el, file, isImage, isVideo, k, len1, match, ref, replace, thumb, type, url; file = post.file; if (!file) { return; } - isImage = file.isImage, isVideo = file.isVideo, thumb = file.thumb, URL = file.URL; + isImage = file.isImage, isVideo = file.isVideo, thumb = file.thumb, url = file.url; if (file.isPrefetched || !(isImage || isVideo) || post.isHidden || post.thread.isHidden) { return; } - type = (match = URL.match(/\.([^.]+)$/)[1].toUpperCase()) === 'JPEG' ? 'JPG' : match; + type = (match = url.match(/\.([^.]+)$/)[1].toUpperCase()) === 'JPEG' ? 'JPG' : match; replace = Conf["Replace " + type] && !/spoiler/.test(thumb.src || thumb.dataset.src); if (!(replace || Conf['prefetch'])) { return; @@ -10360,13 +10394,13 @@ ref1 = post.clones; for (q = 0, len2 = ref1.length; q < len2; q++) { clone = ref1[q]; - clone.file.thumb.src = URL; + clone.file.thumb.src = url; } - thumb.src = URL; + thumb.src = url; return thumb.removeAttribute('data-src'); }); } - return el.src = URL; + return el.src = url; }, toggle: function() { if (Conf['prefetch'] = this.checked) { @@ -10408,7 +10442,7 @@ }, node: function() { var el; - if (!(this.file && /webm$/i.test(this.file.URL))) { + if (!(this.file && /webm$/i.test(this.file.url))) { return; } if (this.isClone) { @@ -10429,7 +10463,7 @@ load: function() { $.rmClass(this.parentNode, 'error'); $.addClass(this.parentNode, 'loading'); - return CrossOrigin.binary(Get.postFromNode(this).file.URL, (function(_this) { + return CrossOrigin.binary(Get.postFromNode(this).file.url, (function(_this) { return function(data) { var output, title; $.rmClass(_this.parentNode, 'loading'); @@ -10563,15 +10597,15 @@ } } parts['text'] || (parts['text'] = ((ref1 = parts['url'].match(/(\w+)\.\w+\//)) != null ? ref1[1] : void 0) || '?'); - ext = post.file.URL.match(/[^.]*$/)[0]; + ext = post.file.url.match(/[^.]*$/)[0]; skip = false; for (key in parts) { parts[key] = parts[key].replace(/%(T?URL|IMG|MD5|board|name|%|semi)/g, function(parameter) { var type; type = { '%TURL': post.file.thumbURL, - '%URL': post.file.URL, - '%IMG': ext === 'gif' || ext === 'jpg' || ext === 'png' ? post.file.URL : post.file.thumbURL, + '%URL': post.file.url, + '%IMG': ext === 'gif' || ext === 'jpg' || ext === 'png' ? post.file.url : post.file.thumbURL, '%MD5': post.file.MD5, '%board': post.board.ID, '%name': post.file.name, @@ -11716,7 +11750,7 @@ if (!file) { return false; } - a.href = file.URL; + a.href = file.url; a.download = file.name; return true; } @@ -12797,6 +12831,9 @@ }) : void 0) { continue; } + if (Filter.isHidden(Build.parseJSON(postObj, boardID))) { + continue; + } unread++; if (!(QR.db && postObj.com)) { continue; @@ -14368,22 +14405,22 @@ formatters: { t: function() { return { - innerHTML: E(this.file.URL.match(/[^/]*$/)[0]) + innerHTML: E(this.file.url.match(/[^/]*$/)[0]) }; }, T: function() { return { - innerHTML: "" + FileInfo.formatters.t.call(this).innerHTML + "" + innerHTML: "" + FileInfo.formatters.t.call(this).innerHTML + "" }; }, l: function() { return { - innerHTML: "" + FileInfo.formatters.n.call(this).innerHTML + "" + innerHTML: "" + FileInfo.formatters.n.call(this).innerHTML + "" }; }, L: function() { return { - innerHTML: "" + FileInfo.formatters.N.call(this).innerHTML + "" + innerHTML: "" + FileInfo.formatters.N.call(this).innerHTML + "" }; }, n: function() { @@ -14435,6 +14472,11 @@ innerHTML: E(this.file.dimensions || "PDF") }; }, + g: function() { + return { + innerHTML: (this.file.tag ? ", " + E(this.file.tag) : "") + }; + }, '%': function() { return { innerHTML: "%" @@ -15892,7 +15934,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.
:
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.

    You can use these settings with each item, separate them with semicolons:
  • Possible items are: name, options (or equivalently email), subject and password.
  • Wrap values of items with quotes, like this: options:"sage".
  • Force values as defaults with the always keyword, for example: options:"sage";always.
  • Select specific boards for an item, separated with commas, for example: options:"sage";boards:jp;always.
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.
:
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.

    You can use these settings with each item, separate them with semicolons:
  • Possible items are: name, options (or equivalently email), subject and password.
  • Wrap values of items with quotes, like this: options:"sage".
  • Force values as defaults with the always keyword, for example: options:"sage";always.
  • Select specific boards for an item, separated with commas, for example: options:"sage";boards:jp;always.
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++) { @@ -16082,13 +16124,15 @@ data = { isReply: true, file: { - URL: '//i.4cdn.org/g/1334437723720.jpg', + url: '//i.4cdn.org/g/1334437723720.jpg', name: 'd9bb2efc98dd0df141a94399ff5880b7.jpg', size: '276 KB', sizeInBytes: 276 * 1024, dimensions: '1280x720', isImage: true, - isSpoiler: true + isVideo: false, + isSpoiler: true, + tag: 'Loop' } }; return FileInfo.format(this.value, data, this.nextElementSibling); @@ -18403,6 +18447,7 @@ " background: linear-gradient(to bottom, #F8F8F8, #DCDCDC) no-repeat;\n" + " border: 1px solid #BBB;\n" + " border-radius: 2px;\n" + +" height: 100%;\n" + "}\n" + "#qr-file-button {\n" + " width: 15%;\n" + diff --git a/builds/4chan-X.zip b/builds/4chan-X.zip index 3890dad90..d0542c9c9 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 214b53249..b7ba3dcba 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 06a246d19..ea30fd227 100644 --- a/builds/updates.xml +++ b/builds/updates.xml @@ -1,7 +1,7 @@ - + diff --git a/package.json b/package.json index 4b81025e2..d9e23b411 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.11.1", - "date": "2015-04-24T14:48:43.242Z", + "version": "1.10.11.2", + "date": "2015-04-26T01:00:36.770Z", "repo": "https://github.com/ccd0/4chan-x/", "page": "https://github.com/ccd0/4chan-x", "downloads": "https://ccd0.github.io/4chan-x/builds/",