diff --git a/CHANGELOG.md b/CHANGELOG.md index 34b68534c..c39d350cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +**ccd0**: +- Support expansion of .webm videos. +- Update archives with data from MayhemYDG fork. + ### v2.9.11 *2014-04-03* diff --git a/Gruntfile.coffee b/Gruntfile.coffee index 464cd9434..cc725392f 100755 --- a/Gruntfile.coffee +++ b/Gruntfile.coffee @@ -50,7 +50,6 @@ module.exports = (grunt) -> crx: files: 'builds/crx/manifest.json': 'src/General/meta/manifest.json' - 'builds/updates.xml': 'src/General/meta/updates.xml' 'builds/crx/script.js': [ 'src/General/meta/botproc.js' 'src/General/meta/banner.js' diff --git a/LICENSE b/LICENSE index 4d40e53ac..42e0d92f1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ /* -* appchan x - Version 2.9.11 - 2014-04-03 +* appchan x - Version 2.9.11 - 2014-04-04 * * Licensed under the MIT license. * https://github.com/zixaphir/appchan-x/blob/master/LICENSE diff --git a/builds/4chan-X.meta.js b/builds/4chan-X.meta.js index 524f9a534..dad0b6be8 100755 --- a/builds/4chan-X.meta.js +++ b/builds/4chan-X.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.4.5 +// @version 1.5.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -17,7 +17,7 @@ // @grant GM_openInTab // @grant GM_xmlhttpRequest // @run-at document-start -// @updateURL https://github.com/ccd0/4chan-x/raw/stable/builds/4chan-X.meta.js -// @downloadURL https://github.com/ccd0/4chan-x/raw/stable/builds/4chan-X.user.js +// @updateURL https://ccd0.github.io/4chan-x/builds/4chan-X.meta.js +// @downloadURL https://ccd0.github.io/4chan-x/builds/4chan-X.user.js // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAF5JREFUeNrtkTESABAQxPD/R6tsE2dUGYUtFJvLDKf93KevHJAjpBorAQWSBIKqFASC4G0pCAkm4GfaEvgYXl0T6HBaE97f0vmnfYHbZOMLZCx9ISdKWwjOWZSC8GYm4SUGwfYgqI4AAAAASUVORK5CYII= // ==/UserScript== diff --git a/builds/appchan-x.meta.js b/builds/appchan-x.meta.js index 1318c264d..831624529 100644 --- a/builds/appchan-x.meta.js +++ b/builds/appchan-x.meta.js @@ -18,7 +18,7 @@ // @grant GM_openInTab // @grant GM_xmlhttpRequest // @run-at document-start -// @updateURL https://github.com/zixaphir/appchan-x/raw/stable/builds/appchan-x.meta.js -// @downloadURL https://github.com/zixaphir/appchan-x/raw/stable/builds/appchan-x.user.js +// @updateURL appchan-x.meta.js +// @downloadURL appchan-x.user.js // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAElBMVEX///8EZgR8ulSk0oT///8EAgQ1A88mAAAAAXRSTlMAQObYZgAAAIpJREFUeF6t0sENwjAMhWF84N4H6gAYMUBkdQMYwfuvwmstEeD4kl892P0OaaWcpga2/K0SGII1HNBXARgu7veoY3ANd+esgMHZIz85u0EABrbms3pl/bkC1Tn5ihGOfQwqHeZ/FdYdirEMgCG2ZAQWDTL0m9FvjAhcvoGNAK2gZhGYYX9+ZgFm9gaiNmNkMENY4QAAAABJRU5ErkJggg== // ==/UserScript== diff --git a/builds/appchan-x.user.js b/builds/appchan-x.user.js index 7a501b752..145456160 100644 --- a/builds/appchan-x.user.js +++ b/builds/appchan-x.user.js @@ -19,13 +19,13 @@ // @grant GM_openInTab // @grant GM_xmlhttpRequest // @run-at document-start -// @updateURL https://github.com/zixaphir/appchan-x/raw/stable/builds/appchan-x.meta.js -// @downloadURL https://github.com/zixaphir/appchan-x/raw/stable/builds/appchan-x.user.js +// @updateURL appchan-x.meta.js +// @downloadURL appchan-x.user.js // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAElBMVEX///8EZgR8ulSk0oT///8EAgQ1A88mAAAAAXRSTlMAQObYZgAAAIpJREFUeF6t0sENwjAMhWF84N4H6gAYMUBkdQMYwfuvwmstEeD4kl892P0OaaWcpga2/K0SGII1HNBXARgu7veoY3ANd+esgMHZIz85u0EABrbms3pl/bkC1Tn5ihGOfQwqHeZ/FdYdirEMgCG2ZAQWDTL0m9FvjAhcvoGNAK2gZhGYYX9+ZgFm9gaiNmNkMENY4QAAAABJRU5ErkJggg== // ==/UserScript== /* -* appchan x - Version 2.9.11 - 2014-04-03 +* appchan x - Version 2.9.11 - 2014-04-04 * * Licensed under the MIT license. * https://github.com/zixaphir/appchan-x/blob/master/LICENSE @@ -170,8 +170,8 @@ 'Filtered Backlinks': [true, 'When enabled, shows backlinks to filtered posts with a line-through decoration. Otherwise, hides the backlinks.'], 'Stubs': [true, 'Show stubs of hidden threads / replies.'] }, - 'Images': { - 'Image Expansion': [true, 'Expand images.'], + 'Images and Videos': { + 'Image Expansion': [true, 'Expand images / videos.'], 'Image Hover': [true, 'Show full image on mouseover.'], 'Image Hover in Catalog': [false, 'Show a floating expanded image on hover in the catalog.'], 'Gallery': [true, 'Adds a simple and cute image gallery.'], @@ -182,7 +182,9 @@ 'Replace JPG': [false, 'Replace jpgs.'], 'Image Prefetching': [false, 'Preload images'], 'Fappe Tyme': [false, 'Hide posts without images when toggled. *hint* *hint*'], - 'Werk Tyme': [false, 'Hide all post images when toggled.'] + 'Werk Tyme': [false, 'Hide all post images when toggled.'], + 'Autoplay': [true, 'Videos begin playing immediately when opened inline.'], + 'Show Controls': [true, 'Show native seek and volume controls on videos. Contract videos when dragged to the left.'] }, 'Menu': { 'Menu': [true, 'Add a drop-down menu to posts.'], @@ -3392,7 +3394,9 @@ this.file.sizeInBytes = size; this.file.thumbURL = that.isArchived ? thumb.src : "" + location.protocol + "//t.4cdn.org/" + this.board + "/thumb/" + (this.file.URL.match(/(\d+)\./)[1]) + "s.jpg"; this.file.name = (nameNode = $('span', fileText)) ? nameNode.title || nameNode.textContent : fileText.title; - if (this.file.isImage = /(jpg|png|gif)$/i.test(this.file.name)) { + this.file.isImage = /(jpg|png|gif)$/i.test(this.file.name); + this.file.isVideo = /webm$/i.test(this.file.name); + if (this.file.isImage || this.file.isVideo) { return this.file.dimensions = fileText.textContent.match(/\d+x\d+/)[0]; } }; @@ -10649,8 +10653,8 @@ }); }, node: function() { - var thumb, _ref; - if (!((_ref = this.file) != null ? _ref.isImage : void 0)) { + var thumb, _ref, _ref1; + if (!(((_ref = this.file) != null ? _ref.isImage : void 0) || ((_ref1 = this.file) != null ? _ref1.isVideo : void 0))) { return; } thumb = this.file.thumb; @@ -10690,7 +10694,7 @@ for (_i = 0, _len = _ref.length; _i < _len; _i++) { post = _ref[_i]; file = post.file; - if (!(file && file.isImage && doc.contains(post.nodes.root))) { + if (!(file && (file.isImage || file.isVideo) && doc.contains(post.nodes.root))) { return; } if (ImageExpand.on && (!Conf['Expand spoilers'] && file.isSpoiler || Conf['Expand from here'] && Header.getTopOf(file.thumb) < 0)) { @@ -10739,36 +10743,51 @@ return ImageExpand.contract(post); }, contract: function(post) { + var _ref, _ref1; + if (post.file.isVideo) { + if ((_ref = post.file.fullImage) != null) { + _ref.pause(); + } + } $.rmClass(post.nodes.root, 'expanded-image'); $.rmClass(post.file.thumb, 'expanding'); - return post.file.isExpanded = false; + post.file.isExpanded = false; + if ((_ref1 = post.file.videoControls) != null) { + _ref1.map($.rm); + } + return delete post.file.videoControls; }, expand: function(post, src) { - var img, thumb; - thumb = post.file.thumb; - if (post.file.isExpanded || $.hasClass(thumb, 'expanding')) { + var img, isVideo, naturalHeight, thumb, _ref; + _ref = post.file, thumb = _ref.thumb, isVideo = _ref.isVideo; + if (post.isHidden || post.file.isExpanded || $.hasClass(thumb, 'expanding')) { return; } $.addClass(thumb, 'expanding'); + naturalHeight = isVideo ? 'videoHeight' : 'naturalHeight'; if (post.file.fullImage) { $.asap((function() { - return post.file.fullImage.naturalHeight; + return post.file.fullImage[naturalHeight]; }), function() { return ImageExpand.completeExpand(post); }); return; } - post.file.fullImage = img = $.el('img', { + post.file.fullImage = img = $.el((isVideo ? 'video' : 'img'), { className: 'full-image', src: src || post.file.URL }); + if (isVideo) { + img.loop = true; + img.controls = Conf['Show Controls']; + } $.on(img, 'error', ImageExpand.error); $.asap((function() { - return post.file.fullImage.naturalHeight; + return post.file.fullImage[naturalHeight]; }), function() { return ImageExpand.completeExpand(post); }); - return $.after(thumb, img); + return $.after((img.controls ? thumb.parentNode : thumb), img); }, completeExpand: function(post) { var bottom, thumb; @@ -10777,6 +10796,9 @@ return; } post.file.isExpanded = true; + if (post.file.isVideo) { + ImageExpand.setupVideo(post); + } if (!post.nodes.root.parentNode) { $.addClass(post.nodes.root, 'expanded-image'); $.rmClass(post.file.thumb, 'expanding'); @@ -10792,6 +10814,57 @@ return window.scrollBy(0, post.nodes.root.getBoundingClientRect().bottom - bottom); }); }, + setupVideo: function(post) { + var contract, file, play, video; + file = post.file; + video = file.fullImage; + file.videoControls = []; + video.muted = true; + if (video.controls) { + contract = $.el('a', { + textContent: 'contract', + href: 'javascript:;', + title: 'You can also contract the video by dragging it to the left.' + }); + $.on(contract, 'click', function(e) { + return ImageExpand.contract(post); + }); + file.videoControls.push($.tn('\u00A0'), contract); + file.mousedown = false; + $.on(video, 'mousedown', function(e) { + if (e.button === 0) { + return file.mousedown = true; + } + }); + $.on(video, 'mouseup', function(e) { + if (e.button === 0) { + return file.mousedown = false; + } + }); + $.on(video, 'mouseover', function(e) { + return file.mousedown = false; + }); + $.on(video, 'mouseout', function(e) { + if (file.mousedown && e.clientX <= video.getBoundingClientRect().left) { + return ImageExpand.contract(post); + } + }); + } + if (Conf['Autoplay']) { + video.play(); + } else if (!video.controls) { + play = $.el('a', { + textContent: 'play', + href: 'javascript:;' + }); + $.on(play, 'click', function(e) { + video[this.textContent](); + return this.textContent = this.textContent === 'play' ? 'pause' : 'play'; + }); + file.videoControls.push($.tn('\u00A0'), play); + } + return $.add(file.text, file.videoControls); + }, error: function() { var URL, post, src, timeoutID; post = Get.postFromNode(this); @@ -12816,7 +12889,7 @@ Redirect = { init: function() { - var archive, archives, boardID, boards, data, files, id, name, o, record, software, type, _i, _j, _len, _len1, _ref, _ref1, _ref2; + var archive, archives, boardID, boards, data, files, id, name, o, record, software, type, _i, _j, _len, _len1, _ref, _ref1; o = { thread: {}, post: {}, @@ -12825,13 +12898,9 @@ archives = {}; _ref = Redirect.archives; for (_i = 0, _len = _ref.length; _i < _len; _i++) { - _ref1 = _ref[_i], name = _ref1.name, boards = _ref1.boards, files = _ref1.files, data = _ref1.data; - archives[name] = { - boards: boards, - files: files, - data: data - }; - software = data.software; + data = _ref[_i]; + name = data.name, boards = data.boards, files = data.files, software = data.software; + archives[name] = data; for (_j = 0, _len1 = boards.length; _j < _len1; _j++) { boardID = boards[_j]; if (!(boardID in o.thread)) { @@ -12845,9 +12914,9 @@ } } } - _ref2 = Conf['selectedArchives']; - for (boardID in _ref2) { - record = _ref2[boardID]; + _ref1 = Conf['selectedArchives']; + for (boardID in _ref1) { + record = _ref1[boardID]; for (type in record) { id = record[type]; if (!((archive = archives[id]))) { @@ -12857,151 +12926,12 @@ if (__indexOf.call(boards, boardID) < 0) { continue; } - o[type][boardID] = archive.data; + o[type][boardID] = archive; } } return Redirect.data = o; }, - archives: [ - { - name: "Foolz", - boards: ["a", "biz", "co", "diy", "gd", "jp", "m", "sci", "sp", "tg", "tv", "v", "vg", "vp", "vr", "wsg"], - files: ["a", "biz", "diy", "gd", "jp", "m", "sci", "tg", "vg", "vp", "vr", "wsg"], - data: { - domain: "archive.foolz.us", - http: false, - https: true, - software: "foolfuuka" - } - }, { - name: "NSFW Foolz", - boards: ["u"], - files: ["u"], - data: { - domain: "nsfw.foolz.us", - http: false, - https: true, - software: "foolfuuka" - } - }, { - name: "The Dark Cave", - boards: ["c", "int", "out", "po"], - files: ["c", "po"], - data: { - domain: "archive.thedarkcave.org", - http: true, - https: true, - software: "foolfuuka" - } - }, { - name: "4plebs", - boards: ["adv", "hr", "o", "pol", "s4s", "tg", "trv", "tv", "x"], - files: ["adv", "hr", "o", "pol", "s4s", "tg", "trv", "tv", "x"], - data: { - domain: "archive.4plebs.org", - http: true, - https: true, - software: "foolfuuka" - } - }, { - name: "4plebs Flash Archive", - boards: ["f"], - files: ["f"], - data: { - domain: "flash.4plebs.org", - http: true, - https: true, - software: "foolfuuka" - } - }, { - name: "Nyafuu", - boards: ["c", "e", "w", "wg"], - files: ["c", "e", "w", "wg"], - data: { - domain: "archive.nyafuu.org", - http: true, - https: true, - software: "foolfuuka" - } - }, { - name: "Love is Over", - boards: ["d", "i"], - files: ["d", "i"], - data: { - domain: "loveisover.me", - http: true, - https: true, - software: "foolfuuka" - } - }, { - name: "Rebecca Black Tech", - boards: ["cgl", "g", "mu", "w"], - files: ["cgl", "g", "mu", "w"], - data: { - domain: "archive.rebeccablacktech.com", - http: true, - https: true, - software: "fuuka" - } - }, { - name: "Heinessen", - boards: ["an", "fit", "k", "mlp", "r9k", "toy"], - files: ["an", "fit", "k", "r9k", "toy"], - data: { - domain: "archive.heinessen.com", - http: true, - software: "fuuka" - } - }, { - name: "warosu", - boards: ["3", "biz", "cgl", "ck", "diy", "fa", "g", "ic", "jp", "lit", "sci", "tg", "vr"], - files: ["3", "biz", "cgl", "ck", "diy", "fa", "ic", "jp", "lit", "sci", "tg", "vr"], - data: { - domain: "fuuka.warosu.org", - https: true, - software: "fuuka" - } - }, { - name: "fgts", - boards: ["cm", "hm", "r", "soc", "y"], - files: ["cm", "hm", "r", "soc", "y"], - data: { - domain: "fgst.eu", - http: true, - https: true, - software: "foolfuuka" - } - }, { - name: "maware", - boards: ["t"], - files: ["t"], - data: { - domain: "archive.mawa.re", - http: true, - software: "foolfuuka" - } - }, { - name: "InstallGentoo", - boards: ["g", "t"], - files: ["g", "t"], - data: { - domain: "chan.installgentoo.com", - http: true, - software: "foolfuuka" - } - }, { - name: "Foolz Beta", - boards: ["a", "biz", "co", "d", "diy", "gd", "jp", "m", "mlp", "s4s", "sci", "sp", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"], - files: ["a", "biz", "d", "diy", "gd", "jp", "m", "s4s", "sci", "tg", "u", "vg", "vp", "vr", "wsg"], - data: { - domain: "beta.foolz.us", - http: true, - https: true, - withCredentials: true, - software: "foolfuuka" - } - } - ], + archives: [{"uid":0,"name":"Foolz","domain":"archive.foolz.us","http":true,"https":true,"software":"foolfuuka","boards":["a","biz","co","diy","gd","jp","m","sci","sp","tg","tv","v","vg","vp","vr","wsg"],"files":["a","biz","gd","diy","jp","m","sci","tg","vg","vp","vr","wsg"]},{"uid":1,"name":"NSFW Foolz","domain":"nsfw.foolz.us","http":true,"https":true,"software":"foolfuuka","boards":["u"],"files":["u"]},{"uid":2,"name":"The Dark Cave","domain":"archive.thedarkcave.org","http":true,"https":true,"software":"foolfuuka","boards":["c","int","out","po"],"files":["c","po"]},{"uid":3,"name":"4plebs Archive","domain":"archive.4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["adv","hr","o","pol","s4s","tg","trv","tv","x"],"files":["adv","hr","o","pol","s4s","tg","trv","tv","x"]},{"uid":18,"name":"4plebs Flash Archive","domain":"flash.4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["f"],"files":["f"]},{"uid":4,"name":"Nyafuu","domain":"archive.nyafuu.org","http":true,"https":true,"software":"foolfuuka","boards":["c","e","w","wg"],"files":["c","e","w","wg"]},{"uid":5,"name":"Love is Over","domain":"loveisover.me","http":true,"https":true,"software":"foolfuuka","boards":["d","i"],"files":["d","i"]},{"uid":8,"name":"Rebecca Black Tech","domain":"rbt.asia","http":true,"https":true,"software":"fuuka","boards":["cgl","g","mu","w"],"files":["cgl","g","mu","w"]},{"uid":9,"name":"Heinessen","domain":"archive.heinessen.com","http":true,"https":false,"software":"fuuka","boards":["an","fit","k","mlp","r9k","toy"],"files":["an","fit","k","r9k","toy"]},{"uid":10,"name":"warosu","domain":"fuuka.warosu.org","http":false,"https":true,"software":"fuuka","boards":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"],"files":["3","biz","cgl","ck","diy","fa","ic","jp","lit","sci","tg","vr"]},{"uid":15,"name":"fgts","domain":"fgts.eu","http":true,"https":true,"software":"foolfuuka","boards":["cm","hm","r","soc","y"],"files":["cm","hm","r","soc","y"]},{"uid":16,"name":"maware","domain":"archive.mawa.re","http":true,"https":false,"software":"foolfuuka","boards":["t"],"files":["t"]},{"uid":17,"name":"installgentoo.com","domain":"chan.installgentoo.com","http":true,"https":false,"software":"foolfuuka","boards":["g","t"],"files":["g","t"]},{"uid":13,"name":"Foolz Beta","domain":"beta.foolz.us","http":true,"https":true,"withCredentials":true,"software":"foolfuuka","boards":["a","biz","co","d","diy","gd","jp","m","s4s","sci","sp","tg","tv","u","v","vg","vp","vr","wsg"],"files":["a","biz","d","diy","gd","jp","m","s4s","sci","tg","u","vg","vp","vr","wsg"]}], to: function(dest, data) { var archive; archive = (dest === 'search' || dest === 'board' ? Redirect.data.thread : Redirect.data[dest])[data.boardID]; @@ -13057,6 +12987,137 @@ } }; + [ + { + "uid": 0, + "name": "Foolz", + "domain": "archive.foolz.us", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["a", "biz", "co", "diy", "gd", "jp", "m", "sci", "sp", "tg", "tv", "v", "vg", "vp", "vr", "wsg"], + "files": ["a", "biz", "gd", "diy", "jp", "m", "sci", "tg", "vg", "vp", "vr", "wsg"] + }, { + "uid": 1, + "name": "NSFW Foolz", + "domain": "nsfw.foolz.us", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["u"], + "files": ["u"] + }, { + "uid": 2, + "name": "The Dark Cave", + "domain": "archive.thedarkcave.org", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["c", "int", "out", "po"], + "files": ["c", "po"] + }, { + "uid": 3, + "name": "4plebs Archive", + "domain": "archive.4plebs.org", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["adv", "hr", "o", "pol", "s4s", "tg", "trv", "tv", "x"], + "files": ["adv", "hr", "o", "pol", "s4s", "tg", "trv", "tv", "x"] + }, { + "uid": 18, + "name": "4plebs Flash Archive", + "domain": "flash.4plebs.org", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["f"], + "files": ["f"] + }, { + "uid": 4, + "name": "Nyafuu", + "domain": "archive.nyafuu.org", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["c", "e", "w", "wg"], + "files": ["c", "e", "w", "wg"] + }, { + "uid": 5, + "name": "Love is Over", + "domain": "loveisover.me", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["d", "i"], + "files": ["d", "i"] + }, { + "uid": 8, + "name": "Rebecca Black Tech", + "domain": "rbt.asia", + "http": true, + "https": true, + "software": "fuuka", + "boards": ["cgl", "g", "mu", "w"], + "files": ["cgl", "g", "mu", "w"] + }, { + "uid": 9, + "name": "Heinessen", + "domain": "archive.heinessen.com", + "http": true, + "https": false, + "software": "fuuka", + "boards": ["an", "fit", "k", "mlp", "r9k", "toy"], + "files": ["an", "fit", "k", "r9k", "toy"] + }, { + "uid": 10, + "name": "warosu", + "domain": "fuuka.warosu.org", + "http": false, + "https": true, + "software": "fuuka", + "boards": ["3", "biz", "cgl", "ck", "diy", "fa", "g", "ic", "jp", "lit", "sci", "tg", "vr"], + "files": ["3", "biz", "cgl", "ck", "diy", "fa", "ic", "jp", "lit", "sci", "tg", "vr"] + }, { + "uid": 15, + "name": "fgts", + "domain": "fgts.eu", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["cm", "hm", "r", "soc", "y"], + "files": ["cm", "hm", "r", "soc", "y"] + }, { + "uid": 16, + "name": "maware", + "domain": "archive.mawa.re", + "http": true, + "https": false, + "software": "foolfuuka", + "boards": ["t"], + "files": ["t"] + }, { + "uid": 17, + "name": "installgentoo.com", + "domain": "chan.installgentoo.com", + "http": true, + "https": false, + "software": "foolfuuka", + "boards": ["g", "t"], + "files": ["g", "t"] + }, { + "uid": 13, + "name": "Foolz Beta", + "domain": "beta.foolz.us", + "http": true, + "https": true, + "withCredentials": true, + "software": "foolfuuka", + "boards": ["a", "biz", "co", "d", "diy", "gd", "jp", "m", "s4s", "sci", "sp", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"], + "files": ["a", "biz", "d", "diy", "gd", "jp", "m", "s4s", "sci", "tg", "u", "vg", "vp", "vr", "wsg"] + } + ]; + Banner = { init: function() { return $.asap((function() { @@ -15194,7 +15255,7 @@ return FileInfo.convertUnit(this.file.sizeInBytes, 'MB'); }, r: function() { - if (this.file.isImage) { + if (this.file.isImage || this.file.isVideo) { return this.file.dimensions; } else { return 'PDF'; @@ -16875,7 +16936,7 @@ return $.on(ta, 'change', $.cb.value); }, advanced: function(section) { - var archBoards, boardID, boardOptions, boardSelect, boards, data, event, files, input, inputs, item, items, name, o, row, rows, ta, table, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2, _ref3, _ref4; + var archBoards, boardID, boardOptions, boardSelect, boards, event, files, input, inputs, item, items, name, o, row, rows, software, ta, table, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2, _ref3, _ref4; section.innerHTML = "
Archiver
404 Redirect is disabled.
Thread redirectionPost fetchingFile redirection
Disabled selections indicate that only one archive is available for that board and redirection type.
Custom Board Navigation
New lines will be converted into spaces.

In the following examples for /g/, g can be changed to a different board ID (a, b, etc...), the current board (current), or the Twitter link (@).
Board link: g
Title link: g-title
Board link (Replace with title when on that board): g-replace
Full text link: g-full
Custom text link: g-text:\"Install Gentoo\"
External link: external-text:\"Google\",\"http://www.google.com\"
Index mode: g-mode:\"type\" where type is paged, all threads or catalog
Index sort: g-sort:\"type\" where type is bump order, last reply, creation date, reply count or file countCombinations are possible: g-text:\"VIP Catalog\"-mode:\"catalog\"-sort:\"creation date\"
Full board list toggle: toggle-all

[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h-mode:\"catalog\"-sort:\"file count\"] [t-text:\"Piracy\"]
will give you
[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
if you are on /g/.
Time Formatting is disabled.
:
Supported format specifiers:
Day: %a, %A, %d, %e
Month: %m, %b, %B
Year: %y, %Y
Hour: %k, %H, %l, %I, %p, %P
Minute: %M
Second: %S
Quote Backlinks formatting is disabled.
:
File Info Formatting is disabled.
:
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
Spoiler indicator: %p
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
Resolution: %r (Displays 'PDF' for PDF files)
Quick Reply Personas

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

Unread Favicon is disabled.
Emoji is disabled.
Sage Icon:
Thread Updater is disabled.
Interval:
Custom CSS
"; items = {}; inputs = {}; @@ -16913,7 +16974,7 @@ archBoards = {}; _ref1 = Redirect.archives; for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - _ref2 = _ref1[_j], name = _ref2.name, boards = _ref2.boards, files = _ref2.files, data = _ref2.data; + _ref2 = _ref1[_j], name = _ref2.name, boards = _ref2.boards, files = _ref2.files, software = _ref2.software; for (_k = 0, _len2 = boards.length; _k < _len2; _k++) { boardID = boards[_k]; o = archBoards[boardID] || (archBoards[boardID] = { @@ -16922,7 +16983,7 @@ file: [] }); o.thread.push(name); - if (data.software === 'foolfuuka') { + if (software === 'foolfuuka') { o.post.push(name); } if (__indexOf.call(files, boardID) >= 0) { @@ -16961,7 +17022,7 @@ return $("tbody > ." + this.value, table).hidden = false; }); $.get('selectedArchives', Conf['selectedArchives'], function(_arg) { - var option, selectedArchives, type; + var data, option, selectedArchives, type; selectedArchives = _arg.selectedArchives; for (boardID in selectedArchives) { data = selectedArchives[boardID]; diff --git a/builds/crx.crx b/builds/crx.crx index d6f999455..a1f50ec4d 100644 Binary files a/builds/crx.crx and b/builds/crx.crx differ diff --git a/builds/crx/manifest.json b/builds/crx/manifest.json index 8c3520653..3d459f011 100644 --- a/builds/crx/manifest.json +++ b/builds/crx/manifest.json @@ -15,7 +15,7 @@ "run_at": "document_start" }], "homepage_url": "http://zixaphir.github.com/appchan-x/", - "update_url": "https://github.com/zixaphir/appchan-x/raw/master/builds/updates.xml", + "update_url": "updates.xml", "minimum_chrome_version": "32", "permissions": [ "storage", diff --git a/builds/crx/script.js b/builds/crx/script.js index d02d8d174..049a1b670 100644 --- a/builds/crx/script.js +++ b/builds/crx/script.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript /* -* appchan x - Version 2.9.11 - 2014-04-03 +* appchan x - Version 2.9.11 - 2014-04-04 * * Licensed under the MIT license. * https://github.com/zixaphir/appchan-x/blob/master/LICENSE @@ -145,8 +145,8 @@ 'Filtered Backlinks': [true, 'When enabled, shows backlinks to filtered posts with a line-through decoration. Otherwise, hides the backlinks.'], 'Stubs': [true, 'Show stubs of hidden threads / replies.'] }, - 'Images': { - 'Image Expansion': [true, 'Expand images.'], + 'Images and Videos': { + 'Image Expansion': [true, 'Expand images / videos.'], 'Image Hover': [true, 'Show full image on mouseover.'], 'Image Hover in Catalog': [false, 'Show a floating expanded image on hover in the catalog.'], 'Gallery': [true, 'Adds a simple and cute image gallery.'], @@ -157,7 +157,9 @@ 'Replace JPG': [false, 'Replace jpgs.'], 'Image Prefetching': [false, 'Preload images'], 'Fappe Tyme': [false, 'Hide posts without images when toggled. *hint* *hint*'], - 'Werk Tyme': [false, 'Hide all post images when toggled.'] + 'Werk Tyme': [false, 'Hide all post images when toggled.'], + 'Autoplay': [true, 'Videos begin playing immediately when opened inline.'], + 'Show Controls': [true, 'Show native seek and volume controls on videos. Contract videos when dragged to the left.'] }, 'Menu': { 'Menu': [true, 'Add a drop-down menu to posts.'], @@ -3448,7 +3450,9 @@ this.file.thumbURL = that.isArchived ? thumb.src : "" + location.protocol + "//t.4cdn.org/" + this.board + "/thumb/" + (this.file.URL.match(/(\d+)\./)[1]) + "s.jpg"; this.file.name = (nameNode = $('span', fileText)) ? nameNode.title || nameNode.textContent : fileText.title; this.file.name = this.file.name.replace(/%22/g, '"'); - if (this.file.isImage = /(jpg|png|gif)$/i.test(this.file.name)) { + this.file.isImage = /(jpg|png|gif)$/i.test(this.file.name); + this.file.isVideo = /webm$/i.test(this.file.name); + if (this.file.isImage || this.file.isVideo) { return this.file.dimensions = fileText.textContent.match(/\d+x\d+/)[0]; } }; @@ -10687,8 +10691,8 @@ }); }, node: function() { - var thumb, _ref; - if (!((_ref = this.file) != null ? _ref.isImage : void 0)) { + var thumb, _ref, _ref1; + if (!(((_ref = this.file) != null ? _ref.isImage : void 0) || ((_ref1 = this.file) != null ? _ref1.isVideo : void 0))) { return; } thumb = this.file.thumb; @@ -10728,7 +10732,7 @@ for (_i = 0, _len = _ref.length; _i < _len; _i++) { post = _ref[_i]; file = post.file; - if (!(file && file.isImage && doc.contains(post.nodes.root))) { + if (!(file && (file.isImage || file.isVideo) && doc.contains(post.nodes.root))) { return; } if (ImageExpand.on && (!Conf['Expand spoilers'] && file.isSpoiler || Conf['Expand from here'] && Header.getTopOf(file.thumb) < 0)) { @@ -10777,36 +10781,51 @@ return ImageExpand.contract(post); }, contract: function(post) { + var _ref, _ref1; + if (post.file.isVideo) { + if ((_ref = post.file.fullImage) != null) { + _ref.pause(); + } + } $.rmClass(post.nodes.root, 'expanded-image'); $.rmClass(post.file.thumb, 'expanding'); - return post.file.isExpanded = false; + post.file.isExpanded = false; + if ((_ref1 = post.file.videoControls) != null) { + _ref1.map($.rm); + } + return delete post.file.videoControls; }, expand: function(post, src) { - var img, thumb; - thumb = post.file.thumb; - if (post.file.isExpanded || $.hasClass(thumb, 'expanding')) { + var img, isVideo, naturalHeight, thumb, _ref; + _ref = post.file, thumb = _ref.thumb, isVideo = _ref.isVideo; + if (post.isHidden || post.file.isExpanded || $.hasClass(thumb, 'expanding')) { return; } $.addClass(thumb, 'expanding'); + naturalHeight = isVideo ? 'videoHeight' : 'naturalHeight'; if (post.file.fullImage) { $.asap((function() { - return post.file.fullImage.naturalHeight; + return post.file.fullImage[naturalHeight]; }), function() { return ImageExpand.completeExpand(post); }); return; } - post.file.fullImage = img = $.el('img', { + post.file.fullImage = img = $.el((isVideo ? 'video' : 'img'), { className: 'full-image', src: src || post.file.URL }); + if (isVideo) { + img.loop = true; + img.controls = Conf['Show Controls']; + } $.on(img, 'error', ImageExpand.error); $.asap((function() { - return post.file.fullImage.naturalHeight; + return post.file.fullImage[naturalHeight]; }), function() { return ImageExpand.completeExpand(post); }); - return $.after(thumb, img); + return $.after((img.controls ? thumb.parentNode : thumb), img); }, completeExpand: function(post) { var bottom, thumb; @@ -10815,6 +10834,9 @@ return; } post.file.isExpanded = true; + if (post.file.isVideo) { + ImageExpand.setupVideo(post); + } if (!post.nodes.root.parentNode) { $.addClass(post.nodes.root, 'expanded-image'); $.rmClass(post.file.thumb, 'expanding'); @@ -10830,6 +10852,57 @@ return window.scrollBy(0, post.nodes.root.getBoundingClientRect().bottom - bottom); }); }, + setupVideo: function(post) { + var contract, file, play, video; + file = post.file; + video = file.fullImage; + file.videoControls = []; + video.muted = true; + if (video.controls) { + contract = $.el('a', { + textContent: 'contract', + href: 'javascript:;', + title: 'You can also contract the video by dragging it to the left.' + }); + $.on(contract, 'click', function(e) { + return ImageExpand.contract(post); + }); + file.videoControls.push($.tn('\u00A0'), contract); + file.mousedown = false; + $.on(video, 'mousedown', function(e) { + if (e.button === 0) { + return file.mousedown = true; + } + }); + $.on(video, 'mouseup', function(e) { + if (e.button === 0) { + return file.mousedown = false; + } + }); + $.on(video, 'mouseover', function(e) { + return file.mousedown = false; + }); + $.on(video, 'mouseout', function(e) { + if (file.mousedown && e.clientX <= video.getBoundingClientRect().left) { + return ImageExpand.contract(post); + } + }); + } + if (Conf['Autoplay']) { + video.play(); + } else if (!video.controls) { + play = $.el('a', { + textContent: 'play', + href: 'javascript:;' + }); + $.on(play, 'click', function(e) { + video[this.textContent](); + return this.textContent = this.textContent === 'play' ? 'pause' : 'play'; + }); + file.videoControls.push($.tn('\u00A0'), play); + } + return $.add(file.text, file.videoControls); + }, error: function() { var URL, post, src, timeoutID; post = Get.postFromNode(this); @@ -12831,7 +12904,7 @@ Redirect = { init: function() { - var archive, archives, boardID, boards, data, files, id, name, o, record, software, type, _i, _j, _len, _len1, _ref, _ref1, _ref2; + var archive, archives, boardID, boards, data, files, id, name, o, record, software, type, _i, _j, _len, _len1, _ref, _ref1; o = { thread: {}, post: {}, @@ -12840,13 +12913,9 @@ archives = {}; _ref = Redirect.archives; for (_i = 0, _len = _ref.length; _i < _len; _i++) { - _ref1 = _ref[_i], name = _ref1.name, boards = _ref1.boards, files = _ref1.files, data = _ref1.data; - archives[name] = { - boards: boards, - files: files, - data: data - }; - software = data.software; + data = _ref[_i]; + name = data.name, boards = data.boards, files = data.files, software = data.software; + archives[name] = data; for (_j = 0, _len1 = boards.length; _j < _len1; _j++) { boardID = boards[_j]; if (!(boardID in o.thread)) { @@ -12860,9 +12929,9 @@ } } } - _ref2 = Conf['selectedArchives']; - for (boardID in _ref2) { - record = _ref2[boardID]; + _ref1 = Conf['selectedArchives']; + for (boardID in _ref1) { + record = _ref1[boardID]; for (type in record) { id = record[type]; if (!((archive = archives[id]))) { @@ -12872,151 +12941,12 @@ if (__indexOf.call(boards, boardID) < 0) { continue; } - o[type][boardID] = archive.data; + o[type][boardID] = archive; } } return Redirect.data = o; }, - archives: [ - { - name: "Foolz", - boards: ["a", "biz", "co", "diy", "gd", "jp", "m", "sci", "sp", "tg", "tv", "v", "vg", "vp", "vr", "wsg"], - files: ["a", "biz", "diy", "gd", "jp", "m", "sci", "tg", "vg", "vp", "vr", "wsg"], - data: { - domain: "archive.foolz.us", - http: false, - https: true, - software: "foolfuuka" - } - }, { - name: "NSFW Foolz", - boards: ["u"], - files: ["u"], - data: { - domain: "nsfw.foolz.us", - http: false, - https: true, - software: "foolfuuka" - } - }, { - name: "The Dark Cave", - boards: ["c", "int", "out", "po"], - files: ["c", "po"], - data: { - domain: "archive.thedarkcave.org", - http: true, - https: true, - software: "foolfuuka" - } - }, { - name: "4plebs", - boards: ["adv", "hr", "o", "pol", "s4s", "tg", "trv", "tv", "x"], - files: ["adv", "hr", "o", "pol", "s4s", "tg", "trv", "tv", "x"], - data: { - domain: "archive.4plebs.org", - http: true, - https: true, - software: "foolfuuka" - } - }, { - name: "4plebs Flash Archive", - boards: ["f"], - files: ["f"], - data: { - domain: "flash.4plebs.org", - http: true, - https: true, - software: "foolfuuka" - } - }, { - name: "Nyafuu", - boards: ["c", "e", "w", "wg"], - files: ["c", "e", "w", "wg"], - data: { - domain: "archive.nyafuu.org", - http: true, - https: true, - software: "foolfuuka" - } - }, { - name: "Love is Over", - boards: ["d", "i"], - files: ["d", "i"], - data: { - domain: "loveisover.me", - http: true, - https: true, - software: "foolfuuka" - } - }, { - name: "Rebecca Black Tech", - boards: ["cgl", "g", "mu", "w"], - files: ["cgl", "g", "mu", "w"], - data: { - domain: "archive.rebeccablacktech.com", - http: true, - https: true, - software: "fuuka" - } - }, { - name: "Heinessen", - boards: ["an", "fit", "k", "mlp", "r9k", "toy"], - files: ["an", "fit", "k", "r9k", "toy"], - data: { - domain: "archive.heinessen.com", - http: true, - software: "fuuka" - } - }, { - name: "warosu", - boards: ["3", "biz", "cgl", "ck", "diy", "fa", "g", "ic", "jp", "lit", "sci", "tg", "vr"], - files: ["3", "biz", "cgl", "ck", "diy", "fa", "ic", "jp", "lit", "sci", "tg", "vr"], - data: { - domain: "fuuka.warosu.org", - https: true, - software: "fuuka" - } - }, { - name: "fgts", - boards: ["cm", "hm", "r", "soc", "y"], - files: ["cm", "hm", "r", "soc", "y"], - data: { - domain: "fgst.eu", - http: true, - https: true, - software: "foolfuuka" - } - }, { - name: "maware", - boards: ["t"], - files: ["t"], - data: { - domain: "archive.mawa.re", - http: true, - software: "foolfuuka" - } - }, { - name: "InstallGentoo", - boards: ["g", "t"], - files: ["g", "t"], - data: { - domain: "chan.installgentoo.com", - http: true, - software: "foolfuuka" - } - }, { - name: "Foolz Beta", - boards: ["a", "biz", "co", "d", "diy", "gd", "jp", "m", "mlp", "s4s", "sci", "sp", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"], - files: ["a", "biz", "d", "diy", "gd", "jp", "m", "s4s", "sci", "tg", "u", "vg", "vp", "vr", "wsg"], - data: { - domain: "beta.foolz.us", - http: true, - https: true, - withCredentials: true, - software: "foolfuuka" - } - } - ], + archives: [{"uid":0,"name":"Foolz","domain":"archive.foolz.us","http":true,"https":true,"software":"foolfuuka","boards":["a","biz","co","diy","gd","jp","m","sci","sp","tg","tv","v","vg","vp","vr","wsg"],"files":["a","biz","gd","diy","jp","m","sci","tg","vg","vp","vr","wsg"]},{"uid":1,"name":"NSFW Foolz","domain":"nsfw.foolz.us","http":true,"https":true,"software":"foolfuuka","boards":["u"],"files":["u"]},{"uid":2,"name":"The Dark Cave","domain":"archive.thedarkcave.org","http":true,"https":true,"software":"foolfuuka","boards":["c","int","out","po"],"files":["c","po"]},{"uid":3,"name":"4plebs Archive","domain":"archive.4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["adv","hr","o","pol","s4s","tg","trv","tv","x"],"files":["adv","hr","o","pol","s4s","tg","trv","tv","x"]},{"uid":18,"name":"4plebs Flash Archive","domain":"flash.4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["f"],"files":["f"]},{"uid":4,"name":"Nyafuu","domain":"archive.nyafuu.org","http":true,"https":true,"software":"foolfuuka","boards":["c","e","w","wg"],"files":["c","e","w","wg"]},{"uid":5,"name":"Love is Over","domain":"loveisover.me","http":true,"https":true,"software":"foolfuuka","boards":["d","i"],"files":["d","i"]},{"uid":8,"name":"Rebecca Black Tech","domain":"rbt.asia","http":true,"https":true,"software":"fuuka","boards":["cgl","g","mu","w"],"files":["cgl","g","mu","w"]},{"uid":9,"name":"Heinessen","domain":"archive.heinessen.com","http":true,"https":false,"software":"fuuka","boards":["an","fit","k","mlp","r9k","toy"],"files":["an","fit","k","r9k","toy"]},{"uid":10,"name":"warosu","domain":"fuuka.warosu.org","http":false,"https":true,"software":"fuuka","boards":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"],"files":["3","biz","cgl","ck","diy","fa","ic","jp","lit","sci","tg","vr"]},{"uid":15,"name":"fgts","domain":"fgts.eu","http":true,"https":true,"software":"foolfuuka","boards":["cm","hm","r","soc","y"],"files":["cm","hm","r","soc","y"]},{"uid":16,"name":"maware","domain":"archive.mawa.re","http":true,"https":false,"software":"foolfuuka","boards":["t"],"files":["t"]},{"uid":17,"name":"installgentoo.com","domain":"chan.installgentoo.com","http":true,"https":false,"software":"foolfuuka","boards":["g","t"],"files":["g","t"]},{"uid":13,"name":"Foolz Beta","domain":"beta.foolz.us","http":true,"https":true,"withCredentials":true,"software":"foolfuuka","boards":["a","biz","co","d","diy","gd","jp","m","s4s","sci","sp","tg","tv","u","v","vg","vp","vr","wsg"],"files":["a","biz","d","diy","gd","jp","m","s4s","sci","tg","u","vg","vp","vr","wsg"]}], to: function(dest, data) { var archive; archive = (dest === 'search' || dest === 'board' ? Redirect.data.thread : Redirect.data[dest])[data.boardID]; @@ -13072,6 +13002,137 @@ } }; + [ + { + "uid": 0, + "name": "Foolz", + "domain": "archive.foolz.us", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["a", "biz", "co", "diy", "gd", "jp", "m", "sci", "sp", "tg", "tv", "v", "vg", "vp", "vr", "wsg"], + "files": ["a", "biz", "gd", "diy", "jp", "m", "sci", "tg", "vg", "vp", "vr", "wsg"] + }, { + "uid": 1, + "name": "NSFW Foolz", + "domain": "nsfw.foolz.us", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["u"], + "files": ["u"] + }, { + "uid": 2, + "name": "The Dark Cave", + "domain": "archive.thedarkcave.org", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["c", "int", "out", "po"], + "files": ["c", "po"] + }, { + "uid": 3, + "name": "4plebs Archive", + "domain": "archive.4plebs.org", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["adv", "hr", "o", "pol", "s4s", "tg", "trv", "tv", "x"], + "files": ["adv", "hr", "o", "pol", "s4s", "tg", "trv", "tv", "x"] + }, { + "uid": 18, + "name": "4plebs Flash Archive", + "domain": "flash.4plebs.org", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["f"], + "files": ["f"] + }, { + "uid": 4, + "name": "Nyafuu", + "domain": "archive.nyafuu.org", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["c", "e", "w", "wg"], + "files": ["c", "e", "w", "wg"] + }, { + "uid": 5, + "name": "Love is Over", + "domain": "loveisover.me", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["d", "i"], + "files": ["d", "i"] + }, { + "uid": 8, + "name": "Rebecca Black Tech", + "domain": "rbt.asia", + "http": true, + "https": true, + "software": "fuuka", + "boards": ["cgl", "g", "mu", "w"], + "files": ["cgl", "g", "mu", "w"] + }, { + "uid": 9, + "name": "Heinessen", + "domain": "archive.heinessen.com", + "http": true, + "https": false, + "software": "fuuka", + "boards": ["an", "fit", "k", "mlp", "r9k", "toy"], + "files": ["an", "fit", "k", "r9k", "toy"] + }, { + "uid": 10, + "name": "warosu", + "domain": "fuuka.warosu.org", + "http": false, + "https": true, + "software": "fuuka", + "boards": ["3", "biz", "cgl", "ck", "diy", "fa", "g", "ic", "jp", "lit", "sci", "tg", "vr"], + "files": ["3", "biz", "cgl", "ck", "diy", "fa", "ic", "jp", "lit", "sci", "tg", "vr"] + }, { + "uid": 15, + "name": "fgts", + "domain": "fgts.eu", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["cm", "hm", "r", "soc", "y"], + "files": ["cm", "hm", "r", "soc", "y"] + }, { + "uid": 16, + "name": "maware", + "domain": "archive.mawa.re", + "http": true, + "https": false, + "software": "foolfuuka", + "boards": ["t"], + "files": ["t"] + }, { + "uid": 17, + "name": "installgentoo.com", + "domain": "chan.installgentoo.com", + "http": true, + "https": false, + "software": "foolfuuka", + "boards": ["g", "t"], + "files": ["g", "t"] + }, { + "uid": 13, + "name": "Foolz Beta", + "domain": "beta.foolz.us", + "http": true, + "https": true, + "withCredentials": true, + "software": "foolfuuka", + "boards": ["a", "biz", "co", "d", "diy", "gd", "jp", "m", "s4s", "sci", "sp", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"], + "files": ["a", "biz", "d", "diy", "gd", "jp", "m", "s4s", "sci", "tg", "u", "vg", "vp", "vr", "wsg"] + } + ]; + Banner = { init: function() { return $.asap((function() { @@ -15215,7 +15276,7 @@ return FileInfo.convertUnit(this.file.sizeInBytes, 'MB'); }, r: function() { - if (this.file.isImage) { + if (this.file.isImage || this.file.isVideo) { return this.file.dimensions; } else { return 'PDF'; @@ -16899,7 +16960,7 @@ return $.on(ta, 'change', $.cb.value); }, advanced: function(section) { - var archBoards, boardID, boardOptions, boardSelect, boards, data, event, files, input, inputs, item, items, name, o, row, rows, ta, table, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2, _ref3, _ref4; + var archBoards, boardID, boardOptions, boardSelect, boards, event, files, input, inputs, item, items, name, o, row, rows, software, ta, table, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2, _ref3, _ref4; section.innerHTML = "
Archiver
404 Redirect is disabled.
Thread redirectionPost fetchingFile redirection
Disabled selections indicate that only one archive is available for that board and redirection type.
Custom Board Navigation
New lines will be converted into spaces.

In the following examples for /g/, g can be changed to a different board ID (a, b, etc...), the current board (current), or the Twitter link (@).
Board link: g
Title link: g-title
Board link (Replace with title when on that board): g-replace
Full text link: g-full
Custom text link: g-text:\"Install Gentoo\"
External link: external-text:\"Google\",\"http://www.google.com\"
Index mode: g-mode:\"type\" where type is paged, all threads or catalog
Index sort: g-sort:\"type\" where type is bump order, last reply, creation date, reply count or file countCombinations are possible: g-text:\"VIP Catalog\"-mode:\"catalog\"-sort:\"creation date\"
Full board list toggle: toggle-all

[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h-mode:\"catalog\"-sort:\"file count\"] [t-text:\"Piracy\"]
will give you
[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
if you are on /g/.
Time Formatting is disabled.
:
Supported format specifiers:
Day: %a, %A, %d, %e
Month: %m, %b, %B
Year: %y, %Y
Hour: %k, %H, %l, %I, %p, %P
Minute: %M
Second: %S
Quote Backlinks formatting is disabled.
:
File Info Formatting is disabled.
:
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
Spoiler indicator: %p
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
Resolution: %r (Displays 'PDF' for PDF files)
Quick Reply Personas

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

Unread Favicon is disabled.
Emoji is disabled.
Sage Icon:
Thread Updater is disabled.
Interval:
Custom CSS
"; items = {}; inputs = {}; @@ -16937,7 +16998,7 @@ archBoards = {}; _ref1 = Redirect.archives; for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - _ref2 = _ref1[_j], name = _ref2.name, boards = _ref2.boards, files = _ref2.files, data = _ref2.data; + _ref2 = _ref1[_j], name = _ref2.name, boards = _ref2.boards, files = _ref2.files, software = _ref2.software; for (_k = 0, _len2 = boards.length; _k < _len2; _k++) { boardID = boards[_k]; o = archBoards[boardID] || (archBoards[boardID] = { @@ -16946,7 +17007,7 @@ file: [] }); o.thread.push(name); - if (data.software === 'foolfuuka') { + if (software === 'foolfuuka') { o.post.push(name); } if (__indexOf.call(files, boardID) >= 0) { @@ -16985,7 +17046,7 @@ return $("tbody > ." + this.value, table).hidden = false; }); $.get('selectedArchives', Conf['selectedArchives'], function(_arg) { - var option, selectedArchives, type; + var data, option, selectedArchives, type; selectedArchives = _arg.selectedArchives; for (boardID in selectedArchives) { data = selectedArchives[boardID]; diff --git a/builds/updates.xml b/builds/updates.xml deleted file mode 100644 index 4a5267d97..000000000 --- a/builds/updates.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/Archive/Redirect.coffee b/src/Archive/Redirect.coffee index 87f548010..126ebc815 100755 --- a/src/Archive/Redirect.coffee +++ b/src/Archive/Redirect.coffee @@ -6,9 +6,9 @@ Redirect = file: {} archives = {} - for {name, boards, files, data} in Redirect.archives - archives[name] = {boards, files, data} - {software} = data + for data in Redirect.archives + {name, boards, files, software} = data + archives[name] = data for boardID in boards o.thread[boardID] = data unless boardID of o.thread o.post[boardID] = data unless boardID of o.post or software isnt 'foolfuuka' @@ -18,134 +18,11 @@ Redirect = for type, id of record when (archive = archives[id]) boards = if type is 'file' then archive.files else archive.boards continue unless boardID in boards - o[type][boardID] = archive.data + o[type][boardID] = archive Redirect.data = o - archives: [ - name: "Foolz" - boards: ["a", "biz", "co", "diy", "gd", "jp", "m", "sci", "sp", "tg", "tv", "v", "vg", "vp", "vr", "wsg"] - files: ["a", "biz", "diy", "gd", "jp", "m", "sci", "tg", "vg", "vp", "vr", "wsg"] - data: - domain: "archive.foolz.us" - http: false - https: true - software: "foolfuuka" - , - name: "NSFW Foolz" - boards: ["u"] - files: ["u"] - data: - domain: "nsfw.foolz.us" - http: false - https: true - software: "foolfuuka" - , - name: "The Dark Cave" - boards: ["c", "int", "out", "po"] - files: ["c", "po"] - data: - domain: "archive.thedarkcave.org" - http: true - https: true - software: "foolfuuka" - , - name: "4plebs" - boards: ["adv", "hr", "o", "pol", "s4s", "tg", "trv", "tv", "x"] - files: ["adv", "hr", "o", "pol", "s4s", "tg", "trv", "tv", "x"] - data: - domain: "archive.4plebs.org" - http: true - https: true - software: "foolfuuka" - , - name: "4plebs Flash Archive", - boards: ["f"] - files: ["f"] - data: - domain: "flash.4plebs.org" - http: true - https: true - software: "foolfuuka" - , - name: "Nyafuu" - boards: ["c", "e", "w", "wg"] - files: ["c", "e", "w", "wg"] - data: - domain: "archive.nyafuu.org" - http: true - https: true - software: "foolfuuka" - , - name: "Love is Over" - boards: ["d", "i"] - files: ["d", "i"] - data: - domain: "loveisover.me" - http: true - https: true - software: "foolfuuka" - , - name: "Rebecca Black Tech" - boards: ["cgl", "g", "mu", "w"] - files: ["cgl", "g", "mu", "w"] - data: - domain: "archive.rebeccablacktech.com" - http: true - https: true - software: "fuuka" - , - name: "Heinessen" - boards: ["an", "fit", "k", "mlp", "r9k", "toy"] - files: ["an", "fit", "k", "r9k", "toy"] - data: - domain: "archive.heinessen.com" - http: true - software: "fuuka" - , - name: "warosu" - boards: ["3", "biz", "cgl", "ck", "diy", "fa", "g", "ic", "jp", "lit", "sci", "tg", "vr"] - files: ["3", "biz", "cgl", "ck", "diy", "fa", "ic", "jp", "lit", "sci", "tg", "vr"] - data: - domain: "fuuka.warosu.org" - https: true - software: "fuuka" - , - name: "fgts" - boards: ["cm", "hm", "r", "soc", "y"] - files: ["cm", "hm", "r", "soc", "y"] - data: - domain: "fgst.eu" - http: true - https: true - software: "foolfuuka" - , - name: "maware" - boards: ["t"] - files: ["t"] - data: - domain: "archive.mawa.re" - http: true - software: "foolfuuka" - , - name: "InstallGentoo" - boards: ["g", "t"] - files: ["g", "t"] - data: - domain: "chan.installgentoo.com" - http: true - software: "foolfuuka" - , - name: "Foolz Beta" - boards: ["a", "biz", "co", "d", "diy", "gd", "jp", "m", "mlp", "s4s", "sci", "sp", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"], - files: ["a", "biz", "d", "diy", "gd", "jp", "m", "s4s", "sci", "tg", "u", "vg", "vp", "vr", "wsg"] - data: - domain: "beta.foolz.us" - http: true - https: true - withCredentials: true - software: "foolfuuka" - ] + archives: `<%= JSON.stringify(grunt.file.readJSON('src/Archive/archives.json')) %>` to: (dest, data) -> archive = (if dest in ['search', 'board'] then Redirect.data.thread else Redirect.data[dest])[data.boardID] diff --git a/src/Archive/archives.json b/src/Archive/archives.json new file mode 100644 index 000000000..8918ef6c0 --- /dev/null +++ b/src/Archive/archives.json @@ -0,0 +1,128 @@ +[{ + "uid": 0, + "name": "Foolz", + "domain": "archive.foolz.us", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["a", "biz", "co", "diy", "gd", "jp", "m", "sci", "sp", "tg", "tv", "v", "vg", "vp", "vr", "wsg"], + "files": ["a", "biz", "gd", "diy", "jp", "m", "sci", "tg", "vg", "vp", "vr", "wsg"] +}, { + "uid": 1, + "name": "NSFW Foolz", + "domain": "nsfw.foolz.us", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["u"], + "files": ["u"] +}, { + "uid": 2, + "name": "The Dark Cave", + "domain": "archive.thedarkcave.org", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["c", "int", "out", "po"], + "files": ["c", "po"] +}, { + "uid": 3, + "name": "4plebs Archive", + "domain": "archive.4plebs.org", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["adv", "hr", "o", "pol", "s4s", "tg", "trv", "tv", "x"], + "files": ["adv", "hr", "o", "pol", "s4s", "tg", "trv", "tv", "x"] +}, { + "uid": 18, + "name": "4plebs Flash Archive", + "domain": "flash.4plebs.org", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["f"], + "files": ["f"] +}, { + "uid": 4, + "name": "Nyafuu", + "domain": "archive.nyafuu.org", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["c", "e", "w", "wg"], + "files": ["c", "e", "w", "wg"] +}, { + "uid": 5, + "name": "Love is Over", + "domain": "loveisover.me", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["d", "i"], + "files": ["d", "i"] +}, { + "uid": 8, + "name": "Rebecca Black Tech", + "domain": "rbt.asia", + "http": true, + "https": true, + "software": "fuuka", + "boards": ["cgl", "g", "mu", "w"], + "files": ["cgl", "g", "mu", "w"] +}, { + "uid": 9, + "name": "Heinessen", + "domain": "archive.heinessen.com", + "http": true, + "https": false, + "software": "fuuka", + "boards": ["an", "fit", "k", "mlp", "r9k", "toy"], + "files": ["an", "fit", "k", "r9k", "toy"] +}, { + "uid": 10, + "name": "warosu", + "domain": "fuuka.warosu.org", + "http": false, + "https": true, + "software": "fuuka", + "boards": ["3", "biz", "cgl", "ck", "diy", "fa", "g", "ic", "jp", "lit", "sci", "tg", "vr"], + "files": ["3", "biz", "cgl", "ck", "diy", "fa", "ic", "jp", "lit", "sci", "tg", "vr"] +}, { + "uid": 15, + "name": "fgts", + "domain": "fgts.eu", + "http": true, + "https": true, + "software": "foolfuuka", + "boards": ["cm", "hm", "r", "soc", "y"], + "files": ["cm", "hm", "r", "soc", "y"] +}, { + "uid": 16, + "name": "maware", + "domain": "archive.mawa.re", + "http": true, + "https": false, + "software": "foolfuuka", + "boards": ["t"], + "files": ["t"] +}, { + "uid": 17, + "name": "installgentoo.com", + "domain": "chan.installgentoo.com", + "http": true, + "https": false, + "software": "foolfuuka", + "boards": ["g", "t"], + "files": ["g", "t"] +}, { + "uid": 13, + "name": "Foolz Beta", + "domain": "beta.foolz.us", + "http": true, + "https": true, + "withCredentials": true, + "software": "foolfuuka", + "boards": ["a", "biz", "co", "d", "diy", "gd", "jp", "m", "s4s", "sci", "sp", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"], + "files": ["a", "biz", "d", "diy", "gd", "jp", "m", "s4s", "sci", "tg", "u", "vg", "vp", "vr", "wsg"] +}] diff --git a/src/General/Config.coffee b/src/General/Config.coffee index 24fd6fc03..183960169 100644 --- a/src/General/Config.coffee +++ b/src/General/Config.coffee @@ -114,10 +114,10 @@ Config = 'Show stubs of hidden threads / replies.' ] - 'Images': + 'Images and Videos': 'Image Expansion': [ true - 'Expand images.' + 'Expand images / videos.' ] 'Image Hover': [ true @@ -163,6 +163,14 @@ Config = false 'Hide all post images when toggled.' ] + 'Autoplay': [ + true + 'Videos begin playing immediately when opened inline.' + ] + 'Show Controls': [ + true + 'Show native seek and volume controls on videos. Contract videos when dragged to the left.' + ] 'Menu': 'Menu': [ diff --git a/src/General/Settings.coffee b/src/General/Settings.coffee index a1e807754..255800c19 100755 --- a/src/General/Settings.coffee +++ b/src/General/Settings.coffee @@ -265,14 +265,14 @@ Settings = $.on $.id('apply-css'), 'click', Settings.usercss archBoards = {} - for {name, boards, files, data} in Redirect.archives + for {name, boards, files, software} in Redirect.archives for boardID in boards o = archBoards[boardID] or= thread: [] post: [] file: [] o.thread.push name - o.post.push name if data.software is 'foolfuuka' + o.post.push name if software is 'foolfuuka' o.file.push name if boardID in files rows = [] diff --git a/src/General/css/style.css b/src/General/css/style.css index 3ecf23e61..28bc9791d 100755 --- a/src/General/css/style.css +++ b/src/General/css/style.css @@ -825,7 +825,7 @@ span.hide-announcement { .fileText:hover .fntrunc, .fileText:not(:hover) .fnfull, .expanded-image > .post > .file > .fileThumb > img[data-md5], -:not(.expanded-image) > .post > .file > .fileThumb > .full-image { +:not(.expanded-image) > .post > .file .full-image { display: none; } .expanding { diff --git a/src/General/lib/post.class b/src/General/lib/post.class index db0fc5e7f..974f30bcc 100755 --- a/src/General/lib/post.class +++ b/src/General/lib/post.class @@ -147,7 +147,9 @@ class Post # http://www.whatwg.org/specs/web-apps/current-work/#multipart-form-data @file.name = @file.name.replace /%22/g, '"' <% } %> - if @file.isImage = /(jpg|png|gif)$/i.test @file.name + @file.isImage = /(jpg|png|gif)$/i.test @file.name + @file.isVideo = /webm$/i.test @file.name + if @file.isImage or @file.isVideo @file.dimensions = fileText.textContent.match(/\d+x\d+/)[0] cleanup: (root, post) -> diff --git a/src/General/meta/manifest.json b/src/General/meta/manifest.json index b9401d1e3..6d3d4caf6 100755 --- a/src/General/meta/manifest.json +++ b/src/General/meta/manifest.json @@ -15,7 +15,7 @@ "run_at": "document_start" }], "homepage_url": "<%= meta.page %>", - "update_url": "<%= meta.repo %>raw/master/builds/updates.xml", + "update_url": "<%= meta.downloads %>updates.xml", "minimum_chrome_version": "<%= meta.min.chrome %>", "permissions": [ "storage", diff --git a/src/General/meta/metadata.js b/src/General/meta/metadata.js index ef89cbc37..76b0a611d 100755 --- a/src/General/meta/metadata.js +++ b/src/General/meta/metadata.js @@ -18,7 +18,7 @@ // @grant GM_openInTab // @grant GM_xmlhttpRequest // @run-at document-start -// @updateURL <%= meta.repo %>raw/stable/builds/<%= meta.files.metajs %> -// @downloadURL <%= meta.repo %>raw/stable/builds/<%= meta.files.userjs %> +// @updateURL <%= meta.downloads %><%= meta.files.metajs %> +// @downloadURL <%= meta.downloads %><%= meta.files.userjs %> // @icon data:image/png;base64,<%= grunt.file.read('src/General/img/icon48.png', {encoding: 'base64'}) %> // ==/UserScript== diff --git a/src/General/meta/updates.xml b/src/General/meta/updates.xml index 4b3f6b662..0f5d3104b 100644 --- a/src/General/meta/updates.xml +++ b/src/General/meta/updates.xml @@ -1,7 +1,7 @@ - - + + diff --git a/src/Images/ImageExpand.coffee b/src/Images/ImageExpand.coffee index 6e1aaa077..f54345a0d 100644 --- a/src/Images/ImageExpand.coffee +++ b/src/Images/ImageExpand.coffee @@ -17,7 +17,7 @@ ImageExpand = cb: @node node: -> - return unless @file?.isImage + return unless @file?.isImage or @file?.isVideo {thumb} = @file $.on thumb.parentNode, 'click', ImageExpand.cb.toggle if @isClone and $.hasClass thumb, 'expanding' @@ -36,7 +36,6 @@ ImageExpand = toggleAll: -> $.event 'CloseMenu' - if ImageExpand.on = $.hasClass ImageExpand.EAI, 'expand-all-shortcut' ImageExpand.EAI.className = 'contract-all-shortcut a-icon' ImageExpand.EAI.title = 'Contract All Images' @@ -49,7 +48,7 @@ ImageExpand = g.posts.forEach (post) -> for post in [post].concat post.clones {file} = post - return unless file and file.isImage and doc.contains post.nodes.root + return unless file and (file.isImage or file.isVideo) and doc.contains post.nodes.root if ImageExpand.on and (!Conf['Expand spoilers'] and file.isSpoiler or Conf['Expand from here'] and Header.getTopOf(file.thumb) < 0) @@ -91,32 +90,40 @@ ImageExpand = ImageExpand.contract post contract: (post) -> + post.file.fullImage?.pause() if post.file.isVideo $.rmClass post.nodes.root, 'expanded-image' $.rmClass post.file.thumb, 'expanding' post.file.isExpanded = false + post.file.videoControls?.map($.rm) + delete post.file.videoControls expand: (post, src) -> # Do not expand images of hidden/filtered replies, or already expanded pictures. - {thumb} = post.file - return if post.file.isExpanded or $.hasClass thumb, 'expanding' + {thumb, isVideo} = post.file + return if post.isHidden or post.file.isExpanded or $.hasClass thumb, 'expanding' $.addClass thumb, 'expanding' + naturalHeight = if isVideo then 'videoHeight' else 'naturalHeight' if post.file.fullImage # Expand already-loaded/ing picture. - $.asap (-> post.file.fullImage.naturalHeight), -> + $.asap (-> post.file.fullImage[naturalHeight]), -> ImageExpand.completeExpand post return - post.file.fullImage = img = $.el 'img', + post.file.fullImage = img = $.el (if isVideo then 'video' else 'img'), className: 'full-image' src: src or post.file.URL + if isVideo + img.loop = true + img.controls = Conf['Show Controls'] $.on img, 'error', ImageExpand.error - $.asap (-> post.file.fullImage.naturalHeight), -> + $.asap (-> post.file.fullImage[naturalHeight]), -> ImageExpand.completeExpand post - $.after thumb, img + $.after (if img.controls then thumb.parentNode else thumb), img completeExpand: (post) -> {thumb} = post.file return unless $.hasClass thumb, 'expanding' # contracted before the image loaded post.file.isExpanded = true + ImageExpand.setupVideo post if post.file.isVideo unless post.nodes.root.parentNode # Image might start/finish loading before the post is inserted. # Don't scroll when it's expanded in a QP for example. @@ -130,6 +137,39 @@ ImageExpand = return unless bottom <= 0 window.scrollBy 0, post.nodes.root.getBoundingClientRect().bottom - bottom + setupVideo: (post) -> + {file} = post + video = file.fullImage + file.videoControls = [] + video.muted = true + if video.controls + # contract link in file info + contract = $.el 'a', + textContent: 'contract' + href: 'javascript:;' + title: 'You can also contract the video by dragging it to the left.' + $.on contract, 'click', (e) -> ImageExpand.contract post + file.videoControls.push $.tn('\u00A0'), contract + # drag left to contract + file.mousedown = false + $.on video, 'mousedown', (e) -> file.mousedown = true if e.button is 0 + $.on video, 'mouseup', (e) -> file.mousedown = false if e.button is 0 + $.on video, 'mouseover', (e) -> file.mousedown = false + $.on video, 'mouseout', (e) -> + if file.mousedown and e.clientX <= video.getBoundingClientRect().left + ImageExpand.contract post + if Conf['Autoplay'] + video.play() + else unless video.controls + play = $.el 'a', + textContent: 'play' + href: 'javascript:;' + $.on play, 'click', (e) -> + video[@textContent]() + @textContent = if @textContent is 'play' then 'pause' else 'play' + file.videoControls.push $.tn('\u00A0'), play + $.add file.text, file.videoControls + error: -> post = Get.postFromNode @ $.rm @ diff --git a/src/Miscellaneous/FileInfo.coffee b/src/Miscellaneous/FileInfo.coffee index 0534b2c33..ee324e59e 100755 --- a/src/Miscellaneous/FileInfo.coffee +++ b/src/Miscellaneous/FileInfo.coffee @@ -47,4 +47,4 @@ FileInfo = B: -> FileInfo.convertUnit @file.sizeInBytes, 'B' K: -> FileInfo.convertUnit @file.sizeInBytes, 'KB' M: -> FileInfo.convertUnit @file.sizeInBytes, 'MB' - r: -> if @file.isImage then @file.dimensions else 'PDF' + r: -> if @file.isImage or @file.isVideo then @file.dimensions else 'PDF'