Merge branch 'ccd0' into v3

Conflicts:
	builds/4chan-X.user.js
	builds/crx/script.js
	src/General/Get.coffee
	src/Images/Gallery.coffee
This commit is contained in:
Zixaphir 2014-04-07 18:35:18 -07:00
commit d9d2ceb9b1
7 changed files with 252 additions and 139 deletions

View File

@ -1424,8 +1424,8 @@
return this.board.posts.rm(this);
};
Post.prototype.addClone = function(context) {
return new Clone(this, context);
Post.prototype.addClone = function(context, contractThumb) {
return new Clone(this, context, contractThumb);
};
Post.prototype.rmClone = function(index) {
@ -1445,8 +1445,8 @@
Clone = (function(_super) {
__extends(Clone, _super);
function Clone(origin, context) {
var file, info, inline, inlined, key, nodes, post, root, val, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3;
function Clone(origin, context, contractThumb) {
var file, info, inline, inlined, key, nodes, post, root, val, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
this.origin = origin;
this.context = context;
_ref = ['ID', 'fullID', 'board', 'thread', 'info', 'quotes', 'isReply'];
@ -1455,7 +1455,7 @@
this[key] = origin[key];
}
nodes = origin.nodes;
root = nodes.root.cloneNode(true);
root = contractThumb ? this.cloneWithoutVideo(nodes.root) : nodes.root.cloneNode(true);
post = $('.post', root);
info = $('.postInfo', post);
this.nodes = {
@ -1515,6 +1515,17 @@
this.file.text = file.firstElementChild;
this.file.thumb = $('img[data-md5]', file);
this.file.fullImage = $('.full-image', file);
if (contractThumb) {
$.rmClass(root, 'expanded-image');
$.rmClass(this.file.thumb, 'expanding');
}
this.file.isExpanded = $.hasClass(root, 'expanded-image');
if ((_ref4 = this.file.fullImage) != null) {
_ref4.removeAttribute('id');
}
if ((_ref5 = $('.video-controls', this.file.text)) != null) {
_ref5.remove();
}
}
if (origin.isDead) {
this.isDead = true;
@ -1523,6 +1534,23 @@
root.dataset.clone = origin.clones.push(this) - 1;
}
Clone.prototype.cloneWithoutVideo = function(node) {
var child, clone, _i, _len, _ref;
if (node.tagName === 'VIDEO') {
return [];
} else if (node.nodeType === Node.ELEMENT_NODE && $('video', node)) {
clone = node.cloneNode(false);
_ref = node.childNodes;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
child = _ref[_i];
$.add(clone, this.cloneWithoutVideo(child));
}
return clone;
} else {
return node.cloneNode(true);
}
};
return Clone;
})(Post);
@ -3999,7 +4027,7 @@
if (!root.parentNode) {
return;
}
clone = post.addClone(context);
clone = post.addClone(context, $.hasClass(root, 'dialog'));
Clone.callbacks.execute([clone]);
nodes = clone.nodes;
$.rmAll(nodes.root);
@ -7682,21 +7710,22 @@
return nodes.total.textContent = --i;
},
generateThumb: function(file) {
var double, post, thumb, title;
var post, thumb, thumbImg, title;
post = Get.postFromNode(file);
title = ($('.fileText a', file)).textContent;
thumb = post.file.thumb.parentNode.cloneNode(true);
if (double = $('* + *', thumb)) {
$.rm(double);
}
thumb.className = 'gal-thumb';
thumb.title = title;
thumb = $.el('a', {
className: 'gal-thumb',
href: post.file.URL,
target: '_blank'
}, title = title);
thumb.dataset.id = Gallery.images.length;
thumb.dataset.post = $('a[title="Highlight this post"]', post.nodes.info).href;
if (post.file.isVideo) {
thumb.dataset.isVideo = true;
}
thumb.firstElementChild.style.cssText = '';
thumbImg = post.file.thumb.cloneNode(false);
thumbImg.style.cssText = '';
$.add(thumb, thumbImg);
$.on(thumb, 'click', Gallery.cb.open);
Gallery.images.push(thumb);
return $.add(Gallery.nodes.thumbs, thumb);
@ -7919,10 +7948,10 @@
$.on(thumb.parentNode, 'click', ImageExpand.cb.toggle);
if (this.isClone && $.hasClass(thumb, 'expanding')) {
ImageExpand.contract(this);
ImageExpand.expand(this);
return;
}
if (ImageExpand.on && !this.isHidden && (Conf['Expand spoilers'] || !this.file.isSpoiler)) {
return ImageExpand.expand(this);
} else if (this.isClone && this.file.isExpanded && this.file.isVideo) {
return ImageExpand.setupVideoControls(this);
} else if (ImageExpand.on && !this.isHidden && (Conf['Expand spoilers'] || !this.file.isSpoiler)) {
return ImageExpand.expand(this);
}
},
@ -8006,7 +8035,7 @@
return ImageExpand.contract(post);
},
contract: function(post) {
var cb, eventName, video, _ref, _ref1;
var cb, eventName, video, _ref;
if (post.file.isVideo && (video = post.file.fullImage)) {
video.pause();
TrashQueue.add(video, post);
@ -8017,9 +8046,7 @@
cb = _ref[eventName];
$.off(video, eventName, cb);
}
if ((_ref1 = post.file.videoControls) != null) {
_ref1.map($.rm);
}
$.rm(post.file.videoControls);
delete post.file.videoControls;
}
$.rmClass(post.nodes.root, 'expanded-image');
@ -8060,26 +8087,36 @@
if (!$.hasClass(thumb, 'expanding')) {
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');
ImageExpand.completeExpand2(post);
return;
}
bottom = post.nodes.root.getBoundingClientRect().bottom;
return $.queueTask(function() {
$.addClass(post.nodes.root, 'expanded-image');
$.rmClass(post.file.thumb, 'expanding');
ImageExpand.completeExpand2(post);
if (!(bottom <= 0)) {
return;
}
return window.scrollBy(0, post.nodes.root.getBoundingClientRect().bottom - bottom);
});
},
completeExpand2: function(post) {
var thumb;
thumb = post.file.thumb;
$.addClass(post.nodes.root, 'expanded-image');
$.rmClass(post.file.thumb, 'expanding');
post.file.isExpanded = true;
if (post.file.isVideo) {
return ImageExpand.setupVideo(post);
}
},
videoCB: {
click: function(e) {
if (this.paused && !this.controls) {
this.play();
return e.stopPropagation();
}
},
mousedown: function(e) {
if (e.button === 0) {
return this.dataset.mousedown = 'true';
@ -8099,21 +8136,21 @@
}
}
},
setupVideo: function(post) {
var cb, contract, eventName, file, play, video, _ref;
setupVideoControls: function(post) {
var cb, contract, eventName, file, video, _ref;
file = post.file;
video = file.fullImage;
file.videoControls = [];
file.thumb.parentNode.removeAttribute('href');
file.thumb.parentNode.removeAttribute('target');
video.muted = !Conf['Allow Sound'];
video.controls = Conf['Show Controls'];
video.dataset.mousedown = 'false';
_ref = ImageExpand.videoCB;
for (eventName in _ref) {
cb = _ref[eventName];
$.on(video, eventName, cb);
}
file.videoControls = $.el('span', {
className: 'video-controls'
});
if (Conf['Show Controls']) {
contract = $.el('a', {
textContent: 'contract',
@ -8123,13 +8160,22 @@
$.on(contract, 'click', function(e) {
return ImageExpand.contract(post);
});
file.videoControls.push($.tn('\u00A0'), contract);
$.add(file.videoControls, [$.tn('\u00A0'), contract]);
}
return $.add(file.text, file.videoControls);
},
setupVideo: function(post) {
var file, video;
ImageExpand.setupVideoControls(post);
file = post.file;
video = file.fullImage;
video.muted = !Conf['Allow Sound'];
video.controls = Conf['Show Controls'];
if (Conf['Autoplay']) {
video.controls = false;
video.play();
if (Conf['Show Controls']) {
$.asap((function() {
return $.asap((function() {
return (video.readyState >= 3 && video.currentTime <= Math.max(0.1, video.duration - 0.5)) || !file.isExpanded;
}), function() {
if (file.isExpanded) {
@ -8137,18 +8183,7 @@
}
}, 500);
}
} else if (!Conf['Show 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;

View File

@ -1481,8 +1481,8 @@
return this.board.posts.rm(this);
};
Post.prototype.addClone = function(context) {
return new Clone(this, context);
Post.prototype.addClone = function(context, contractThumb) {
return new Clone(this, context, contractThumb);
};
Post.prototype.rmClone = function(index) {
@ -1502,8 +1502,8 @@
Clone = (function(_super) {
__extends(Clone, _super);
function Clone(origin, context) {
var file, info, inline, inlined, key, nodes, post, root, val, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3;
function Clone(origin, context, contractThumb) {
var file, info, inline, inlined, key, nodes, post, root, val, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
this.origin = origin;
this.context = context;
_ref = ['ID', 'fullID', 'board', 'thread', 'info', 'quotes', 'isReply'];
@ -1512,7 +1512,7 @@
this[key] = origin[key];
}
nodes = origin.nodes;
root = nodes.root.cloneNode(true);
root = contractThumb ? this.cloneWithoutVideo(nodes.root) : nodes.root.cloneNode(true);
post = $('.post', root);
info = $('.postInfo', post);
this.nodes = {
@ -1572,6 +1572,17 @@
this.file.text = file.firstElementChild;
this.file.thumb = $('img[data-md5]', file);
this.file.fullImage = $('.full-image', file);
if (contractThumb) {
$.rmClass(root, 'expanded-image');
$.rmClass(this.file.thumb, 'expanding');
}
this.file.isExpanded = $.hasClass(root, 'expanded-image');
if ((_ref4 = this.file.fullImage) != null) {
_ref4.removeAttribute('id');
}
if ((_ref5 = $('.video-controls', this.file.text)) != null) {
_ref5.remove();
}
}
if (origin.isDead) {
this.isDead = true;
@ -1580,6 +1591,23 @@
root.dataset.clone = origin.clones.push(this) - 1;
}
Clone.prototype.cloneWithoutVideo = function(node) {
var child, clone, _i, _len, _ref;
if (node.tagName === 'VIDEO') {
return [];
} else if (node.nodeType === Node.ELEMENT_NODE && $('video', node)) {
clone = node.cloneNode(false);
_ref = node.childNodes;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
child = _ref[_i];
$.add(clone, this.cloneWithoutVideo(child));
}
return clone;
} else {
return node.cloneNode(true);
}
};
return Clone;
})(Post);
@ -4060,7 +4088,7 @@
if (!root.parentNode) {
return;
}
clone = post.addClone(context);
clone = post.addClone(context, $.hasClass(root, 'dialog'));
Clone.callbacks.execute([clone]);
nodes = clone.nodes;
$.rmAll(nodes.root);
@ -7721,21 +7749,22 @@
return nodes.total.textContent = --i;
},
generateThumb: function(file) {
var double, post, thumb, title;
var post, thumb, thumbImg, title;
post = Get.postFromNode(file);
title = ($('.fileText a', file)).textContent;
thumb = post.file.thumb.parentNode.cloneNode(true);
if (double = $('* + *', thumb)) {
$.rm(double);
}
thumb.className = 'gal-thumb';
thumb.title = title;
thumb = $.el('a', {
className: 'gal-thumb',
href: post.file.URL,
target: '_blank'
}, title = title);
thumb.dataset.id = Gallery.images.length;
thumb.dataset.post = $('a[title="Highlight this post"]', post.nodes.info).href;
if (post.file.isVideo) {
thumb.dataset.isVideo = true;
}
thumb.firstElementChild.style.cssText = '';
thumbImg = post.file.thumb.cloneNode(false);
thumbImg.style.cssText = '';
$.add(thumb, thumbImg);
$.on(thumb, 'click', Gallery.cb.open);
Gallery.images.push(thumb);
return $.add(Gallery.nodes.thumbs, thumb);
@ -7958,10 +7987,10 @@
$.on(thumb.parentNode, 'click', ImageExpand.cb.toggle);
if (this.isClone && $.hasClass(thumb, 'expanding')) {
ImageExpand.contract(this);
ImageExpand.expand(this);
return;
}
if (ImageExpand.on && !this.isHidden && (Conf['Expand spoilers'] || !this.file.isSpoiler)) {
return ImageExpand.expand(this);
} else if (this.isClone && this.file.isExpanded && this.file.isVideo) {
return ImageExpand.setupVideoControls(this);
} else if (ImageExpand.on && !this.isHidden && (Conf['Expand spoilers'] || !this.file.isSpoiler)) {
return ImageExpand.expand(this);
}
},
@ -8045,7 +8074,7 @@
return ImageExpand.contract(post);
},
contract: function(post) {
var cb, eventName, video, _ref, _ref1;
var cb, eventName, video, _ref;
if (post.file.isVideo && (video = post.file.fullImage)) {
video.pause();
TrashQueue.add(video, post);
@ -8056,9 +8085,7 @@
cb = _ref[eventName];
$.off(video, eventName, cb);
}
if ((_ref1 = post.file.videoControls) != null) {
_ref1.map($.rm);
}
$.rm(post.file.videoControls);
delete post.file.videoControls;
}
$.rmClass(post.nodes.root, 'expanded-image');
@ -8099,26 +8126,36 @@
if (!$.hasClass(thumb, 'expanding')) {
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');
ImageExpand.completeExpand2(post);
return;
}
bottom = post.nodes.root.getBoundingClientRect().bottom;
return $.queueTask(function() {
$.addClass(post.nodes.root, 'expanded-image');
$.rmClass(post.file.thumb, 'expanding');
ImageExpand.completeExpand2(post);
if (!(bottom <= 0)) {
return;
}
return window.scrollBy(0, post.nodes.root.getBoundingClientRect().bottom - bottom);
});
},
completeExpand2: function(post) {
var thumb;
thumb = post.file.thumb;
$.addClass(post.nodes.root, 'expanded-image');
$.rmClass(post.file.thumb, 'expanding');
post.file.isExpanded = true;
if (post.file.isVideo) {
return ImageExpand.setupVideo(post);
}
},
videoCB: {
click: function(e) {
if (this.paused && !this.controls) {
this.play();
return e.stopPropagation();
}
},
mousedown: function(e) {
if (e.button === 0) {
return this.dataset.mousedown = 'true';
@ -8138,21 +8175,21 @@
}
}
},
setupVideo: function(post) {
var cb, contract, eventName, file, play, video, _ref;
setupVideoControls: function(post) {
var cb, contract, eventName, file, video, _ref;
file = post.file;
video = file.fullImage;
file.videoControls = [];
file.thumb.parentNode.removeAttribute('href');
file.thumb.parentNode.removeAttribute('target');
video.muted = !Conf['Allow Sound'];
video.controls = Conf['Show Controls'];
video.dataset.mousedown = 'false';
_ref = ImageExpand.videoCB;
for (eventName in _ref) {
cb = _ref[eventName];
$.on(video, eventName, cb);
}
file.videoControls = $.el('span', {
className: 'video-controls'
});
if (Conf['Show Controls']) {
contract = $.el('a', {
textContent: 'contract',
@ -8162,13 +8199,22 @@
$.on(contract, 'click', function(e) {
return ImageExpand.contract(post);
});
file.videoControls.push($.tn('\u00A0'), contract);
$.add(file.videoControls, [$.tn('\u00A0'), contract]);
}
return $.add(file.text, file.videoControls);
},
setupVideo: function(post) {
var file, video;
ImageExpand.setupVideoControls(post);
file = post.file;
video = file.fullImage;
video.muted = !Conf['Allow Sound'];
video.controls = Conf['Show Controls'];
if (Conf['Autoplay']) {
video.controls = false;
video.play();
if (Conf['Show Controls']) {
$.asap((function() {
return $.asap((function() {
return (video.readyState >= 3 && video.currentTime <= Math.max(0.1, video.duration - 0.5)) || !file.isExpanded;
}), function() {
if (file.isExpanded) {
@ -8176,18 +8222,7 @@
}
}, 500);
}
} else if (!Conf['Show 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;

View File

@ -47,7 +47,7 @@ Get =
# get all their backlinks.
posts.forEach (qPost) ->
if fullID in qPost.quotes
handleQuotes qPost, 'quotelinks'
handleQuotes qPost, 'quotelinks'
# Second:
# If we have quote backlinks:
@ -62,6 +62,7 @@ Get =
quotelinks.filter (quotelink) ->
{boardID, postID} = Get.postDataFromLink quotelink
boardID is post.board.ID and postID is post.ID
postClone: (boardID, threadID, postID, root, context) ->
if post = g.posts["#{boardID}.#{postID}"]
Get.insert post, root, context
@ -80,7 +81,7 @@ Get =
insert: (post, root, context) ->
# Stop here if the container has been removed while loading.
return unless root.parentNode
clone = post.addClone context
clone = post.addClone context, ($.hasClass root, 'dialog')
Clone.callbacks.execute [clone]
# Get rid of the side arrows/stubs.

View File

@ -1,11 +1,14 @@
class Clone extends Post
constructor: (@origin, @context) ->
constructor: (@origin, @context, contractThumb) ->
for key in ['ID', 'fullID', 'board', 'thread', 'info', 'quotes', 'isReply']
# Copy or point to the origin's key value.
@[key] = origin[key]
{nodes} = origin
root = nodes.root.cloneNode true
root = if contractThumb
@cloneWithoutVideo nodes.root
else
nodes.root.cloneNode true
post = $ '.post', root
info = $ '.postInfo', post
@nodes =
@ -56,6 +59,29 @@ class Clone extends Post
@file.thumb = $ 'img[data-md5]', file
@file.fullImage = $ '.full-image', file
# Contract thumbnails in quote preview
if contractThumb
$.rmClass root, 'expanded-image'
$.rmClass @file.thumb, 'expanding'
@file.isExpanded = $.hasClass root, 'expanded-image'
# Remove any #ihover ID
@file.fullImage?.removeAttribute 'id'
# Remove video controls.
($ '.video-controls', @file.text)?.remove()
@isDead = true if origin.isDead
@isClone = true
root.dataset.clone = origin.clones.push(@) - 1
cloneWithoutVideo: (node) ->
if node.tagName is 'VIDEO'
[]
else if node.nodeType is Node.ELEMENT_NODE and $ 'video', node
clone = node.cloneNode false
$.add clone, @cloneWithoutVideo child for child in node.childNodes
clone
else
node.cloneNode true

View File

@ -290,8 +290,8 @@ class Post
@thread.posts.rm @
@board.posts.rm @
addClone: (context) ->
new Clone @, context
addClone: (context, contractThumb) ->
new Clone @, context, contractThumb
rmClone: (index) ->
@clones.splice index, 1

View File

@ -106,16 +106,20 @@ Gallery =
generateThumb: (file) ->
post = Get.postFromNode file
title = ($ '.fileText a', file).textContent
thumb = post.file.thumb.parentNode.cloneNode true
if double = $ '* + *', thumb
$.rm double
thumb.className = 'gal-thumb'
thumb.title = title
thumb.dataset.id = Gallery.images.length
thumb.dataset.post = $('a[title="Highlight this post"]', post.nodes.info).href
thumb = $.el 'a',
className: 'gal-thumb'
href: post.file.URL
target: '_blank'
title = title
thumb.dataset.id = Gallery.images.length
thumb.dataset.post = $('a[title="Highlight this post"]', post.nodes.info).href
thumb.dataset.isVideo = true if post.file.isVideo
thumb.firstElementChild.style.cssText = ''
thumbImg = post.file.thumb.cloneNode false
thumbImg.style.cssText = ''
$.add thumb, thumbImg
$.on thumb, 'click', Gallery.cb.open
@ -153,12 +157,12 @@ Gallery =
src: name.href = @href
title: name.download = name.textContent = @title
if @dataset.isVideo
if @dataset.isVideo
file.muted = !Conf['Allow Sound']
file.controls = Conf['Show Controls']
file.autoplay = Conf['Autoplay']
file.loop = true
$.extend file.dataset, @dataset
$.replace nodes.current, file
nodes.count.textContent = +@dataset.id + 1
@ -174,7 +178,7 @@ Gallery =
return if top < 0
nodes.thumbs.scrollTop += top
$.on file, 'error', ->
Gallery.cb.error file, thumb

View File

@ -22,8 +22,9 @@ ImageExpand =
# make it loading in the clone too.
ImageExpand.contract @
ImageExpand.expand @
return
if ImageExpand.on and !@isHidden and (Conf['Expand spoilers'] or !@file.isSpoiler)
else if @isClone and @file.isExpanded and @file.isVideo
ImageExpand.setupVideoControls @
else if ImageExpand.on and !@isHidden and (Conf['Expand spoilers'] or !@file.isSpoiler)
ImageExpand.expand @
cb:
toggle: (e) ->
@ -96,7 +97,7 @@ ImageExpand =
post.file.thumb.parentNode.target = '_blank'
for eventName, cb of ImageExpand.videoCB
$.off video, eventName, cb
post.file.videoControls?.map($.rm)
$.rm post.file.videoControls
delete post.file.videoControls
$.rmClass post.nodes.root, 'expanded-image'
$.rmClass post.file.thumb, 'expanding'
@ -123,22 +124,31 @@ ImageExpand =
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.
$.addClass post.nodes.root, 'expanded-image'
$.rmClass post.file.thumb, 'expanding'
ImageExpand.completeExpand2 post
return
{bottom} = post.nodes.root.getBoundingClientRect()
$.queueTask ->
$.addClass post.nodes.root, 'expanded-image'
$.rmClass post.file.thumb, 'expanding'
ImageExpand.completeExpand2 post
return unless bottom <= 0
window.scrollBy 0, post.nodes.root.getBoundingClientRect().bottom - bottom
completeExpand2: (post) ->
{thumb} = post.file
$.addClass post.nodes.root, 'expanded-image'
$.rmClass post.file.thumb, 'expanding'
post.file.isExpanded = true
ImageExpand.setupVideo post if post.file.isVideo
videoCB:
click: (e) ->
if @paused and not @controls
@play()
e.stopPropagation()
# dragging to the left contracts the video
mousedown: (e) -> @dataset.mousedown = 'true' if e.button is 0
mouseup: (e) -> @dataset.mousedown = 'false' if e.button is 0
mouseover: (e) -> @dataset.mousedown = 'false'
@ -146,42 +156,44 @@ ImageExpand =
if @dataset.mousedown is 'true' and e.clientX <= @getBoundingClientRect().left
ImageExpand.contract (Get.postFromNode @)
setupVideo: (post) ->
setupVideoControls: (post) ->
{file} = post
video = file.fullImage
file.videoControls = []
# disable link to file so native controls can work
file.thumb.parentNode.removeAttribute 'href'
file.thumb.parentNode.removeAttribute 'target'
video.muted = !Conf['Allow Sound']
video.controls = Conf['Show Controls']
# drag left to contract
# setup callbacks on video element
video.dataset.mousedown = 'false'
$.on video, eventName, cb for eventName, cb of ImageExpand.videoCB
# setup controls in file info
file.videoControls = $.el 'span',
className: 'video-controls'
if Conf['Show 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
$.add file.videoControls, [$.tn('\u00A0'), contract]
$.add file.text, file.videoControls
setupVideo: (post) ->
ImageExpand.setupVideoControls post
{file} = post
video = file.fullImage
video.muted = !Conf['Allow Sound']
video.controls = Conf['Show Controls']
if Conf['Autoplay']
video.controls = false
video.play()
# Hacky workaround for Firefox forever-loading bug
# Hacky workaround for Firefox forever-loading bug for very short videos
if Conf['Show Controls']
$.asap (-> (video.readyState >= 3 and video.currentTime <= Math.max 0.1, (video.duration - 0.5)) or !file.isExpanded), ->
video.controls = true if file.isExpanded
, 500
else unless Conf['Show 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 @