diff --git a/Gruntfile.coffee b/Gruntfile.coffee index c23ced9a1..f400d89a6 100644 --- a/Gruntfile.coffee +++ b/Gruntfile.coffee @@ -61,6 +61,7 @@ module.exports = (grunt) -> files: 'builds/<%= pkg.name %>.meta.js': 'src/General/meta/metadata.js' 'builds/<%= pkg.name %>.user.js': [ + 'src/General/meta/botproc.js' 'src/General/meta/metadata.js' 'src/General/meta/banner.js' 'src/General/meta/usestrict.js' diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index f5ce94ae5..44df79589 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -1,3 +1,4 @@ +// Generated by CoffeeScript // ==UserScript== // @name 4chan X // @version 1.2.25 @@ -430,13 +431,12 @@ fd = new FormData(); for (key in form) { val = form[key]; - if (!val) { - continue; - } - if (val.size && val.name) { - fd.append(key, val, val.name); - } else { - fd.append(key, val); + if (val) { + if (val.size && val.name) { + fd.append(key, val, val.name); + } else { + fd.append(key, val); + } } } return fd; @@ -1080,7 +1080,7 @@ _ref1 = Get.allQuotelinksLinkingTo(this); for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { quotelink = _ref1[_j]; - if ($.hasClass(quotelink, 'deadlink')) { + if (!(!$.hasClass(quotelink, 'deadlink'))) { continue; } $.add(quotelink, $.tn('\u00A0(Dead)')); @@ -1844,6 +1844,7 @@ date: data.now, dateUTC: data.time, comment: data.com, + capReps: data.capcode_replies, isSticky: !!data.sticky, isClosed: !!data.closed }; @@ -1871,9 +1872,9 @@ @license: https://github.com/4chan/4chan-JS/blob/master/LICENSE */ - var a, boardID, capcode, capcodeClass, capcodeStart, closed, comment, container, date, dateUTC, email, emailEnd, emailStart, ext, file, fileDims, fileHTML, fileInfo, fileSize, fileThumb, filename, flag, flagCode, flagName, href, imgSrc, isClosed, isOP, isSticky, name, postID, quote, shortFilename, spoilerRange, staticPath, sticky, subject, threadID, tripcode, uniqueID, userID, _i, _len, _ref; + var a, array, boardID, capReps, capcode, capcodeClass, capcodeReplies, capcodeStart, capcodeType, closed, comment, container, date, dateUTC, email, emailEnd, emailStart, ext, file, fileDims, fileHTML, fileInfo, fileSize, fileThumb, filename, flag, flagCode, flagName, generateCapcodeReplies, href, imgSrc, isClosed, isOP, isSticky, name, postID, quote, shortFilename, spoilerRange, staticPath, sticky, subject, threadID, tripcode, uniqueID, userID, _i, _len, _ref; - postID = o.postID, threadID = o.threadID, 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, isSticky = o.isSticky, isClosed = o.isClosed, comment = o.comment, file = o.file; + 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, isSticky = o.isSticky, isClosed = o.isClosed, comment = o.comment, capReps = o.capReps, file = o.file; isOP = postID === threadID; staticPath = '//static.4chan.org/image/'; if (email) { @@ -1947,10 +1948,32 @@ tripcode = tripcode ? " " + tripcode + "" : ''; sticky = isSticky ? " Sticky" : ''; closed = isClosed ? " Closed" : ''; + capcodeReplies = ''; + if (capReps) { + generateCapcodeReplies = function(capcodeType, array) { + return "" + ((function() { + switch (capcodeType) { + case 'admin': + return 'Administrator'; + case 'mod': + return 'Moderator'; + case 'developer': + return 'Developer'; + } + })()) + " Repl" + (array.length > 1 ? 'ies' : 'y') + ": " + (array.map(function(ID) { + return ">>" + ID + ""; + }).join(' ')) + "
"; + }; + for (capcodeType in capReps) { + array = capReps[capcodeType]; + capcodeReplies += generateCapcodeReplies(capcodeType, array); + } + capcodeReplies = "

" + capcodeReplies + ""; + } container = $.el('div', { id: "pc" + postID, className: "postContainer " + (isOP ? 'op' : 'reply') + "Container", - innerHTML: (isOP ? '' : "
>>
") + ("
") + ("
") + ("") + ("" + (name || '') + "") + tripcode + capcodeStart + capcode + userID + flag + sticky + closed + ("
" + subject) + ("
" + date) + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? fileHTML : '') + ("
") + (" ") + ("" + subject + " ") + ("") + emailStart + ("" + (name || '') + "") + tripcode + capcodeStart + emailEnd + capcode + userID + flag + sticky + closed + ' ' + ("" + date + " ") + "" + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? '' : fileHTML) + ("
" + (comment || '') + "
") + '
' + innerHTML: (isOP ? '' : "
>>
") + ("
") + ("
") + ("") + ("" + (name || '') + "") + tripcode + capcodeStart + capcode + userID + flag + sticky + closed + ("
" + subject) + ("
" + date) + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? fileHTML : '') + ("
") + (" ") + ("" + subject + " ") + ("") + emailStart + ("" + (name || '') + "") + tripcode + capcodeStart + emailEnd + capcode + userID + flag + sticky + closed + ' ' + ("" + date + " ") + "" + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? '' : fileHTML) + ("
" + (comment || '') + capcodeReplies + "
") + '
' }); _ref = $$('.quotelink', container); for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -4328,6 +4351,9 @@ len = snapshot.snapshotLength; while (++i < len) { node = snapshot.snapshotItem(i); + if (node.parentElement.nodeName === "A") { + continue; + } data = node.data; if (Linkify.regString.test(data)) { Linkify.regString.lastIndex = 0; @@ -4360,7 +4386,7 @@ index = match.index; link = match[0]; len2 = index + link.length; - if (len - len2 === 0) { + if (len === len2) { break; } range = document.createRange(); @@ -4393,10 +4419,7 @@ } } if (range.collapsed) { - if (node.nodeName === 'WBR') { - node = node.previousSibling; - } - range.setEnd(node, node.length); + range.setEndAfter(node); } return Linkify.makeLink(range, post); }, @@ -4428,21 +4451,28 @@ } }, embed: function(data) { - var embed, key, link, options, uid; + var embed, href, key, link, name, options, uid, value, _ref; key = data[0], uid = data[1], options = data[2], link = data[3]; + href = link.href; embed = $.el('a', { - name: uid, - option: options, className: 'embedder', href: 'javascript:;', textContent: '(embed)' }); - embed.dataset.service = key; - embed.dataset.originalurl = link.href; - $.addClass(link, "" + embed.dataset.service); + _ref = { + key: key, + href: href, + uid: uid, + options: options + }; + for (name in _ref) { + value = _ref[name]; + embed.dataset[name] = value; + } + $.addClass(link, "" + embed.dataset.key); $.on(embed, 'click', Linkify.cb.toggle); - return $.after(link, [$.tn(' '), embed]); + $.after(link, [$.tn(' '), embed]); }, title: function(data) { var err, key, link, options, service, title, titles, uid; @@ -4488,23 +4518,24 @@ embed: function(a) { var el, style, type; - el = (type = Linkify.types[a.dataset.service]).el.call(a); + el = (type = Linkify.types[a.dataset.key]).el.call(a); el.style.cssText = (style = type.style) ? style : "border: 0; width: 640px; height: 390px"; a.textContent = '(unembed)'; return el; }, unembed: function(a) { - var el, url; + var el, href; + href = a.dataset.href; el = $.el('a', { rel: 'nofollow noreferrer', target: 'blank', className: 'linkify', - href: url = a.dataset.originalurl, - textContent: a.dataset.title || url + href: href, + textContent: a.dataset.title || href }); a.textContent = '(embed)'; - $.addClass(el, "" + a.dataset.service); + $.addClass(el, "" + a.dataset.key); return el; }, title: function(data) { @@ -4532,108 +4563,13 @@ } }, types: { - YouTube: { - regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/, - el: function() { - return $.el('iframe', { - src: "//www.youtube.com/embed/" + this.name + (this.option ? '#' + this.option : '') + "?wmode=opaque" - }); - }, - title: { - api: function(uid) { - return "https://gdata.youtube.com/feeds/api/videos/" + uid + "?alt=json&fields=title/text(),yt:noembed,app:control/yt:state/@reasonCode"; - }, - text: function() { - return JSON.parse(this.responseText).entry.title.$t; - } - } - }, - Vocaroo: { - regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/, - style: 'border: 0; width: 150px; height: 45px;', - el: function() { - return $.el('object', { - innerHTML: "" - }); - } - }, - Vimeo: { - regExp: /.*(?:vimeo.com\/)([^#\&\?]*).*/, - el: function() { - return $.el('iframe', { - src: "//player.vimeo.com/video/" + this.name + "?wmode=opaque" - }); - }, - title: { - api: function(uid) { - return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + uid; - }, - text: function() { - return JSON.parse(this.responseText).title; - } - } - }, - LiveLeak: { - regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/, - el: function() { - return $.el('object', { - innerHTML: "" - }); - } - }, audio: { regExp: /(.*\.(mp3|ogg|wav))$/, el: function() { return $.el('audio', { controls: 'controls', preload: 'auto', - src: this.name - }); - } - }, - image: { - regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/, - style: 'border: 0; width: auto; height: auto;', - el: function() { - return $.el('div', { - innerHTML: "" - }); - } - }, - SoundCloud: { - regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/, - style: 'height: auto; width: 500px; display: inline-block;', - el: function() { - var div; - - div = $.el('div', { - className: "soundcloud", - name: "soundcloud" - }); - $.ajax("//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + this.name, { - div: div, - onloadend: function() { - return this.div.innerHTML = JSON.parse(this.responseText).html; - } - }, false); - return div; - }, - title: { - api: function(uid) { - return "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + uid; - }, - text: function() { - return JSON.parse(this.responseText).title; - } - } - }, - pastebin: { - regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/, - el: function() { - var div; - - return div = $.el('iframe', { - src: "http://pastebin.com/embed_iframe.php?i=" + this.name + src: this.dataset.uid }); } }, @@ -4643,7 +4579,7 @@ var div; return div = $.el('iframe', { - src: "http://www.purplegene.com/script?url=https://gist.github.com/" + this.name + ".js" + src: "http://www.purplegene.com/script?url=https://gist.github.com/" + this.dataset.uid + ".js" }); }, title: { @@ -4662,13 +4598,138 @@ } } }, + image: { + regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/, + style: 'border: 0; width: auto; height: auto;', + el: function() { + return $.el('div', { + innerHTML: "" + }); + } + }, InstallGentoo: { regExp: /.*(?:paste.installgentoo.com\/view\/)([0-9a-z_]+)/, el: function() { return $.el('iframe', { - src: "http://paste.installgentoo.com/view/embed/" + this.name + src: "http://paste.installgentoo.com/view/embed/" + this.dataset.uid }); } + }, + LiveLeak: { + regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/, + el: function() { + return $.el('object', { + innerHTML: "" + }); + } + }, + pastebin: { + regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/, + el: function() { + var div; + + return div = $.el('iframe', { + src: "http://pastebin.com/embed_iframe.php?i=" + this.dataset.uid + }); + } + }, + SoundCloud: { + regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/, + style: 'height: auto; width: 500px; display: inline-block;', + el: function() { + var div; + + div = $.el('div', { + className: "soundcloud", + name: "soundcloud" + }); + $.ajax("//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + this.dataset.uid, { + div: div, + onloadend: function() { + return this.div.innerHTML = JSON.parse(this.responseText).html; + } + }, false); + return div; + }, + title: { + api: function(uid) { + return "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + uid; + }, + text: function() { + return JSON.parse(this.responseText).title; + } + } + }, + TwitchTV: { + regExp: /.*(?:twitch.tv\/)([^#\&\?]*).*/, + style: "border: none; width: 640px; height: 360px;", + el: function() { + var channel, chapter, result, _; + + if (result = /(\w+)\/(?:[a-z]\/)?(\d+)/i.exec(this.dataset.uid)) { + _ = result[0], channel = result[1], chapter = result[2]; + return $.el('object', { + data: 'http://www.twitch.tv/widgets/archive_embed_player.swf', + innerHTML: "\n" + }); + } else { + channel = (/(\w+)/.exec(this.dataset.uid))[0]; + return $.el('object', { + data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=" + channel, + innerHTML: "\n\n" + }); + } + } + }, + Vocaroo: { + regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/, + style: 'border: 0; width: 150px; height: 45px;', + el: function() { + return $.el('object', { + innerHTML: "" + }); + } + }, + Vimeo: { + regExp: /.*(?:vimeo.com\/)([^#\&\?]*).*/, + el: function() { + return $.el('iframe', { + src: "//player.vimeo.com/video/" + this.dataset.uid + "?wmode=opaque" + }); + }, + title: { + api: function(uid) { + return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + uid; + }, + text: function() { + return JSON.parse(this.responseText).title; + } + } + }, + Vine: { + regExp: /.*(?:vine.co\/)([^#\&\?]*).*/, + style: 'border: none; width: 500px; height: 500px;', + el: function() { + return $.el('iframe', { + src: "https://vine.co/" + this.dataset.uid + "/card" + }); + } + }, + YouTube: { + regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/, + el: function() { + return $.el('iframe', { + src: "//www.youtube.com/embed/" + this.dataset.uid + (this.dataset.option ? '#' + this.dataset.option : '') + "?wmode=opaque" + }); + }, + title: { + api: function(uid) { + return "https://gdata.youtube.com/feeds/api/videos/" + uid + "?alt=json&fields=title/text(),yt:noembed,app:control/yt:state/@reasonCode"; + }, + text: function() { + return JSON.parse(this.responseText).entry.title.$t; + } + } } } }; @@ -4958,12 +5019,11 @@ list = $("#list-" + type, QR.nodes.el); for (_i = 0, _len = arr.length; _i < _len; _i++) { val = arr[_i]; - if (!val) { - continue; + if (val) { + $.add(list, $.el('option', { + textContent: val + })); } - $.add(list, $.el('option', { - textContent: val - })); } }, getPassword: function() { @@ -9870,14 +9930,13 @@ _ref = Config.hotkeys; for (key in _ref) { val = _ref[key]; - if (!(key in data.Conf)) { - continue; + if (key in data.Conf) { + data.Conf[key] = data.Conf[key].replace(/ctrl|alt|meta/g, function(s) { + return "" + (s[0].toUpperCase()) + s.slice(1); + }).replace(/(^|.+\+)[A-Z]$/g, function(s) { + return "Shift+" + s.slice(0, -1) + (s.slice(-1).toLowerCase()); + }); } - data.Conf[key] = data.Conf[key].replace(/ctrl|alt|meta/g, function(s) { - return "" + (s[0].toUpperCase()) + s.slice(1); - }).replace(/(^|.+\+)[A-Z]$/g, function(s) { - return "Shift+" + s.slice(0, -1) + (s.slice(-1).toLowerCase()); - }); } data.Conf.WatchedThreads = data.WatchedThreads; } else if (version[0] === '3') { diff --git a/builds/appchan-x.user.js b/builds/appchan-x.user.js index 1d16d7f9c..a353d21fb 100644 --- a/builds/appchan-x.user.js +++ b/builds/appchan-x.user.js @@ -1,3 +1,4 @@ +// Generated by CoffeeScript // ==UserScript== // @name appchan x // @version 2.2.2 @@ -2787,13 +2788,12 @@ fd = new FormData(); for (key in form) { val = form[key]; - if (!val) { - continue; - } - if (val.size && val.name) { - fd.append(key, val, val.name); - } else { - fd.append(key, val); + if (val) { + if (val.size && val.name) { + fd.append(key, val, val.name); + } else { + fd.append(key, val); + } } } return fd; @@ -3437,7 +3437,7 @@ _ref1 = Get.allQuotelinksLinkingTo(this); for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { quotelink = _ref1[_j]; - if ($.hasClass(quotelink, 'deadlink')) { + if (!(!$.hasClass(quotelink, 'deadlink'))) { continue; } $.add(quotelink, $.tn('\u00A0(Dead)')); @@ -4140,6 +4140,7 @@ date: data.now, dateUTC: data.time, comment: data.com, + capReps: data.capcode_replies, isSticky: !!data.sticky, isClosed: !!data.closed }; @@ -4167,9 +4168,9 @@ @license: https://github.com/4chan/4chan-JS/blob/master/LICENSE */ - var a, boardID, capcode, capcodeClass, capcodeStart, closed, comment, container, date, dateUTC, email, emailEnd, emailStart, ext, file, fileDims, fileHTML, fileInfo, fileSize, fileThumb, filename, flag, flagCode, flagName, href, imgSrc, isClosed, isOP, isSticky, name, postID, quote, shortFilename, spoilerRange, staticPath, sticky, subject, threadID, tripcode, uniqueID, userID, _i, _len, _ref; + var a, array, boardID, capReps, capcode, capcodeClass, capcodeReplies, capcodeStart, capcodeType, closed, comment, container, date, dateUTC, email, emailEnd, emailStart, ext, file, fileDims, fileHTML, fileInfo, fileSize, fileThumb, filename, flag, flagCode, flagName, generateCapcodeReplies, href, imgSrc, isClosed, isOP, isSticky, name, postID, quote, shortFilename, spoilerRange, staticPath, sticky, subject, threadID, tripcode, uniqueID, userID, _i, _len, _ref; - postID = o.postID, threadID = o.threadID, 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, isSticky = o.isSticky, isClosed = o.isClosed, comment = o.comment, file = o.file; + 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, isSticky = o.isSticky, isClosed = o.isClosed, comment = o.comment, capReps = o.capReps, file = o.file; isOP = postID === threadID; staticPath = '//static.4chan.org/image/'; if (email) { @@ -4243,10 +4244,32 @@ tripcode = tripcode ? " " + tripcode + "" : ''; sticky = isSticky ? " Sticky" : ''; closed = isClosed ? " Closed" : ''; + capcodeReplies = ''; + if (capReps) { + generateCapcodeReplies = function(capcodeType, array) { + return "" + ((function() { + switch (capcodeType) { + case 'admin': + return 'Administrator'; + case 'mod': + return 'Moderator'; + case 'developer': + return 'Developer'; + } + })()) + " Repl" + (array.length > 1 ? 'ies' : 'y') + ": " + (array.map(function(ID) { + return ">>" + ID + ""; + }).join(' ')) + "
"; + }; + for (capcodeType in capReps) { + array = capReps[capcodeType]; + capcodeReplies += generateCapcodeReplies(capcodeType, array); + } + capcodeReplies = "

" + capcodeReplies + ""; + } container = $.el('div', { id: "pc" + postID, className: "postContainer " + (isOP ? 'op' : 'reply') + "Container", - innerHTML: (isOP ? '' : "
>>
") + ("
") + ("
") + ("") + ("" + (name || '') + "") + tripcode + capcodeStart + capcode + userID + flag + sticky + closed + ("
" + subject) + ("
" + date) + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? fileHTML : '') + ("
") + (" ") + ("" + subject + " ") + ("") + emailStart + ("" + (name || '') + "") + tripcode + capcodeStart + emailEnd + capcode + userID + flag + sticky + closed + ' ' + ("" + date + " ") + "" + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? '' : fileHTML) + ("
" + (comment || '') + "
") + '
' + innerHTML: (isOP ? '' : "
>>
") + ("
") + ("
") + ("") + ("" + (name || '') + "") + tripcode + capcodeStart + capcode + userID + flag + sticky + closed + ("
" + subject) + ("
" + date) + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? fileHTML : '') + ("
") + (" ") + ("" + subject + " ") + ("") + emailStart + ("" + (name || '') + "") + tripcode + capcodeStart + emailEnd + capcode + userID + flag + sticky + closed + ' ' + ("" + date + " ") + "" + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? '' : fileHTML) + ("
" + (comment || '') + capcodeReplies + "
") + '
' }); _ref = $$('.quotelink', container); for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -6620,6 +6643,9 @@ len = snapshot.snapshotLength; while (++i < len) { node = snapshot.snapshotItem(i); + if (node.parentElement.nodeName === "A") { + continue; + } data = node.data; if (Linkify.regString.test(data)) { Linkify.regString.lastIndex = 0; @@ -6652,7 +6678,7 @@ index = match.index; link = match[0]; len2 = index + link.length; - if (len - len2 === 0) { + if (len === len2) { break; } range = document.createRange(); @@ -6685,10 +6711,7 @@ } } if (range.collapsed) { - if (node.nodeName === 'WBR') { - node = node.previousSibling; - } - range.setEnd(node, node.length); + range.setEndAfter(node); } return Linkify.makeLink(range, post); }, @@ -6720,21 +6743,28 @@ } }, embed: function(data) { - var embed, key, link, options, uid; + var embed, href, key, link, name, options, uid, value, _ref; key = data[0], uid = data[1], options = data[2], link = data[3]; + href = link.href; embed = $.el('a', { - name: uid, - option: options, className: 'embedder', href: 'javascript:;', textContent: '(embed)' }); - embed.dataset.service = key; - embed.dataset.originalurl = link.href; - $.addClass(link, "" + embed.dataset.service); + _ref = { + key: key, + href: href, + uid: uid, + options: options + }; + for (name in _ref) { + value = _ref[name]; + embed.dataset[name] = value; + } + $.addClass(link, "" + embed.dataset.key); $.on(embed, 'click', Linkify.cb.toggle); - return $.after(link, [$.tn(' '), embed]); + $.after(link, [$.tn(' '), embed]); }, title: function(data) { var err, key, link, options, service, title, titles, uid; @@ -6780,23 +6810,24 @@ embed: function(a) { var el, style, type; - el = (type = Linkify.types[a.dataset.service]).el.call(a); + el = (type = Linkify.types[a.dataset.key]).el.call(a); el.style.cssText = (style = type.style) ? style : "border: 0; width: 640px; height: 390px"; a.textContent = '(unembed)'; return el; }, unembed: function(a) { - var el, url; + var el, href; + href = a.dataset.href; el = $.el('a', { rel: 'nofollow noreferrer', target: 'blank', className: 'linkify', - href: url = a.dataset.originalurl, - textContent: a.dataset.title || url + href: href, + textContent: a.dataset.title || href }); a.textContent = '(embed)'; - $.addClass(el, "" + a.dataset.service); + $.addClass(el, "" + a.dataset.key); return el; }, title: function(data) { @@ -6824,108 +6855,13 @@ } }, types: { - YouTube: { - regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/, - el: function() { - return $.el('iframe', { - src: "//www.youtube.com/embed/" + this.name + (this.option ? '#' + this.option : '') + "?wmode=opaque" - }); - }, - title: { - api: function(uid) { - return "https://gdata.youtube.com/feeds/api/videos/" + uid + "?alt=json&fields=title/text(),yt:noembed,app:control/yt:state/@reasonCode"; - }, - text: function() { - return JSON.parse(this.responseText).entry.title.$t; - } - } - }, - Vocaroo: { - regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/, - style: 'border: 0; width: 150px; height: 45px;', - el: function() { - return $.el('object', { - innerHTML: "" - }); - } - }, - Vimeo: { - regExp: /.*(?:vimeo.com\/)([^#\&\?]*).*/, - el: function() { - return $.el('iframe', { - src: "//player.vimeo.com/video/" + this.name + "?wmode=opaque" - }); - }, - title: { - api: function(uid) { - return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + uid; - }, - text: function() { - return JSON.parse(this.responseText).title; - } - } - }, - LiveLeak: { - regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/, - el: function() { - return $.el('object', { - innerHTML: "" - }); - } - }, audio: { regExp: /(.*\.(mp3|ogg|wav))$/, el: function() { return $.el('audio', { controls: 'controls', preload: 'auto', - src: this.name - }); - } - }, - image: { - regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/, - style: 'border: 0; width: auto; height: auto;', - el: function() { - return $.el('div', { - innerHTML: "" - }); - } - }, - SoundCloud: { - regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/, - style: 'height: auto; width: 500px; display: inline-block;', - el: function() { - var div; - - div = $.el('div', { - className: "soundcloud", - name: "soundcloud" - }); - $.ajax("//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + this.name, { - div: div, - onloadend: function() { - return this.div.innerHTML = JSON.parse(this.responseText).html; - } - }, false); - return div; - }, - title: { - api: function(uid) { - return "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + uid; - }, - text: function() { - return JSON.parse(this.responseText).title; - } - } - }, - pastebin: { - regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/, - el: function() { - var div; - - return div = $.el('iframe', { - src: "http://pastebin.com/embed_iframe.php?i=" + this.name + src: this.dataset.uid }); } }, @@ -6935,7 +6871,7 @@ var div; return div = $.el('iframe', { - src: "http://www.purplegene.com/script?url=https://gist.github.com/" + this.name + ".js" + src: "http://www.purplegene.com/script?url=https://gist.github.com/" + this.dataset.uid + ".js" }); }, title: { @@ -6954,13 +6890,138 @@ } } }, + image: { + regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/, + style: 'border: 0; width: auto; height: auto;', + el: function() { + return $.el('div', { + innerHTML: "" + }); + } + }, InstallGentoo: { regExp: /.*(?:paste.installgentoo.com\/view\/)([0-9a-z_]+)/, el: function() { return $.el('iframe', { - src: "http://paste.installgentoo.com/view/embed/" + this.name + src: "http://paste.installgentoo.com/view/embed/" + this.dataset.uid }); } + }, + LiveLeak: { + regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/, + el: function() { + return $.el('object', { + innerHTML: "" + }); + } + }, + pastebin: { + regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/, + el: function() { + var div; + + return div = $.el('iframe', { + src: "http://pastebin.com/embed_iframe.php?i=" + this.dataset.uid + }); + } + }, + SoundCloud: { + regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/, + style: 'height: auto; width: 500px; display: inline-block;', + el: function() { + var div; + + div = $.el('div', { + className: "soundcloud", + name: "soundcloud" + }); + $.ajax("//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + this.dataset.uid, { + div: div, + onloadend: function() { + return this.div.innerHTML = JSON.parse(this.responseText).html; + } + }, false); + return div; + }, + title: { + api: function(uid) { + return "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + uid; + }, + text: function() { + return JSON.parse(this.responseText).title; + } + } + }, + TwitchTV: { + regExp: /.*(?:twitch.tv\/)([^#\&\?]*).*/, + style: "border: none; width: 640px; height: 360px;", + el: function() { + var channel, chapter, result, _; + + if (result = /(\w+)\/(?:[a-z]\/)?(\d+)/i.exec(this.dataset.uid)) { + _ = result[0], channel = result[1], chapter = result[2]; + return $.el('object', { + data: 'http://www.twitch.tv/widgets/archive_embed_player.swf', + innerHTML: "\n" + }); + } else { + channel = (/(\w+)/.exec(this.dataset.uid))[0]; + return $.el('object', { + data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=" + channel, + innerHTML: "\n\n" + }); + } + } + }, + Vocaroo: { + regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/, + style: 'border: 0; width: 150px; height: 45px;', + el: function() { + return $.el('object', { + innerHTML: "" + }); + } + }, + Vimeo: { + regExp: /.*(?:vimeo.com\/)([^#\&\?]*).*/, + el: function() { + return $.el('iframe', { + src: "//player.vimeo.com/video/" + this.dataset.uid + "?wmode=opaque" + }); + }, + title: { + api: function(uid) { + return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + uid; + }, + text: function() { + return JSON.parse(this.responseText).title; + } + } + }, + Vine: { + regExp: /.*(?:vine.co\/)([^#\&\?]*).*/, + style: 'border: none; width: 500px; height: 500px;', + el: function() { + return $.el('iframe', { + src: "https://vine.co/" + this.dataset.uid + "/card" + }); + } + }, + YouTube: { + regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/, + el: function() { + return $.el('iframe', { + src: "//www.youtube.com/embed/" + this.dataset.uid + (this.dataset.option ? '#' + this.dataset.option : '') + "?wmode=opaque" + }); + }, + title: { + api: function(uid) { + return "https://gdata.youtube.com/feeds/api/videos/" + uid + "?alt=json&fields=title/text(),yt:noembed,app:control/yt:state/@reasonCode"; + }, + text: function() { + return JSON.parse(this.responseText).entry.title.$t; + } + } } } }; @@ -7242,12 +7303,11 @@ list = $("#list-" + type, QR.nodes.el); for (_i = 0, _len = arr.length; _i < _len; _i++) { val = arr[_i]; - if (!val) { - continue; + if (val) { + $.add(list, $.el('option', { + textContent: val + })); } - $.add(list, $.el('option', { - textContent: val - })); } }, getPassword: function() { diff --git a/builds/crx/script.js b/builds/crx/script.js index 6470fd0e9..0c36aab39 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -2770,13 +2770,12 @@ fd = new FormData(); for (key in form) { val = form[key]; - if (!val) { - continue; - } - if (val.size && val.name) { - fd.append(key, val, val.name); - } else { - fd.append(key, val); + if (val) { + if (val.size && val.name) { + fd.append(key, val, val.name); + } else { + fd.append(key, val); + } } } return fd; @@ -3451,7 +3450,7 @@ _ref1 = Get.allQuotelinksLinkingTo(this); for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { quotelink = _ref1[_j]; - if ($.hasClass(quotelink, 'deadlink')) { + if (!(!$.hasClass(quotelink, 'deadlink'))) { continue; } $.add(quotelink, $.tn('\u00A0(Dead)')); @@ -4154,6 +4153,7 @@ date: data.now, dateUTC: data.time, comment: data.com, + capReps: data.capcode_replies, isSticky: !!data.sticky, isClosed: !!data.closed }; @@ -4181,9 +4181,9 @@ @license: https://github.com/4chan/4chan-JS/blob/master/LICENSE */ - var a, boardID, capcode, capcodeClass, capcodeStart, closed, comment, container, date, dateUTC, email, emailEnd, emailStart, ext, file, fileDims, fileHTML, fileInfo, fileSize, fileThumb, filename, flag, flagCode, flagName, href, imgSrc, isClosed, isOP, isSticky, name, postID, quote, shortFilename, spoilerRange, staticPath, sticky, subject, threadID, tripcode, uniqueID, userID, _i, _len, _ref; + var a, array, boardID, capReps, capcode, capcodeClass, capcodeReplies, capcodeStart, capcodeType, closed, comment, container, date, dateUTC, email, emailEnd, emailStart, ext, file, fileDims, fileHTML, fileInfo, fileSize, fileThumb, filename, flag, flagCode, flagName, generateCapcodeReplies, href, imgSrc, isClosed, isOP, isSticky, name, postID, quote, shortFilename, spoilerRange, staticPath, sticky, subject, threadID, tripcode, uniqueID, userID, _i, _len, _ref; - postID = o.postID, threadID = o.threadID, 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, isSticky = o.isSticky, isClosed = o.isClosed, comment = o.comment, file = o.file; + 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, isSticky = o.isSticky, isClosed = o.isClosed, comment = o.comment, capReps = o.capReps, file = o.file; isOP = postID === threadID; staticPath = '//static.4chan.org/image/'; if (email) { @@ -4257,10 +4257,32 @@ tripcode = tripcode ? " " + tripcode + "" : ''; sticky = isSticky ? " Sticky" : ''; closed = isClosed ? " Closed" : ''; + capcodeReplies = ''; + if (capReps) { + generateCapcodeReplies = function(capcodeType, array) { + return "" + ((function() { + switch (capcodeType) { + case 'admin': + return 'Administrator'; + case 'mod': + return 'Moderator'; + case 'developer': + return 'Developer'; + } + })()) + " Repl" + (array.length > 1 ? 'ies' : 'y') + ": " + (array.map(function(ID) { + return ">>" + ID + ""; + }).join(' ')) + "
"; + }; + for (capcodeType in capReps) { + array = capReps[capcodeType]; + capcodeReplies += generateCapcodeReplies(capcodeType, array); + } + capcodeReplies = "

" + capcodeReplies + ""; + } container = $.el('div', { id: "pc" + postID, className: "postContainer " + (isOP ? 'op' : 'reply') + "Container", - innerHTML: (isOP ? '' : "
>>
") + ("
") + ("
") + ("") + ("" + (name || '') + "") + tripcode + capcodeStart + capcode + userID + flag + sticky + closed + ("
" + subject) + ("
" + date) + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? fileHTML : '') + ("
") + (" ") + ("" + subject + " ") + ("") + emailStart + ("" + (name || '') + "") + tripcode + capcodeStart + emailEnd + capcode + userID + flag + sticky + closed + ' ' + ("" + date + " ") + "" + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? '' : fileHTML) + ("
" + (comment || '') + "
") + '
' + innerHTML: (isOP ? '' : "
>>
") + ("
") + ("
") + ("") + ("" + (name || '') + "") + tripcode + capcodeStart + capcode + userID + flag + sticky + closed + ("
" + subject) + ("
" + date) + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? fileHTML : '') + ("
") + (" ") + ("" + subject + " ") + ("") + emailStart + ("" + (name || '') + "") + tripcode + capcodeStart + emailEnd + capcode + userID + flag + sticky + closed + ' ' + ("" + date + " ") + "" + ("No.") + ("" + postID + "") + '' + '
' + (isOP ? '' : fileHTML) + ("
" + (comment || '') + capcodeReplies + "
") + '
' }); _ref = $$('.quotelink', container); for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -6627,6 +6649,9 @@ len = snapshot.snapshotLength; while (++i < len) { node = snapshot.snapshotItem(i); + if (node.parentElement.nodeName === "A") { + continue; + } data = node.data; if (Linkify.regString.test(data)) { Linkify.regString.lastIndex = 0; @@ -6659,7 +6684,7 @@ index = match.index; link = match[0]; len2 = index + link.length; - if (len - len2 === 0) { + if (len === len2) { break; } range = document.createRange(); @@ -6692,10 +6717,7 @@ } } if (range.collapsed) { - if (node.nodeName === 'WBR') { - node = node.previousSibling; - } - range.setEnd(node, node.length); + range.setEndAfter(node); } return Linkify.makeLink(range, post); }, @@ -6727,21 +6749,28 @@ } }, embed: function(data) { - var embed, key, link, options, uid; + var embed, href, key, link, name, options, uid, value, _ref; key = data[0], uid = data[1], options = data[2], link = data[3]; + href = link.href; embed = $.el('a', { - name: uid, - option: options, className: 'embedder', href: 'javascript:;', textContent: '(embed)' }); - embed.dataset.service = key; - embed.dataset.originalurl = link.href; - $.addClass(link, "" + embed.dataset.service); + _ref = { + key: key, + href: href, + uid: uid, + options: options + }; + for (name in _ref) { + value = _ref[name]; + embed.dataset[name] = value; + } + $.addClass(link, "" + embed.dataset.key); $.on(embed, 'click', Linkify.cb.toggle); - return $.after(link, [$.tn(' '), embed]); + $.after(link, [$.tn(' '), embed]); }, title: function(data) { var err, key, link, options, service, title, titles, uid; @@ -6787,23 +6816,24 @@ embed: function(a) { var el, style, type; - el = (type = Linkify.types[a.dataset.service]).el.call(a); + el = (type = Linkify.types[a.dataset.key]).el.call(a); el.style.cssText = (style = type.style) ? style : "border: 0; width: 640px; height: 390px"; a.textContent = '(unembed)'; return el; }, unembed: function(a) { - var el, url; + var el, href; + href = a.dataset.href; el = $.el('a', { rel: 'nofollow noreferrer', target: 'blank', className: 'linkify', - href: url = a.dataset.originalurl, - textContent: a.dataset.title || url + href: href, + textContent: a.dataset.title || href }); a.textContent = '(embed)'; - $.addClass(el, "" + a.dataset.service); + $.addClass(el, "" + a.dataset.key); return el; }, title: function(data) { @@ -6831,108 +6861,13 @@ } }, types: { - YouTube: { - regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/, - el: function() { - return $.el('iframe', { - src: "//www.youtube.com/embed/" + this.name + (this.option ? '#' + this.option : '') + "?wmode=opaque" - }); - }, - title: { - api: function(uid) { - return "https://gdata.youtube.com/feeds/api/videos/" + uid + "?alt=json&fields=title/text(),yt:noembed,app:control/yt:state/@reasonCode"; - }, - text: function() { - return JSON.parse(this.responseText).entry.title.$t; - } - } - }, - Vocaroo: { - regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/, - style: 'border: 0; width: 150px; height: 45px;', - el: function() { - return $.el('object', { - innerHTML: "" - }); - } - }, - Vimeo: { - regExp: /.*(?:vimeo.com\/)([^#\&\?]*).*/, - el: function() { - return $.el('iframe', { - src: "//player.vimeo.com/video/" + this.name + "?wmode=opaque" - }); - }, - title: { - api: function(uid) { - return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + uid; - }, - text: function() { - return JSON.parse(this.responseText).title; - } - } - }, - LiveLeak: { - regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/, - el: function() { - return $.el('object', { - innerHTML: "" - }); - } - }, audio: { regExp: /(.*\.(mp3|ogg|wav))$/, el: function() { return $.el('audio', { controls: 'controls', preload: 'auto', - src: this.name - }); - } - }, - image: { - regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/, - style: 'border: 0; width: auto; height: auto;', - el: function() { - return $.el('div', { - innerHTML: "" - }); - } - }, - SoundCloud: { - regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/, - style: 'height: auto; width: 500px; display: inline-block;', - el: function() { - var div; - - div = $.el('div', { - className: "soundcloud", - name: "soundcloud" - }); - $.ajax("//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + this.name, { - div: div, - onloadend: function() { - return this.div.innerHTML = JSON.parse(this.responseText).html; - } - }, false); - return div; - }, - title: { - api: function(uid) { - return "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + uid; - }, - text: function() { - return JSON.parse(this.responseText).title; - } - } - }, - pastebin: { - regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/, - el: function() { - var div; - - return div = $.el('iframe', { - src: "http://pastebin.com/embed_iframe.php?i=" + this.name + src: this.dataset.uid }); } }, @@ -6942,7 +6877,7 @@ var div; return div = $.el('iframe', { - src: "http://www.purplegene.com/script?url=https://gist.github.com/" + this.name + ".js" + src: "http://www.purplegene.com/script?url=https://gist.github.com/" + this.dataset.uid + ".js" }); }, title: { @@ -6961,13 +6896,138 @@ } } }, + image: { + regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/, + style: 'border: 0; width: auto; height: auto;', + el: function() { + return $.el('div', { + innerHTML: "" + }); + } + }, InstallGentoo: { regExp: /.*(?:paste.installgentoo.com\/view\/)([0-9a-z_]+)/, el: function() { return $.el('iframe', { - src: "http://paste.installgentoo.com/view/embed/" + this.name + src: "http://paste.installgentoo.com/view/embed/" + this.dataset.uid }); } + }, + LiveLeak: { + regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/, + el: function() { + return $.el('object', { + innerHTML: "" + }); + } + }, + pastebin: { + regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/, + el: function() { + var div; + + return div = $.el('iframe', { + src: "http://pastebin.com/embed_iframe.php?i=" + this.dataset.uid + }); + } + }, + SoundCloud: { + regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/, + style: 'height: auto; width: 500px; display: inline-block;', + el: function() { + var div; + + div = $.el('div', { + className: "soundcloud", + name: "soundcloud" + }); + $.ajax("//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + this.dataset.uid, { + div: div, + onloadend: function() { + return this.div.innerHTML = JSON.parse(this.responseText).html; + } + }, false); + return div; + }, + title: { + api: function(uid) { + return "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + uid; + }, + text: function() { + return JSON.parse(this.responseText).title; + } + } + }, + TwitchTV: { + regExp: /.*(?:twitch.tv\/)([^#\&\?]*).*/, + style: "border: none; width: 640px; height: 360px;", + el: function() { + var channel, chapter, result, _; + + if (result = /(\w+)\/(?:[a-z]\/)?(\d+)/i.exec(this.dataset.uid)) { + _ = result[0], channel = result[1], chapter = result[2]; + return $.el('object', { + data: 'http://www.twitch.tv/widgets/archive_embed_player.swf', + innerHTML: "\n" + }); + } else { + channel = (/(\w+)/.exec(this.dataset.uid))[0]; + return $.el('object', { + data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=" + channel, + innerHTML: "\n\n" + }); + } + } + }, + Vocaroo: { + regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/, + style: 'border: 0; width: 150px; height: 45px;', + el: function() { + return $.el('object', { + innerHTML: "" + }); + } + }, + Vimeo: { + regExp: /.*(?:vimeo.com\/)([^#\&\?]*).*/, + el: function() { + return $.el('iframe', { + src: "//player.vimeo.com/video/" + this.dataset.uid + "?wmode=opaque" + }); + }, + title: { + api: function(uid) { + return "https://vimeo.com/api/oembed.json?url=http://vimeo.com/" + uid; + }, + text: function() { + return JSON.parse(this.responseText).title; + } + } + }, + Vine: { + regExp: /.*(?:vine.co\/)([^#\&\?]*).*/, + style: 'border: none; width: 500px; height: 500px;', + el: function() { + return $.el('iframe', { + src: "https://vine.co/" + this.dataset.uid + "/card" + }); + } + }, + YouTube: { + regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/, + el: function() { + return $.el('iframe', { + src: "//www.youtube.com/embed/" + this.dataset.uid + (this.dataset.option ? '#' + this.dataset.option : '') + "?wmode=opaque" + }); + }, + title: { + api: function(uid) { + return "https://gdata.youtube.com/feeds/api/videos/" + uid + "?alt=json&fields=title/text(),yt:noembed,app:control/yt:state/@reasonCode"; + }, + text: function() { + return JSON.parse(this.responseText).entry.title.$t; + } + } } } }; @@ -7250,12 +7310,11 @@ list = $("#list-" + type, QR.nodes.el); for (_i = 0, _len = arr.length; _i < _len; _i++) { val = arr[_i]; - if (!val) { - continue; + if (val) { + $.add(list, $.el('option', { + textContent: val + })); } - $.add(list, $.el('option', { - textContent: val - })); } }, getPassword: function() { diff --git a/src/General/Build.coffee b/src/General/Build.coffee index 4f4453e6d..bb0903db1 100644 --- a/src/General/Build.coffee +++ b/src/General/Build.coffee @@ -27,6 +27,7 @@ Build = date: data.now dateUTC: data.time comment: data.com + capReps: data.capcode_replies # thread status isSticky: !!data.sticky isClosed: !!data.closed @@ -58,7 +59,7 @@ Build = postID, threadID, boardID name, capcode, tripcode, uniqueID, email, subject, flagCode, flagName, date, dateUTC isSticky, isClosed - comment + comment, capReps file } = o isOP = postID is threadID @@ -176,22 +177,39 @@ Build = else fileHTML = '' - tripcode = - if tripcode - " #{tripcode}" - else - '' + tripcode = if tripcode + " #{tripcode}" + else + '' - sticky = - if isSticky - " Sticky" - else - '' - closed = - if isClosed - " Closed" - else - '' + sticky = if isSticky + " Sticky" + else + '' + closed = if isClosed + " Closed" + else + '' + + capcodeReplies = '' + if capReps + generateCapcodeReplies = (capcodeType, array) -> + "#{ + switch capcodeType + when 'admin' + 'Administrator' + when 'mod' + 'Moderator' + when 'developer' + 'Developer' + } Repl#{if array.length > 1 then 'ies' else 'y'}: #{ + array.map (ID) -> + ">>#{ID}" + .join ' ' + }
" + for capcodeType, array of capReps + capcodeReplies += generateCapcodeReplies capcodeType, array + capcodeReplies = "

#{capcodeReplies}" container = $.el 'div', id: "pc#{postID}" @@ -245,7 +263,7 @@ Build = (if isOP then '' else fileHTML) + - "
#{comment or ''}
" + + "
#{comment or ''}#{capcodeReplies}
" + '' diff --git a/src/General/lib/$.coffee b/src/General/lib/$.coffee index 8cf3f31b6..a9afda0bb 100644 --- a/src/General/lib/$.coffee +++ b/src/General/lib/$.coffee @@ -61,8 +61,7 @@ $.formData = (form) -> if form instanceof HTMLFormElement return new FormData form fd = new FormData() - for key, val of form - continue unless val + for key, val of form when val # XXX GM bug # if val instanceof Blob if val.size and val.name diff --git a/src/General/lib/post.class b/src/General/lib/post.class index 2b5c26aa4..02e9fb9a0 100644 --- a/src/General/lib/post.class +++ b/src/General/lib/post.class @@ -174,8 +174,7 @@ class Post return if file # Get quotelinks/backlinks to this post # and paint them (Dead). - for quotelink in Get.allQuotelinksLinkingTo @ - continue if $.hasClass quotelink, 'deadlink' + for quotelink in Get.allQuotelinksLinkingTo @ when not $.hasClass quotelink, 'deadlink' $.add quotelink, $.tn '\u00A0(Dead)' $.addClass quotelink, 'deadlink' return diff --git a/src/Linkification/Linkify.coffee b/src/Linkification/Linkify.coffee index c32ec484e..ba46a0c58 100644 --- a/src/Linkification/Linkify.coffee +++ b/src/Linkification/Linkify.coffee @@ -44,6 +44,9 @@ Linkify = while ++i < len node = snapshot.snapshotItem i + + continue if node.parentElement.nodeName is "A" + data = node.data if Linkify.regString.test data @@ -69,7 +72,7 @@ Linkify = link = match[0] len2 = index + link.length - break if len - len2 is 0 + break if len is len2 range = document.createRange(); range.setStart node, index @@ -99,9 +102,7 @@ Linkify = range.setEnd node, result.index if range.collapsed - if node.nodeName is 'WBR' - node = node.previousSibling - range.setEnd node, node.length + range.setEndAfter node Linkify.makeLink range, post @@ -137,20 +138,20 @@ Linkify = embed: (data) -> [key, uid, options, link] = data + href = link.href embed = $.el 'a', - name: uid - option: options className: 'embedder' href: 'javascript:;' textContent: '(embed)' - embed.dataset.service = key - embed.dataset.originalurl = link.href + for name, value of {key, href, uid, options} + embed.dataset[name] = value - $.addClass link, "#{embed.dataset.service}" + $.addClass link, "#{embed.dataset.key}" $.on embed, 'click', Linkify.cb.toggle $.after link, [$.tn(' '), embed] + return title: (data) -> [key, uid, options, link] = data @@ -190,7 +191,7 @@ Linkify = embed: (a) -> # We create an element to embed - el = (type = Linkify.types[a.dataset.service]).el.call a + el = (type = Linkify.types[a.dataset.key]).el.call a # Set style values. el.style.cssText = if style = type.style @@ -204,15 +205,16 @@ Linkify = unembed: (a) -> # Recreate the original link. + {href} = a.dataset el = $.el 'a', rel: 'nofollow noreferrer' target: 'blank' className: 'linkify' - href: url = a.dataset.originalurl - textContent: a.dataset.title or url + href: href + textContent: a.dataset.title or href a.textContent = '(embed)' - $.addClass el, "#{a.dataset.service}" + $.addClass el, "#{a.dataset.key}" return el @@ -233,51 +235,50 @@ Linkify = "[#{key}] #{@status}'d" types: - YouTube: - regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/ - el: -> - $.el 'iframe', - src: "//www.youtube.com/embed/#{@name}#{if @option then '#' + @option else ''}?wmode=opaque" - title: - api: (uid) -> "https://gdata.youtube.com/feeds/api/videos/#{uid}?alt=json&fields=title/text(),yt:noembed,app:control/yt:state/@reasonCode" - text: -> JSON.parse(@responseText).entry.title.$t - - Vocaroo: - regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/ - style: 'border: 0; width: 150px; height: 45px;' - el: -> - $.el 'object', - innerHTML: "" - - Vimeo: - regExp: /.*(?:vimeo.com\/)([^#\&\?]*).*/ - el: -> - $.el 'iframe', - src: "//player.vimeo.com/video/#{@name}?wmode=opaque" - title: - api: (uid) -> "https://vimeo.com/api/oembed.json?url=http://vimeo.com/#{uid}" - text: -> JSON.parse(@responseText).title - - LiveLeak: - regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/ - el: -> - $.el 'object', - innerHTML: "" - audio: - regExp: /(.*\.(mp3|ogg|wav))$/ + regExp: /(.*\.(mp3|ogg|wav))$/ el: -> $.el 'audio', controls: 'controls' preload: 'auto' - src: @name + src: @dataset.uid + + gist: + regExp: /.*(?:gist.github.com.*\/)([^\/][^\/]*)$/ + el: -> + div = $.el 'iframe', + # Github doesn't allow embedding straight from the site, so we use an external site to bypass that. + src: "http://www.purplegene.com/script?url=https://gist.github.com/#{@dataset.uid}.js" + title: + api: (uid) -> "https://api.github.com/gists/#{uid}" + text: -> + response = JSON.parse(@responseText).files + return file for file of response when response.hasOwnProperty file image: - regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/ + regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/ style: 'border: 0; width: auto; height: auto;' el: -> $.el 'div', - innerHTML: "" + innerHTML: "" + + InstallGentoo: + regExp: /.*(?:paste.installgentoo.com\/view\/)([0-9a-z_]+)/ + el: -> + $.el 'iframe', + src: "http://paste.installgentoo.com/view/embed/#{@dataset.uid}" + + LiveLeak: + regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/ + el: -> + $.el 'object', + innerHTML: "" + + pastebin: + regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/ + el: -> + div = $.el 'iframe', + src: "http://pastebin.com/embed_iframe.php?i=#{@dataset.uid}" SoundCloud: regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/ @@ -287,7 +288,7 @@ Linkify = className: "soundcloud" name: "soundcloud" $.ajax( - "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/#{@name}" + "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/#{@dataset.uid}" div: div onloadend: -> @div.innerHTML = JSON.parse(@responseText).html @@ -297,26 +298,59 @@ Linkify = api: (uid) -> "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/#{uid}" text: -> JSON.parse(@responseText).title - pastebin: - regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/ + TwitchTV: + regExp: /.*(?:twitch.tv\/)([^#\&\?]*).*/ + style: "border: none; width: 640px; height: 360px;" el: -> - div = $.el 'iframe', - src: "http://pastebin.com/embed_iframe.php?i=#{@name}" + if result = /(\w+)\/(?:[a-z]\/)?(\d+)/i.exec @dataset.uid + [_, channel, chapter] = result - gist: - regExp: /.*(?:gist.github.com.*\/)([^\/][^\/]*)$/ + $.el 'object', + data: 'http://www.twitch.tv/widgets/archive_embed_player.swf' + innerHTML: """ + + +""" + + else + channel = (/(\w+)/.exec @dataset.uid)[0] + + $.el 'object', + data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=#{channel}" + innerHTML: """ + + + +""" + + Vocaroo: + regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/ + style: 'border: 0; width: 150px; height: 45px;' el: -> - div = $.el 'iframe', - # Github doesn't allow embedding straight from the site, so we use an external site to bypass that. - src: "http://www.purplegene.com/script?url=https://gist.github.com/#{@name}.js" - title: - api: (uid) -> "https://api.github.com/gists/#{uid}" - text: -> - response = JSON.parse(@responseText).files - return file for file of response when response.hasOwnProperty file + $.el 'object', + innerHTML: "" - InstallGentoo: - regExp: /.*(?:paste.installgentoo.com\/view\/)([0-9a-z_]+)/ + Vimeo: + regExp: /.*(?:vimeo.com\/)([^#\&\?]*).*/ el: -> $.el 'iframe', - src: "http://paste.installgentoo.com/view/embed/#{@name}" \ No newline at end of file + src: "//player.vimeo.com/video/#{@dataset.uid}?wmode=opaque" + title: + api: (uid) -> "https://vimeo.com/api/oembed.json?url=http://vimeo.com/#{uid}" + text: -> JSON.parse(@responseText).title + + Vine: + regExp: /.*(?:vine.co\/)([^#\&\?]*).*/ + style: 'border: none; width: 500px; height: 500px;' + el: -> + $.el 'iframe', + src: "https://vine.co/#{@dataset.uid}/card" + + YouTube: + regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/ + el: -> + $.el 'iframe', + src: "//www.youtube.com/embed/#{@dataset.uid}#{if @dataset.option then '#' + @dataset.option else ''}?wmode=opaque" + title: + api: (uid) -> "https://gdata.youtube.com/feeds/api/videos/#{uid}?alt=json&fields=title/text(),yt:noembed,app:control/yt:state/@reasonCode" + text: -> JSON.parse(@responseText).entry.title.$t \ No newline at end of file diff --git a/src/Posting/QuickReply.coffee b/src/Posting/QuickReply.coffee index 2be479ea3..18104756e 100644 --- a/src/Posting/QuickReply.coffee +++ b/src/Posting/QuickReply.coffee @@ -215,9 +215,7 @@ QR = loadPersonas: (type, arr) -> list = $ "#list-#{type}", QR.nodes.el - for val in arr - # XXX Firefox displays empty