diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fa7e0637..dd32efe03 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ Sometimes the changelog has notes (not comprehensive) acknowledging people's work. This does not mean the changes are their fault, only that their code was used. All changes to the script are chosen by and the fault of the maintainer (ccd0). +### v1.11.14 + +**v1.11.14.0** *(2015-10-25)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.14.0/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.14.0/builds/4chan-X-noupdate.crx "Chromium version")] +- Based on v1.11.13.9. +- Allow editing Quick Reply images in the oekaki painter on all boards. + ### v1.11.13 **v1.11.13.9** *(2015-10-24)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.13.9/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.13.9/builds/4chan-X-noupdate.crx "Chromium version")] diff --git a/builds/4chan-X-beta.crx b/builds/4chan-X-beta.crx index 8ffded605..38e38b036 100644 Binary files a/builds/4chan-X-beta.crx and b/builds/4chan-X-beta.crx differ diff --git a/builds/4chan-X-beta.meta.js b/builds/4chan-X-beta.meta.js index 8118125f4..0b3138e12 100644 --- a/builds/4chan-X-beta.meta.js +++ b/builds/4chan-X-beta.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X beta -// @version 1.11.13.9 +// @version 1.11.14.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X diff --git a/builds/4chan-X-beta.user.js b/builds/4chan-X-beta.user.js index 3d2d0311f..8dad60121 100644 --- a/builds/4chan-X-beta.user.js +++ b/builds/4chan-X-beta.user.js @@ -1,7 +1,7 @@ // Generated by CoffeeScript // ==UserScript== // @name 4chan X beta -// @version 1.11.13.9 +// @version 1.11.14.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -413,7 +413,7 @@ doc = d.documentElement; g = { - VERSION: '1.11.13.9', + VERSION: '1.11.14.0', NAMESPACE: '4chan X.', boards: {} }; @@ -902,6 +902,10 @@ return $.rm(script); }; + $.global = function(fn) { + return $.globalEval("(" + fn + ")();"); + }; + $.bytesToString = function(size) { var unit; unit = 0; @@ -6863,6 +6867,15 @@ 'swf': 'application/vnd.adobe.flash.movie', 'webm': 'video/webm' }, + extensionFromType: { + 'image/jpeg': 'jpg', + 'image/png': 'png', + 'image/gif': 'gif', + 'application/pdf': 'pdf', + 'application/vnd.adobe.flash.movie': 'swf', + 'application/x-shockwave-flash': 'swf', + 'video/webm': 'webm' + }, init: function() { var sc, version; if (!Conf['Quick Reply']) { @@ -7099,9 +7112,6 @@ QR.setCustomCooldown(enabled); return $.set('customCooldownEnabled', enabled); }, - oekakiDraw: function() { - return $.globalEval('Tegaki.open({\n onDone: function() {\n Tegaki.flatten().toBlob(function (blob) {\n var detail = {file: blob, name: \'tegaki.png\'};\n var event = new CustomEvent(\'QRSetFile\', {bubbles: true, detail: detail});\n document.dispatchEvent(event);\n });\n },\n onCancel: function() {},\n width: +document.querySelector(\'#qr [name=oekaki-width]\').value,\n height: +document.querySelector(\'#qr [name=oekaki-height]\').value\n});'); - }, error: function(err, focusOverride) { var el, notice, notif; QR.open(); @@ -7425,7 +7435,7 @@ var dialog, event, i, items, m, match_max, match_min, name, node, nodes, ref, rules, save, scriptData, setNode; QR.nodes = nodes = { el: dialog = UI.dialog('qr', 'top: 50px; right: 0px;', { - innerHTML: "
" + innerHTML: " " }) }; setNode = function(name, query) { @@ -7462,6 +7472,7 @@ setNode('customCooldown', '#custom-cooldown-button'); setNode('flashTag', '[name=filetag]'); setNode('drawButton', '#qr-draw-button'); + setNode('editButton', '#qr-edit-button'); rules = $('ul.rules').textContent.trim(); match_min = rules.match(/.+smaller than (\d+)x(\d+).+/); match_max = rules.match(/.+greater than (\d+)x(\d+).+/); @@ -7534,7 +7545,8 @@ $.on(nodes.texButton, 'mousedown', QR.texPreviewShow); $.on(nodes.texButton, 'mouseup', QR.texPreviewHide); $.on(nodes.customCooldown, 'click', QR.toggleCustomCooldown); - $.on(nodes.drawButton, 'click', QR.oekakiDraw); + $.on(nodes.drawButton, 'click', QR.oekaki.draw); + $.on(nodes.editButton, 'click', QR.oekaki.edit); window.addEventListener('focus', QR.focus, true); window.addEventListener('blur', QR.focus, true); $.on(d, 'click', QR.focus); @@ -8913,6 +8925,115 @@ } }; + QR.oekaki = { + load: function(cb) { + var n, onload, script, style; + if ($('script[src^="//s.4cdn.org/js/painter"]', d.head)) { + return cb(); + } else { + style = $.el('link', { + rel: 'stylesheet', + href: "//s.4cdn.org/css/painter." + (Date.now()) + ".css" + }); + script = $.el('script', { + src: "//s.4cdn.org/js/painter.min." + (Date.now()) + ".js" + }); + n = 0; + onload = function() { + if (++n === 2) { + return cb(); + } + }; + $.on(style, 'load', onload); + $.on(script, 'load', onload); + return $.add(d.head, [style, script]); + } + }, + draw: function() { + return $.global(function() { + var Tegaki; + Tegaki = window.Tegaki; + return Tegaki.open({ + onDone: function() { + return Tegaki.flatten().toBlob(function(file) { + return document.dispatchEvent(new CustomEvent('QRSetFile', { + bubbles: true, + detail: { + file: file, + name: 'tegaki.png' + } + })); + }); + }, + onCancel: function() {}, + width: +document.querySelector('#qr [name=oekaki-width]').value, + height: +document.querySelector('#qr [name=oekaki-height]').value + }); + }); + }, + edit: function() { + return QR.oekaki.load(function() { + return $.global(function() { + var Tegaki, cb, error, name; + Tegaki = window.Tegaki; + name = document.getElementById('qr-filename').value.replace(/\.\w+$/, '') + '.png'; + error = function(content) { + return document.dispatchEvent(new CustomEvent('CreateNotification', { + bubbles: true, + detail: { + type: 'warning', + content: content, + lifetime: 20 + } + })); + }; + cb = function(e) { + var img; + document.removeEventListener('QRFile', cb, false); + if (!e.detail) { + return error('No file to edit.'); + } + if (!/^image\//.test(e.detail.type)) { + return error('Not an image.'); + } + img = new Image(); + img.onerror = function() { + return error('Could not open image.'); + }; + img.onload = function() { + if (Tegaki.bg) { + Tegaki.destroy(); + } + Tegaki.open({ + onDone: function() { + return Tegaki.flatten().toBlob(function(file) { + return document.dispatchEvent(new CustomEvent('QRSetFile', { + bubbles: true, + detail: { + file: file, + name: name + } + })); + }); + }, + onCancel: function() {}, + width: img.naturalWidth, + height: img.naturalHeight, + bgColor: 'transparent' + }); + return Tegaki.activeCtx.drawImage(img, 0, 0); + }; + return img.src = URL.createObjectURL(e.detail); + }; + document.addEventListener('QRFile', cb, false); + return document.dispatchEvent(new CustomEvent('QRGetFile', { + bubbles: true + })); + }); + }); + } + }; + QR.persona = { pwd: '', always: {}, @@ -9430,7 +9551,7 @@ _Class.prototype.saveFilename = function() { this.file.newName = (this.filename || '').replace(/[\/\\]/g, '-'); if (!QR.validExtension.test(this.filename)) { - return this.file.newName += '.jpg'; + return this.file.newName += "." + (QR.extensionFromType[this.file.type] || 'jpg'); } }; @@ -19468,6 +19589,7 @@ "}\n" + "#qr:not(.has-spoiler) #qr-spoiler-label,\n" + "#file-n-submit:not(.has-file) #qr-spoiler-label,\n" + +"#file-n-submit:not(.has-file) #qr-edit-button,\n" + ".has-file #paste-area,\n" + ".has-file #url-button,\n" + "#file-n-submit:not(.custom-cooldown) #custom-cooldown-button {\n" + diff --git a/builds/4chan-X-noupdate.crx b/builds/4chan-X-noupdate.crx index 59322bd60..5d8e92ef0 100644 Binary files a/builds/4chan-X-noupdate.crx and b/builds/4chan-X-noupdate.crx differ diff --git a/builds/4chan-X-noupdate.user.js b/builds/4chan-X-noupdate.user.js index 25b1b4c02..a45d7b00a 100644 --- a/builds/4chan-X-noupdate.user.js +++ b/builds/4chan-X-noupdate.user.js @@ -1,7 +1,7 @@ // Generated by CoffeeScript // ==UserScript== // @name 4chan X -// @version 1.11.13.9 +// @version 1.11.14.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -413,7 +413,7 @@ doc = d.documentElement; g = { - VERSION: '1.11.13.9', + VERSION: '1.11.14.0', NAMESPACE: '4chan X.', boards: {} }; @@ -902,6 +902,10 @@ return $.rm(script); }; + $.global = function(fn) { + return $.globalEval("(" + fn + ")();"); + }; + $.bytesToString = function(size) { var unit; unit = 0; @@ -6863,6 +6867,15 @@ 'swf': 'application/vnd.adobe.flash.movie', 'webm': 'video/webm' }, + extensionFromType: { + 'image/jpeg': 'jpg', + 'image/png': 'png', + 'image/gif': 'gif', + 'application/pdf': 'pdf', + 'application/vnd.adobe.flash.movie': 'swf', + 'application/x-shockwave-flash': 'swf', + 'video/webm': 'webm' + }, init: function() { var sc, version; if (!Conf['Quick Reply']) { @@ -7099,9 +7112,6 @@ QR.setCustomCooldown(enabled); return $.set('customCooldownEnabled', enabled); }, - oekakiDraw: function() { - return $.globalEval('Tegaki.open({\n onDone: function() {\n Tegaki.flatten().toBlob(function (blob) {\n var detail = {file: blob, name: \'tegaki.png\'};\n var event = new CustomEvent(\'QRSetFile\', {bubbles: true, detail: detail});\n document.dispatchEvent(event);\n });\n },\n onCancel: function() {},\n width: +document.querySelector(\'#qr [name=oekaki-width]\').value,\n height: +document.querySelector(\'#qr [name=oekaki-height]\').value\n});'); - }, error: function(err, focusOverride) { var el, notice, notif; QR.open(); @@ -7425,7 +7435,7 @@ var dialog, event, i, items, m, match_max, match_min, name, node, nodes, ref, rules, save, scriptData, setNode; QR.nodes = nodes = { el: dialog = UI.dialog('qr', 'top: 50px; right: 0px;', { - innerHTML: " " + innerHTML: " " }) }; setNode = function(name, query) { @@ -7462,6 +7472,7 @@ setNode('customCooldown', '#custom-cooldown-button'); setNode('flashTag', '[name=filetag]'); setNode('drawButton', '#qr-draw-button'); + setNode('editButton', '#qr-edit-button'); rules = $('ul.rules').textContent.trim(); match_min = rules.match(/.+smaller than (\d+)x(\d+).+/); match_max = rules.match(/.+greater than (\d+)x(\d+).+/); @@ -7534,7 +7545,8 @@ $.on(nodes.texButton, 'mousedown', QR.texPreviewShow); $.on(nodes.texButton, 'mouseup', QR.texPreviewHide); $.on(nodes.customCooldown, 'click', QR.toggleCustomCooldown); - $.on(nodes.drawButton, 'click', QR.oekakiDraw); + $.on(nodes.drawButton, 'click', QR.oekaki.draw); + $.on(nodes.editButton, 'click', QR.oekaki.edit); window.addEventListener('focus', QR.focus, true); window.addEventListener('blur', QR.focus, true); $.on(d, 'click', QR.focus); @@ -8913,6 +8925,115 @@ } }; + QR.oekaki = { + load: function(cb) { + var n, onload, script, style; + if ($('script[src^="//s.4cdn.org/js/painter"]', d.head)) { + return cb(); + } else { + style = $.el('link', { + rel: 'stylesheet', + href: "//s.4cdn.org/css/painter." + (Date.now()) + ".css" + }); + script = $.el('script', { + src: "//s.4cdn.org/js/painter.min." + (Date.now()) + ".js" + }); + n = 0; + onload = function() { + if (++n === 2) { + return cb(); + } + }; + $.on(style, 'load', onload); + $.on(script, 'load', onload); + return $.add(d.head, [style, script]); + } + }, + draw: function() { + return $.global(function() { + var Tegaki; + Tegaki = window.Tegaki; + return Tegaki.open({ + onDone: function() { + return Tegaki.flatten().toBlob(function(file) { + return document.dispatchEvent(new CustomEvent('QRSetFile', { + bubbles: true, + detail: { + file: file, + name: 'tegaki.png' + } + })); + }); + }, + onCancel: function() {}, + width: +document.querySelector('#qr [name=oekaki-width]').value, + height: +document.querySelector('#qr [name=oekaki-height]').value + }); + }); + }, + edit: function() { + return QR.oekaki.load(function() { + return $.global(function() { + var Tegaki, cb, error, name; + Tegaki = window.Tegaki; + name = document.getElementById('qr-filename').value.replace(/\.\w+$/, '') + '.png'; + error = function(content) { + return document.dispatchEvent(new CustomEvent('CreateNotification', { + bubbles: true, + detail: { + type: 'warning', + content: content, + lifetime: 20 + } + })); + }; + cb = function(e) { + var img; + document.removeEventListener('QRFile', cb, false); + if (!e.detail) { + return error('No file to edit.'); + } + if (!/^image\//.test(e.detail.type)) { + return error('Not an image.'); + } + img = new Image(); + img.onerror = function() { + return error('Could not open image.'); + }; + img.onload = function() { + if (Tegaki.bg) { + Tegaki.destroy(); + } + Tegaki.open({ + onDone: function() { + return Tegaki.flatten().toBlob(function(file) { + return document.dispatchEvent(new CustomEvent('QRSetFile', { + bubbles: true, + detail: { + file: file, + name: name + } + })); + }); + }, + onCancel: function() {}, + width: img.naturalWidth, + height: img.naturalHeight, + bgColor: 'transparent' + }); + return Tegaki.activeCtx.drawImage(img, 0, 0); + }; + return img.src = URL.createObjectURL(e.detail); + }; + document.addEventListener('QRFile', cb, false); + return document.dispatchEvent(new CustomEvent('QRGetFile', { + bubbles: true + })); + }); + }); + } + }; + QR.persona = { pwd: '', always: {}, @@ -9430,7 +9551,7 @@ _Class.prototype.saveFilename = function() { this.file.newName = (this.filename || '').replace(/[\/\\]/g, '-'); if (!QR.validExtension.test(this.filename)) { - return this.file.newName += '.jpg'; + return this.file.newName += "." + (QR.extensionFromType[this.file.type] || 'jpg'); } }; @@ -19468,6 +19589,7 @@ "}\n" + "#qr:not(.has-spoiler) #qr-spoiler-label,\n" + "#file-n-submit:not(.has-file) #qr-spoiler-label,\n" + +"#file-n-submit:not(.has-file) #qr-edit-button,\n" + ".has-file #paste-area,\n" + ".has-file #url-button,\n" + "#file-n-submit:not(.custom-cooldown) #custom-cooldown-button {\n" + diff --git a/builds/4chan-X.crx b/builds/4chan-X.crx index 27c139404..353d0c6cc 100644 Binary files a/builds/4chan-X.crx and b/builds/4chan-X.crx differ diff --git a/builds/4chan-X.meta.js b/builds/4chan-X.meta.js index 221b88147..00bea6ea1 100644 --- a/builds/4chan-X.meta.js +++ b/builds/4chan-X.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.11.13.9 +// @version 1.11.14.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 656032626..30efccbbf 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -1,7 +1,7 @@ // Generated by CoffeeScript // ==UserScript== // @name 4chan X -// @version 1.11.13.9 +// @version 1.11.14.0 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -413,7 +413,7 @@ doc = d.documentElement; g = { - VERSION: '1.11.13.9', + VERSION: '1.11.14.0', NAMESPACE: '4chan X.', boards: {} }; @@ -902,6 +902,10 @@ return $.rm(script); }; + $.global = function(fn) { + return $.globalEval("(" + fn + ")();"); + }; + $.bytesToString = function(size) { var unit; unit = 0; @@ -6863,6 +6867,15 @@ 'swf': 'application/vnd.adobe.flash.movie', 'webm': 'video/webm' }, + extensionFromType: { + 'image/jpeg': 'jpg', + 'image/png': 'png', + 'image/gif': 'gif', + 'application/pdf': 'pdf', + 'application/vnd.adobe.flash.movie': 'swf', + 'application/x-shockwave-flash': 'swf', + 'video/webm': 'webm' + }, init: function() { var sc, version; if (!Conf['Quick Reply']) { @@ -7099,9 +7112,6 @@ QR.setCustomCooldown(enabled); return $.set('customCooldownEnabled', enabled); }, - oekakiDraw: function() { - return $.globalEval('Tegaki.open({\n onDone: function() {\n Tegaki.flatten().toBlob(function (blob) {\n var detail = {file: blob, name: \'tegaki.png\'};\n var event = new CustomEvent(\'QRSetFile\', {bubbles: true, detail: detail});\n document.dispatchEvent(event);\n });\n },\n onCancel: function() {},\n width: +document.querySelector(\'#qr [name=oekaki-width]\').value,\n height: +document.querySelector(\'#qr [name=oekaki-height]\').value\n});'); - }, error: function(err, focusOverride) { var el, notice, notif; QR.open(); @@ -7425,7 +7435,7 @@ var dialog, event, i, items, m, match_max, match_min, name, node, nodes, ref, rules, save, scriptData, setNode; QR.nodes = nodes = { el: dialog = UI.dialog('qr', 'top: 50px; right: 0px;', { - innerHTML: " " + innerHTML: " " }) }; setNode = function(name, query) { @@ -7462,6 +7472,7 @@ setNode('customCooldown', '#custom-cooldown-button'); setNode('flashTag', '[name=filetag]'); setNode('drawButton', '#qr-draw-button'); + setNode('editButton', '#qr-edit-button'); rules = $('ul.rules').textContent.trim(); match_min = rules.match(/.+smaller than (\d+)x(\d+).+/); match_max = rules.match(/.+greater than (\d+)x(\d+).+/); @@ -7534,7 +7545,8 @@ $.on(nodes.texButton, 'mousedown', QR.texPreviewShow); $.on(nodes.texButton, 'mouseup', QR.texPreviewHide); $.on(nodes.customCooldown, 'click', QR.toggleCustomCooldown); - $.on(nodes.drawButton, 'click', QR.oekakiDraw); + $.on(nodes.drawButton, 'click', QR.oekaki.draw); + $.on(nodes.editButton, 'click', QR.oekaki.edit); window.addEventListener('focus', QR.focus, true); window.addEventListener('blur', QR.focus, true); $.on(d, 'click', QR.focus); @@ -8913,6 +8925,115 @@ } }; + QR.oekaki = { + load: function(cb) { + var n, onload, script, style; + if ($('script[src^="//s.4cdn.org/js/painter"]', d.head)) { + return cb(); + } else { + style = $.el('link', { + rel: 'stylesheet', + href: "//s.4cdn.org/css/painter." + (Date.now()) + ".css" + }); + script = $.el('script', { + src: "//s.4cdn.org/js/painter.min." + (Date.now()) + ".js" + }); + n = 0; + onload = function() { + if (++n === 2) { + return cb(); + } + }; + $.on(style, 'load', onload); + $.on(script, 'load', onload); + return $.add(d.head, [style, script]); + } + }, + draw: function() { + return $.global(function() { + var Tegaki; + Tegaki = window.Tegaki; + return Tegaki.open({ + onDone: function() { + return Tegaki.flatten().toBlob(function(file) { + return document.dispatchEvent(new CustomEvent('QRSetFile', { + bubbles: true, + detail: { + file: file, + name: 'tegaki.png' + } + })); + }); + }, + onCancel: function() {}, + width: +document.querySelector('#qr [name=oekaki-width]').value, + height: +document.querySelector('#qr [name=oekaki-height]').value + }); + }); + }, + edit: function() { + return QR.oekaki.load(function() { + return $.global(function() { + var Tegaki, cb, error, name; + Tegaki = window.Tegaki; + name = document.getElementById('qr-filename').value.replace(/\.\w+$/, '') + '.png'; + error = function(content) { + return document.dispatchEvent(new CustomEvent('CreateNotification', { + bubbles: true, + detail: { + type: 'warning', + content: content, + lifetime: 20 + } + })); + }; + cb = function(e) { + var img; + document.removeEventListener('QRFile', cb, false); + if (!e.detail) { + return error('No file to edit.'); + } + if (!/^image\//.test(e.detail.type)) { + return error('Not an image.'); + } + img = new Image(); + img.onerror = function() { + return error('Could not open image.'); + }; + img.onload = function() { + if (Tegaki.bg) { + Tegaki.destroy(); + } + Tegaki.open({ + onDone: function() { + return Tegaki.flatten().toBlob(function(file) { + return document.dispatchEvent(new CustomEvent('QRSetFile', { + bubbles: true, + detail: { + file: file, + name: name + } + })); + }); + }, + onCancel: function() {}, + width: img.naturalWidth, + height: img.naturalHeight, + bgColor: 'transparent' + }); + return Tegaki.activeCtx.drawImage(img, 0, 0); + }; + return img.src = URL.createObjectURL(e.detail); + }; + document.addEventListener('QRFile', cb, false); + return document.dispatchEvent(new CustomEvent('QRGetFile', { + bubbles: true + })); + }); + }); + } + }; + QR.persona = { pwd: '', always: {}, @@ -9430,7 +9551,7 @@ _Class.prototype.saveFilename = function() { this.file.newName = (this.filename || '').replace(/[\/\\]/g, '-'); if (!QR.validExtension.test(this.filename)) { - return this.file.newName += '.jpg'; + return this.file.newName += "." + (QR.extensionFromType[this.file.type] || 'jpg'); } }; @@ -19468,6 +19589,7 @@ "}\n" + "#qr:not(.has-spoiler) #qr-spoiler-label,\n" + "#file-n-submit:not(.has-file) #qr-spoiler-label,\n" + +"#file-n-submit:not(.has-file) #qr-edit-button,\n" + ".has-file #paste-area,\n" + ".has-file #url-button,\n" + "#file-n-submit:not(.custom-cooldown) #custom-cooldown-button {\n" + diff --git a/builds/4chan-X.zip b/builds/4chan-X.zip index f323c764a..80bcb6d88 100644 Binary files a/builds/4chan-X.zip and b/builds/4chan-X.zip differ diff --git a/builds/updates-beta.xml b/builds/updates-beta.xml index d24c13610..28dd65c8c 100644 --- a/builds/updates-beta.xml +++ b/builds/updates-beta.xml @@ -1,7 +1,7 @@