Merge branch 'v3'

Conflicts:
	CHANGELOG.md
	LICENSE
	builds/appchan-x.user.js
	builds/crx/manifest.json
	builds/crx/script.js
	builds/updates.xml
	latest.js
	package.json
This commit is contained in:
Zixaphir 2014-04-04 16:12:31 -07:00
commit 8536ae3d37
13 changed files with 195 additions and 87 deletions

View File

@ -1,5 +1,8 @@
**ccd0**: **ccd0**:
- Support expansion of .webm videos. - Support expansion of .webm videos.
- Support hover for .webm videos.
- Add .webm to supported posting types.
- Add option to enable/disable sound.
- Update archives with data from MayhemYDG fork. - Update archives with data from MayhemYDG fork.
### v2.9.11 ### v2.9.11

View File

@ -1,6 +1,6 @@
// ==UserScript== // ==UserScript==
// @name 4chan X // @name 4chan X
// @version 1.5.0 // @version 1.5.1
// @minGMVer 1.14 // @minGMVer 1.14
// @minFFVer 26 // @minFFVer 26
// @namespace 4chan-X // @namespace 4chan-X

View File

@ -172,7 +172,7 @@
}, },
'Images and Videos': { 'Images and Videos': {
'Image Expansion': [true, 'Expand images / videos.'], 'Image Expansion': [true, 'Expand images / videos.'],
'Image Hover': [true, 'Show full image on mouseover.'], 'Image Hover': [true, 'Show full image / video on mouseover.'],
'Image Hover in Catalog': [false, 'Show a floating expanded image on hover in the catalog.'], 'Image Hover in Catalog': [false, 'Show a floating expanded image on hover in the catalog.'],
'Gallery': [true, 'Adds a simple and cute image gallery.'], 'Gallery': [true, 'Adds a simple and cute image gallery.'],
'Sauce': [true, 'Add sauce links to images.'], 'Sauce': [true, 'Add sauce links to images.'],
@ -184,7 +184,8 @@
'Fappe Tyme': [false, 'Hide posts without images when toggled. *hint* *hint*'], '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.'], '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.'] 'Show Controls': [true, 'Show native seek and volume controls on videos. Contract videos when dragged to the left.'],
'Allow Sound': [true, 'Allow sound in inline videos.']
}, },
'Menu': { 'Menu': {
'Menu': [true, 'Add a drop-down menu to posts.'], 'Menu': [true, 'Add a drop-down menu to posts.'],
@ -6684,7 +6685,9 @@
if (e.type === 'keydown' && e.keyCode !== 13 || e.target.nodeName === "TEXTAREA") { if (e.type === 'keydown' && e.keyCode !== 13 || e.target.nodeName === "TEXTAREA") {
return; return;
} }
$.rm(this.el); if (this.el.parentNode === Header.hover) {
$.rm(this.el);
}
$.off(this.root, this.endEvents, this.hoverend); $.off(this.root, this.endEvents, this.hoverend);
$.off(d, 'keydown', this.hoverend); $.off(d, 'keydown', this.hoverend);
$.off(this.root, 'mousemove', this.hover); $.off(this.root, 'mousemove', this.hover);
@ -8597,7 +8600,7 @@
}; };
QR = { QR = {
mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'application/pdf', 'application/x-shockwave-flash', ''], mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'application/pdf', 'application/x-shockwave-flash', 'video/webm', ''],
init: function() { init: function() {
var con, sc; var con, sc;
this.db = new DataBoard('yourPosts'); this.db = new DataBoard('yourPosts');
@ -9030,21 +9033,25 @@
}, },
checkDimensions: function(file, isSingle, max) { checkDimensions: function(file, isSingle, max) {
var img; var img;
img = new Image(); if (/^image\//.test(file.type)) {
img.onload = (function(_this) { img = new Image();
return function() { img.onload = (function(_this) {
var height, width; return function() {
height = img.height, width = img.width; var height, width;
if (height > QR.max_heigth || width > QR.max_heigth) { height = img.height, width = img.width;
return QR.error("" + file.name + ": Image too large (image: " + img.height + "x" + img.width + "px, max: " + QR.max_heigth + "x" + QR.max_width + "px)"); if (height > QR.max_heigth || width > QR.max_heigth) {
} return QR.error("" + file.name + ": Image too large (image: " + img.height + "x" + img.width + "px, max: " + QR.max_heigth + "x" + QR.max_width + "px)");
if (height < QR.min_heigth || width < QR.min_heigth) { }
return QR.error("" + file.name + ": Image too small (image: " + img.height + "x" + img.width + "px, min: " + QR.min_heigth + "x" + QR.min_width + "px)"); if (height < QR.min_heigth || width < QR.min_heigth) {
} return QR.error("" + file.name + ": Image too small (image: " + img.height + "x" + img.width + "px, min: " + QR.min_heigth + "x" + QR.min_width + "px)");
return QR.handleFile(file, isSingle, max); }
}; return QR.handleFile(file, isSingle, max);
})(this); };
return img.src = URL.createObjectURL(file); })(this);
return img.src = URL.createObjectURL(file);
} else {
return QR.handleFile(file, isSingle, max);
}
}, },
handleFile: function(file, isSingle, max) { handleFile: function(file, isSingle, max) {
var post, _ref; var post, _ref;
@ -10046,7 +10053,7 @@
return; return;
} }
this.file.newName = this.filename.replace(/[/\\]/g, '-'); this.file.newName = this.filename.replace(/[/\\]/g, '-');
if (!/\.(jpe?g|png|gif|pdf|swf)$/i.test(this.filename)) { if (!/\.(jpe?g|png|gif|pdf|swf|webm)$/i.test(this.filename)) {
this.file.newName += '.jpg'; this.file.newName += '.jpg';
} }
return this.updateFilename(); return this.updateFilename();
@ -10765,9 +10772,12 @@
} }
$.addClass(thumb, 'expanding'); $.addClass(thumb, 'expanding');
naturalHeight = isVideo ? 'videoHeight' : 'naturalHeight'; naturalHeight = isVideo ? 'videoHeight' : 'naturalHeight';
if (post.file.fullImage) { if (img = post.file.fullImage) {
$.rmClass(img, 'ihover');
$.addClass(img, 'full-image');
img.controls = img.parentNode !== thumb.parentNode;
$.asap((function() { $.asap((function() {
return post.file.fullImage[naturalHeight]; return img[naturalHeight];
}), function() { }), function() {
return ImageExpand.completeExpand(post); return ImageExpand.completeExpand(post);
}); });
@ -10819,7 +10829,7 @@
file = post.file; file = post.file;
video = file.fullImage; video = file.fullImage;
file.videoControls = []; file.videoControls = [];
video.muted = true; video.muted = !Conf['Allow Sound'];
if (video.controls) { if (video.controls) {
contract = $.el('a', { contract = $.el('a', {
textContent: 'contract', textContent: 'contract',
@ -10972,8 +10982,8 @@
} }
}, },
node: function() { node: function() {
var _ref; var _ref, _ref1;
if (!((_ref = this.file) != null ? _ref.isImage : void 0)) { if (!(((_ref = this.file) != null ? _ref.isImage : void 0) || ((_ref1 = this.file) != null ? _ref1.isVideo : void 0))) {
return; return;
} }
return $.on(this.file.thumb, 'mouseover', ImageHover.mouseover); return $.on(this.file.thumb, 'mouseover', ImageHover.mouseover);
@ -10986,21 +10996,46 @@
return $.on(this.nodes.thumb, 'mouseover', ImageHover.mouseover); return $.on(this.nodes.thumb, 'mouseover', ImageHover.mouseover);
}, },
mouseover: function(e) { mouseover: function(e) {
var el, post; var el, isVideo, naturalHeight, post, thumb;
post = $.hasClass(this, 'thumb') ? g.posts[this.parentNode.dataset.fullID] : Get.postFromNode(this); post = $.hasClass(this, 'thumb') ? g.posts[this.parentNode.dataset.fullID] : Get.postFromNode(this);
el = $.el('img', { isVideo = post.file.isVideo;
id: 'ihover', if (post.file.fullImage) {
src: post.file.URL el = post.file.fullImage;
}); $.rmClass(el, 'full-image');
$.addClass(el, 'ihover');
} else {
el = $.el((isVideo ? 'video' : 'img'), {
className: 'ihover',
src: post.file.URL
});
post.file.fullImage = el;
thumb = post.file.thumb;
$.after((isVideo && Conf['Show Controls'] ? thumb.parentNode : thumb), el);
}
el.dataset.fullID = post.fullID; el.dataset.fullID = post.fullID;
$.add(Header.hover, el); if (isVideo) {
el.loop = true;
el.controls = false;
el.muted = !Conf['Allow Sound'];
if (Conf['Autoplay']) {
el.play();
}
}
naturalHeight = post.file.isVideo ? 'videoHeight' : 'naturalHeight';
UI.hover({ UI.hover({
root: this, root: this,
el: el, el: el,
latestEvent: e, latestEvent: e,
endEvents: 'mouseout click', endEvents: 'mouseout click',
asapTest: function() { asapTest: function() {
return el.naturalHeight; return el[naturalHeight];
},
cb: function() {
if (isVideo) {
el.pause();
}
$.rmClass(el, 'ihover');
return $.addClass(el, 'full-image');
} }
}); });
return $.on(el, 'error', ImageHover.error); return $.on(el, 'error', ImageHover.error);

Binary file not shown.

View File

@ -147,7 +147,7 @@
}, },
'Images and Videos': { 'Images and Videos': {
'Image Expansion': [true, 'Expand images / videos.'], 'Image Expansion': [true, 'Expand images / videos.'],
'Image Hover': [true, 'Show full image on mouseover.'], 'Image Hover': [true, 'Show full image / video on mouseover.'],
'Image Hover in Catalog': [false, 'Show a floating expanded image on hover in the catalog.'], 'Image Hover in Catalog': [false, 'Show a floating expanded image on hover in the catalog.'],
'Gallery': [true, 'Adds a simple and cute image gallery.'], 'Gallery': [true, 'Adds a simple and cute image gallery.'],
'Sauce': [true, 'Add sauce links to images.'], 'Sauce': [true, 'Add sauce links to images.'],
@ -159,7 +159,8 @@
'Fappe Tyme': [false, 'Hide posts without images when toggled. *hint* *hint*'], '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.'], '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.'] 'Show Controls': [true, 'Show native seek and volume controls on videos. Contract videos when dragged to the left.'],
'Allow Sound': [true, 'Allow sound in inline videos.']
}, },
'Menu': { 'Menu': {
'Menu': [true, 'Add a drop-down menu to posts.'], 'Menu': [true, 'Add a drop-down menu to posts.'],
@ -6738,7 +6739,9 @@
if (e.type === 'keydown' && e.keyCode !== 13 || e.target.nodeName === "TEXTAREA") { if (e.type === 'keydown' && e.keyCode !== 13 || e.target.nodeName === "TEXTAREA") {
return; return;
} }
$.rm(this.el); if (this.el.parentNode === Header.hover) {
$.rm(this.el);
}
$.off(this.root, this.endEvents, this.hoverend); $.off(this.root, this.endEvents, this.hoverend);
$.off(d, 'keydown', this.hoverend); $.off(d, 'keydown', this.hoverend);
$.off(this.root, 'mousemove', this.hover); $.off(this.root, 'mousemove', this.hover);
@ -8650,7 +8653,7 @@
}; };
QR = { QR = {
mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'application/pdf', 'application/x-shockwave-flash', ''], mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'application/pdf', 'application/x-shockwave-flash', 'video/webm', ''],
init: function() { init: function() {
var con, sc; var con, sc;
this.db = new DataBoard('yourPosts'); this.db = new DataBoard('yourPosts');
@ -9085,21 +9088,25 @@
}, },
checkDimensions: function(file, isSingle, max) { checkDimensions: function(file, isSingle, max) {
var img; var img;
img = new Image(); if (/^image\//.test(file.type)) {
img.onload = (function(_this) { img = new Image();
return function() { img.onload = (function(_this) {
var height, width; return function() {
height = img.height, width = img.width; var height, width;
if (height > QR.max_heigth || width > QR.max_heigth) { height = img.height, width = img.width;
return QR.error("" + file.name + ": Image too large (image: " + img.height + "x" + img.width + "px, max: " + QR.max_heigth + "x" + QR.max_width + "px)"); if (height > QR.max_heigth || width > QR.max_heigth) {
} return QR.error("" + file.name + ": Image too large (image: " + img.height + "x" + img.width + "px, max: " + QR.max_heigth + "x" + QR.max_width + "px)");
if (height < QR.min_heigth || width < QR.min_heigth) { }
return QR.error("" + file.name + ": Image too small (image: " + img.height + "x" + img.width + "px, min: " + QR.min_heigth + "x" + QR.min_width + "px)"); if (height < QR.min_heigth || width < QR.min_heigth) {
} return QR.error("" + file.name + ": Image too small (image: " + img.height + "x" + img.width + "px, min: " + QR.min_heigth + "x" + QR.min_width + "px)");
return QR.handleFile(file, isSingle, max); }
}; return QR.handleFile(file, isSingle, max);
})(this); };
return img.src = URL.createObjectURL(file); })(this);
return img.src = URL.createObjectURL(file);
} else {
return QR.handleFile(file, isSingle, max);
}
}, },
handleFile: function(file, isSingle, max) { handleFile: function(file, isSingle, max) {
var post, _ref; var post, _ref;
@ -10084,7 +10091,7 @@
return; return;
} }
this.file.newName = this.filename.replace(/[/\\]/g, '-'); this.file.newName = this.filename.replace(/[/\\]/g, '-');
if (!/\.(jpe?g|png|gif|pdf|swf)$/i.test(this.filename)) { if (!/\.(jpe?g|png|gif|pdf|swf|webm)$/i.test(this.filename)) {
this.file.newName += '.jpg'; this.file.newName += '.jpg';
} }
return this.updateFilename(); return this.updateFilename();
@ -10803,9 +10810,12 @@
} }
$.addClass(thumb, 'expanding'); $.addClass(thumb, 'expanding');
naturalHeight = isVideo ? 'videoHeight' : 'naturalHeight'; naturalHeight = isVideo ? 'videoHeight' : 'naturalHeight';
if (post.file.fullImage) { if (img = post.file.fullImage) {
$.rmClass(img, 'ihover');
$.addClass(img, 'full-image');
img.controls = img.parentNode !== thumb.parentNode;
$.asap((function() { $.asap((function() {
return post.file.fullImage[naturalHeight]; return img[naturalHeight];
}), function() { }), function() {
return ImageExpand.completeExpand(post); return ImageExpand.completeExpand(post);
}); });
@ -10857,7 +10867,7 @@
file = post.file; file = post.file;
video = file.fullImage; video = file.fullImage;
file.videoControls = []; file.videoControls = [];
video.muted = true; video.muted = !Conf['Allow Sound'];
if (video.controls) { if (video.controls) {
contract = $.el('a', { contract = $.el('a', {
textContent: 'contract', textContent: 'contract',
@ -10999,8 +11009,8 @@
} }
}, },
node: function() { node: function() {
var _ref; var _ref, _ref1;
if (!((_ref = this.file) != null ? _ref.isImage : void 0)) { if (!(((_ref = this.file) != null ? _ref.isImage : void 0) || ((_ref1 = this.file) != null ? _ref1.isVideo : void 0))) {
return; return;
} }
return $.on(this.file.thumb, 'mouseover', ImageHover.mouseover); return $.on(this.file.thumb, 'mouseover', ImageHover.mouseover);
@ -11013,21 +11023,46 @@
return $.on(this.nodes.thumb, 'mouseover', ImageHover.mouseover); return $.on(this.nodes.thumb, 'mouseover', ImageHover.mouseover);
}, },
mouseover: function(e) { mouseover: function(e) {
var el, post; var el, isVideo, naturalHeight, post, thumb;
post = $.hasClass(this, 'thumb') ? g.posts[this.parentNode.dataset.fullID] : Get.postFromNode(this); post = $.hasClass(this, 'thumb') ? g.posts[this.parentNode.dataset.fullID] : Get.postFromNode(this);
el = $.el('img', { isVideo = post.file.isVideo;
id: 'ihover', if (post.file.fullImage) {
src: post.file.URL el = post.file.fullImage;
}); $.rmClass(el, 'full-image');
$.addClass(el, 'ihover');
} else {
el = $.el((isVideo ? 'video' : 'img'), {
className: 'ihover',
src: post.file.URL
});
post.file.fullImage = el;
thumb = post.file.thumb;
$.after((isVideo && Conf['Show Controls'] ? thumb.parentNode : thumb), el);
}
el.dataset.fullID = post.fullID; el.dataset.fullID = post.fullID;
$.add(Header.hover, el); if (isVideo) {
el.loop = true;
el.controls = false;
el.muted = !Conf['Allow Sound'];
if (Conf['Autoplay']) {
el.play();
}
}
naturalHeight = post.file.isVideo ? 'videoHeight' : 'naturalHeight';
UI.hover({ UI.hover({
root: this, root: this,
el: el, el: el,
latestEvent: e, latestEvent: e,
endEvents: 'mouseout click', endEvents: 'mouseout click',
asapTest: function() { asapTest: function() {
return el.naturalHeight; return el[naturalHeight];
},
cb: function() {
if (isVideo) {
el.pause();
}
$.rmClass(el, 'ihover');
return $.addClass(el, 'full-image');
} }
}); });
return $.on(el, 'error', ImageHover.error); return $.on(el, 'error', ImageHover.error);

7
builds/updates.xml Normal file
View File

@ -0,0 +1,7 @@
<?xml version='1.0' encoding='UTF-8'?>
<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>
<app appid='lacclbnghgdicfifcamcmcnilckjamag'>
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/crx.crx' version='1.5.1' />
</app>
</gupdate>

View File

@ -121,7 +121,7 @@ Config =
] ]
'Image Hover': [ 'Image Hover': [
true true
'Show full image on mouseover.' 'Show full image / video on mouseover.'
] ]
'Image Hover in Catalog': [ 'Image Hover in Catalog': [
false false
@ -171,6 +171,10 @@ Config =
true true
'Show native seek and volume controls on videos. Contract videos when dragged to the left.' 'Show native seek and volume controls on videos. Contract videos when dragged to the left.'
] ]
'Allow Sound': [
true
'Allow sound in inline videos.'
]
'Menu': 'Menu':
'Menu': [ 'Menu': [

View File

@ -366,7 +366,7 @@ UI = do ->
hoverend = (e) -> hoverend = (e) ->
return if e.type is 'keydown' and e.keyCode isnt 13 or e.target.nodeName is "TEXTAREA" return if e.type is 'keydown' and e.keyCode isnt 13 or e.target.nodeName is "TEXTAREA"
$.rm @el $.rm @el if @el.parentNode is Header.hover
$.off @root, @endEvents, @hoverend $.off @root, @endEvents, @hoverend
$.off d, 'keydown', @hoverend $.off d, 'keydown', @hoverend
$.off @root, 'mousemove', @hover $.off @root, 'mousemove', @hover

View File

@ -108,7 +108,7 @@ div.center:not(.ad-cnt) {
/* fixed, z-index */ /* fixed, z-index */
#overlay, #overlay,
#fourchanx-settings, #fourchanx-settings,
#qp, #ihover, #qp, .ihover,
#navlinks, .fixed #header-bar, #navlinks, .fixed #header-bar,
:root.float #updater, :root.float #updater,
:root.float #thread-stats, :root.float #thread-stats,
@ -124,7 +124,7 @@ div.center:not(.ad-cnt) {
#notifications { #notifications {
z-index: 70; z-index: 70;
} }
#qp, #ihover { #qp, .ihover {
z-index: 60; z-index: 60;
} }
#menu { #menu {
@ -840,7 +840,7 @@ span.hide-announcement {
:root.gecko.fit-width .full-image { :root.gecko.fit-width .full-image {
width: 100%; width: 100%;
} }
#ihover { .ihover {
-moz-box-sizing: border-box; -moz-box-sizing: border-box;
box-sizing: border-box; box-sizing: border-box;
max-height: 100%; max-height: 100%;

View File

@ -103,9 +103,12 @@ ImageExpand =
return if post.isHidden or post.file.isExpanded or $.hasClass thumb, 'expanding' return if post.isHidden or post.file.isExpanded or $.hasClass thumb, 'expanding'
$.addClass thumb, 'expanding' $.addClass thumb, 'expanding'
naturalHeight = if isVideo then 'videoHeight' else 'naturalHeight' naturalHeight = if isVideo then 'videoHeight' else 'naturalHeight'
if post.file.fullImage if img = post.file.fullImage
# Expand already-loaded/ing picture. # Expand already-loaded/ing picture.
$.asap (-> post.file.fullImage[naturalHeight]), -> $.rmClass img, 'ihover'
$.addClass img, 'full-image'
img.controls = (img.parentNode isnt thumb.parentNode)
$.asap (-> img[naturalHeight]), ->
ImageExpand.completeExpand post ImageExpand.completeExpand post
return return
post.file.fullImage = img = $.el (if isVideo then 'video' else 'img'), post.file.fullImage = img = $.el (if isVideo then 'video' else 'img'),
@ -141,7 +144,7 @@ ImageExpand =
{file} = post {file} = post
video = file.fullImage video = file.fullImage
file.videoControls = [] file.videoControls = []
video.muted = true video.muted = not Conf['Allow Sound']
if video.controls if video.controls
# contract link in file info # contract link in file info
contract = $.el 'a', contract = $.el 'a',

View File

@ -9,7 +9,7 @@ ImageHover =
name: 'Image Hover' name: 'Image Hover'
cb: @catalogNode cb: @catalogNode
node: -> node: ->
return unless @file?.isImage return unless @file?.isImage or @file?.isVideo
$.on @file.thumb, 'mouseover', ImageHover.mouseover $.on @file.thumb, 'mouseover', ImageHover.mouseover
catalogNode: -> catalogNode: ->
return unless @thread.OP.file?.isImage return unless @thread.OP.file?.isImage
@ -19,17 +19,35 @@ ImageHover =
g.posts[@parentNode.dataset.fullID] g.posts[@parentNode.dataset.fullID]
else else
Get.postFromNode @ Get.postFromNode @
el = $.el 'img', {isVideo} = post.file
id: 'ihover' if post.file.fullImage
src: post.file.URL el = post.file.fullImage
$.rmClass el, 'full-image'
$.addClass el, 'ihover'
else
el = $.el (if isVideo then 'video' else 'img'),
className: 'ihover'
src: post.file.URL
post.file.fullImage = el
{thumb} = post.file
$.after (if isVideo and Conf['Show Controls'] then thumb.parentNode else thumb), el
el.dataset.fullID = post.fullID el.dataset.fullID = post.fullID
$.add Header.hover, el if isVideo
el.loop = true
el.controls = false
el.muted = not Conf['Allow Sound']
el.play() if Conf['Autoplay']
naturalHeight = if post.file.isVideo then 'videoHeight' else 'naturalHeight'
UI.hover UI.hover
root: @ root: @
el: el el: el
latestEvent: e latestEvent: e
endEvents: 'mouseout click' endEvents: 'mouseout click'
asapTest: -> el.naturalHeight asapTest: -> el[naturalHeight]
cb: ->
el.pause() if isVideo
$.rmClass el, 'ihover'
$.addClass el, 'full-image'
$.on el, 'error', ImageHover.error $.on el, 'error', ImageHover.error
error: -> error: ->
return unless doc.contains @ return unless doc.contains @

View File

@ -1,6 +1,6 @@
QR = QR =
# Add empty mimeType to avoid errors with URLs selected in Window's file dialog. # Add empty mimeType to avoid errors with URLs selected in Window's file dialog.
mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'application/pdf', 'application/x-shockwave-flash', ''] mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'application/pdf', 'application/x-shockwave-flash', 'video/webm', '']
init: -> init: ->
@db = new DataBoard 'yourPosts' @db = new DataBoard 'yourPosts'
@ -371,13 +371,16 @@ QR =
$.addClass QR.nodes.el, 'dump' unless isSingle $.addClass QR.nodes.el, 'dump' unless isSingle
checkDimensions: (file, isSingle, max) -> checkDimensions: (file, isSingle, max) ->
img = new Image() if /^image\//.test file.type
img.onload = => img = new Image()
{height, width} = img img.onload = =>
return QR.error "#{file.name}: Image too large (image: #{img.height}x#{img.width}px, max: #{QR.max_heigth}x#{QR.max_width}px)" if height > QR.max_heigth or width > QR.max_heigth {height, width} = img
return QR.error "#{file.name}: Image too small (image: #{img.height}x#{img.width}px, min: #{QR.min_heigth}x#{QR.min_width}px)" if height < QR.min_heigth or width < QR.min_heigth return QR.error "#{file.name}: Image too large (image: #{img.height}x#{img.width}px, max: #{QR.max_heigth}x#{QR.max_width}px)" if height > QR.max_heigth or width > QR.max_heigth
return QR.error "#{file.name}: Image too small (image: #{img.height}x#{img.width}px, min: #{QR.min_heigth}x#{QR.min_width}px)" if height < QR.min_heigth or width < QR.min_heigth
QR.handleFile file, isSingle, max
img.src = URL.createObjectURL file
else
QR.handleFile file, isSingle, max QR.handleFile file, isSingle, max
img.src = URL.createObjectURL file
handleFile: (file, isSingle, max) -> handleFile: (file, isSingle, max) ->
if file.size > max if file.size > max

View File

@ -146,7 +146,7 @@ QR.post = class
when 'filename' when 'filename'
return unless @file return unless @file
@file.newName = @filename.replace /[/\\]/g, '-' @file.newName = @filename.replace /[/\\]/g, '-'
unless /\.(jpe?g|png|gif|pdf|swf)$/i.test @filename unless /\.(jpe?g|png|gif|pdf|swf|webm)$/i.test @filename
# 4chan will truncate the filename if it has no extension, # 4chan will truncate the filename if it has no extension,
# but it will always replace the extension by the correct one, # but it will always replace the extension by the correct one,
# so we suffix it with '.jpg' when needed. # so we suffix it with '.jpg' when needed.