diff --git a/CHANGELOG.md b/CHANGELOG.md index a5b0ebd9d..4547a9576 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ Sometimes the changelog has notes (not comprehensive) acknowledging people's wor ### v1.11.14 +**v1.11.14.4** *(2015-10-26)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.14.4/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.14.4/builds/4chan-X-noupdate.crx "Chromium version")] +- Support drawing on frames from WebMs. + **v1.11.14.3** *(2015-10-25)* - [[Firefox](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.14.3/builds/4chan-X-noupdate.user.js "Firefox version")] [[Chromium](https://raw.githubusercontent.com/ccd0/4chan-x/1.11.14.3/builds/4chan-X-noupdate.crx "Chromium version")] - Support opening a blank canvas from boards other than /i/. With no file selected, oekaki button in QR shows/hides the new image controls. - Support resume (retaining layers and undo history) in Tegaki when possible. Only available when re-opening the last image edited. diff --git a/builds/4chan-X-beta.crx b/builds/4chan-X-beta.crx index 0a1a57870..18ff86968 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 213c1db86..812344f51 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.14.3 +// @version 1.11.14.4 // @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 5aa8b569a..03b648c0e 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.14.3 +// @version 1.11.14.4 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -414,7 +414,7 @@ doc = d.documentElement; g = { - VERSION: '1.11.14.3', + VERSION: '1.11.14.4', NAMESPACE: '4chan X.', boards: {} }; @@ -7376,7 +7376,7 @@ if (blob) { return QR.handleFiles([blob]); } else { - return QR.error("Can't load image."); + return QR.error("Can't load file."); } }); }, @@ -8951,8 +8951,8 @@ }); }, node: function() { - var link, ref; - if (!((ref = this.file) != null ? ref.isImage : void 0)) { + var link; + if (!(this.file && (this.file.isImage || this.file.isVideo))) { return; } if (this.isClone) { @@ -8971,19 +8971,41 @@ return $.on(link, 'click', QR.oekaki.editFile); }, editFile: function() { - var post; + var currentTime, isVideo, post, ref; if (!QR.postingIsEnabled) { return; } QR.quote.call(this); post = Get.postFromNode(this); + isVideo = post.file.isVideo; + currentTime = ((ref = post.file.fullImage) != null ? ref.currentTime : void 0) || 0; return CrossOrigin.file(post.file.url, function(blob) { - if (blob) { + var video; + if (!blob) { + return QR.error("Can't load file."); + } else if (isVideo) { + video = $.el('video'); + $.on(video, 'loadedmetadata', function() { + $.on(video, 'seeked', function() { + var canvas; + canvas = $.el('canvas', { + width: video.videoWidth, + height: video.videoHeight + }); + canvas.getContext('2d').drawImage(video, 0, 0); + return canvas.toBlob(function(snapshot) { + snapshot.name = post.file.name.replace(/\.\w+$/, '') + '.png'; + QR.handleFiles([snapshot]); + return QR.oekaki.edit(); + }); + }); + return video.currentTime = currentTime; + }); + return video.src = URL.createObjectURL(blob); + } else { blob.name = post.file.name; QR.handleFiles([blob]); return QR.oekaki.edit(); - } else { - return QR.error("Can't load image."); } }); }, @@ -9075,19 +9097,20 @@ })); }; cb = function(e) { - var img; + var file, isVideo; document.removeEventListener('QRFile', cb, false); if (!e.detail) { return error('No file to edit.'); } - if (!/^image\//.test(e.detail.type)) { + if (!/^(image|video)\//.test(e.detail.type)) { return error('Not an image.'); } - img = new Image(); - img.onerror = function() { - return error('Could not open image.'); - }; - img.onload = function() { + isVideo = /^video\//.test(e.detail.type); + file = document.createElement(isVideo ? 'video' : 'img'); + file.addEventListener('error', function() { + return error('Could not open file.', false); + }); + file.addEventListener((isVideo ? 'loadeddata' : 'load'), function() { if (Tegaki.bg) { Tegaki.destroy(); } @@ -9095,13 +9118,13 @@ Tegaki.open({ onDone: FCX.oekakiCB, onCancel: function() {}, - width: img.naturalWidth, - height: img.naturalHeight, + width: file.naturalWidth || file.videoWidth, + height: file.naturalHeight || file.videoHeight, bgColor: 'transparent' }); - return Tegaki.activeCtx.drawImage(img, 0, 0); - }; - return img.src = URL.createObjectURL(e.detail); + return Tegaki.activeCtx.drawImage(file, 0, 0); + }, false); + return file.src = URL.createObjectURL(e.detail); }; if (Tegaki.bg && Tegaki.onDoneCb === FCX.oekakiCB && source === FCX.oekakiLatest) { FCX.oekakiName = name; diff --git a/builds/4chan-X-noupdate.crx b/builds/4chan-X-noupdate.crx index a463df0ea..5f42c94f0 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 786e191d7..0a091018d 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.14.3 +// @version 1.11.14.4 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -414,7 +414,7 @@ doc = d.documentElement; g = { - VERSION: '1.11.14.3', + VERSION: '1.11.14.4', NAMESPACE: '4chan X.', boards: {} }; @@ -7376,7 +7376,7 @@ if (blob) { return QR.handleFiles([blob]); } else { - return QR.error("Can't load image."); + return QR.error("Can't load file."); } }); }, @@ -8951,8 +8951,8 @@ }); }, node: function() { - var link, ref; - if (!((ref = this.file) != null ? ref.isImage : void 0)) { + var link; + if (!(this.file && (this.file.isImage || this.file.isVideo))) { return; } if (this.isClone) { @@ -8971,19 +8971,41 @@ return $.on(link, 'click', QR.oekaki.editFile); }, editFile: function() { - var post; + var currentTime, isVideo, post, ref; if (!QR.postingIsEnabled) { return; } QR.quote.call(this); post = Get.postFromNode(this); + isVideo = post.file.isVideo; + currentTime = ((ref = post.file.fullImage) != null ? ref.currentTime : void 0) || 0; return CrossOrigin.file(post.file.url, function(blob) { - if (blob) { + var video; + if (!blob) { + return QR.error("Can't load file."); + } else if (isVideo) { + video = $.el('video'); + $.on(video, 'loadedmetadata', function() { + $.on(video, 'seeked', function() { + var canvas; + canvas = $.el('canvas', { + width: video.videoWidth, + height: video.videoHeight + }); + canvas.getContext('2d').drawImage(video, 0, 0); + return canvas.toBlob(function(snapshot) { + snapshot.name = post.file.name.replace(/\.\w+$/, '') + '.png'; + QR.handleFiles([snapshot]); + return QR.oekaki.edit(); + }); + }); + return video.currentTime = currentTime; + }); + return video.src = URL.createObjectURL(blob); + } else { blob.name = post.file.name; QR.handleFiles([blob]); return QR.oekaki.edit(); - } else { - return QR.error("Can't load image."); } }); }, @@ -9075,19 +9097,20 @@ })); }; cb = function(e) { - var img; + var file, isVideo; document.removeEventListener('QRFile', cb, false); if (!e.detail) { return error('No file to edit.'); } - if (!/^image\//.test(e.detail.type)) { + if (!/^(image|video)\//.test(e.detail.type)) { return error('Not an image.'); } - img = new Image(); - img.onerror = function() { - return error('Could not open image.'); - }; - img.onload = function() { + isVideo = /^video\//.test(e.detail.type); + file = document.createElement(isVideo ? 'video' : 'img'); + file.addEventListener('error', function() { + return error('Could not open file.', false); + }); + file.addEventListener((isVideo ? 'loadeddata' : 'load'), function() { if (Tegaki.bg) { Tegaki.destroy(); } @@ -9095,13 +9118,13 @@ Tegaki.open({ onDone: FCX.oekakiCB, onCancel: function() {}, - width: img.naturalWidth, - height: img.naturalHeight, + width: file.naturalWidth || file.videoWidth, + height: file.naturalHeight || file.videoHeight, bgColor: 'transparent' }); - return Tegaki.activeCtx.drawImage(img, 0, 0); - }; - return img.src = URL.createObjectURL(e.detail); + return Tegaki.activeCtx.drawImage(file, 0, 0); + }, false); + return file.src = URL.createObjectURL(e.detail); }; if (Tegaki.bg && Tegaki.onDoneCb === FCX.oekakiCB && source === FCX.oekakiLatest) { FCX.oekakiName = name; diff --git a/builds/4chan-X.crx b/builds/4chan-X.crx index 6f689b6cd..6e4a32142 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 0589d599f..20fc0904f 100644 --- a/builds/4chan-X.meta.js +++ b/builds/4chan-X.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.11.14.3 +// @version 1.11.14.4 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 5803dfdbf..a312d2079 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.14.3 +// @version 1.11.14.4 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -414,7 +414,7 @@ doc = d.documentElement; g = { - VERSION: '1.11.14.3', + VERSION: '1.11.14.4', NAMESPACE: '4chan X.', boards: {} }; @@ -7376,7 +7376,7 @@ if (blob) { return QR.handleFiles([blob]); } else { - return QR.error("Can't load image."); + return QR.error("Can't load file."); } }); }, @@ -8951,8 +8951,8 @@ }); }, node: function() { - var link, ref; - if (!((ref = this.file) != null ? ref.isImage : void 0)) { + var link; + if (!(this.file && (this.file.isImage || this.file.isVideo))) { return; } if (this.isClone) { @@ -8971,19 +8971,41 @@ return $.on(link, 'click', QR.oekaki.editFile); }, editFile: function() { - var post; + var currentTime, isVideo, post, ref; if (!QR.postingIsEnabled) { return; } QR.quote.call(this); post = Get.postFromNode(this); + isVideo = post.file.isVideo; + currentTime = ((ref = post.file.fullImage) != null ? ref.currentTime : void 0) || 0; return CrossOrigin.file(post.file.url, function(blob) { - if (blob) { + var video; + if (!blob) { + return QR.error("Can't load file."); + } else if (isVideo) { + video = $.el('video'); + $.on(video, 'loadedmetadata', function() { + $.on(video, 'seeked', function() { + var canvas; + canvas = $.el('canvas', { + width: video.videoWidth, + height: video.videoHeight + }); + canvas.getContext('2d').drawImage(video, 0, 0); + return canvas.toBlob(function(snapshot) { + snapshot.name = post.file.name.replace(/\.\w+$/, '') + '.png'; + QR.handleFiles([snapshot]); + return QR.oekaki.edit(); + }); + }); + return video.currentTime = currentTime; + }); + return video.src = URL.createObjectURL(blob); + } else { blob.name = post.file.name; QR.handleFiles([blob]); return QR.oekaki.edit(); - } else { - return QR.error("Can't load image."); } }); }, @@ -9075,19 +9097,20 @@ })); }; cb = function(e) { - var img; + var file, isVideo; document.removeEventListener('QRFile', cb, false); if (!e.detail) { return error('No file to edit.'); } - if (!/^image\//.test(e.detail.type)) { + if (!/^(image|video)\//.test(e.detail.type)) { return error('Not an image.'); } - img = new Image(); - img.onerror = function() { - return error('Could not open image.'); - }; - img.onload = function() { + isVideo = /^video\//.test(e.detail.type); + file = document.createElement(isVideo ? 'video' : 'img'); + file.addEventListener('error', function() { + return error('Could not open file.', false); + }); + file.addEventListener((isVideo ? 'loadeddata' : 'load'), function() { if (Tegaki.bg) { Tegaki.destroy(); } @@ -9095,13 +9118,13 @@ Tegaki.open({ onDone: FCX.oekakiCB, onCancel: function() {}, - width: img.naturalWidth, - height: img.naturalHeight, + width: file.naturalWidth || file.videoWidth, + height: file.naturalHeight || file.videoHeight, bgColor: 'transparent' }); - return Tegaki.activeCtx.drawImage(img, 0, 0); - }; - return img.src = URL.createObjectURL(e.detail); + return Tegaki.activeCtx.drawImage(file, 0, 0); + }, false); + return file.src = URL.createObjectURL(e.detail); }; if (Tegaki.bg && Tegaki.onDoneCb === FCX.oekakiCB && source === FCX.oekakiLatest) { FCX.oekakiName = name; diff --git a/builds/4chan-X.zip b/builds/4chan-X.zip index e3ccecc1f..232cd5260 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 6fa8146bd..3a87001cf 100644 --- a/builds/updates-beta.xml +++ b/builds/updates-beta.xml @@ -1,7 +1,7 @@ - + diff --git a/builds/updates.xml b/builds/updates.xml index c9893599e..283385829 100644 --- a/builds/updates.xml +++ b/builds/updates.xml @@ -1,7 +1,7 @@ - + diff --git a/package.json b/package.json index 1e7dae233..ea8187179 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,8 @@ "meta": { "name": "4chan X", "fork": "ccd0", - "version": "1.11.14.3", - "date": "2015-10-26T06:21:56.818Z", + "version": "1.11.14.4", + "date": "2015-10-26T18:29:12.872Z", "page": "https://www.4chan-x.net/", "downloads": "https://www.4chan-x.net/builds/", "oldVersions": "https://raw.githubusercontent.com/ccd0/4chan-x/",