Merge branch 'ccd0' into v3
Rebase ImageExpand implemention off ccd0's Conflicts: CHANGELOG.md builds/4chan-X.user.js builds/crx.crx builds/crx/script.js src/Images/ImageExpand.coffee
This commit is contained in:
commit
b00390b980
20
CHANGELOG.md
20
CHANGELOG.md
@ -1,3 +1,19 @@
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
### v1.7.3
|
||||
*2014-04-07*
|
||||
|
||||
**ccd0**
|
||||
- Fix behavior of .webm videos expanded within inline quotes.
|
||||
- Contract thumbnails in quoted previews to avoid crashes caused by videos in quoted previews on some systems.
|
||||
- Change interface when both `Autoplay` and `Show Controls` are unchecked. In this mode, videos are now activated by clicking on them. The first click expands the video, the second click plays the video, and the third click contracts it.
|
||||
- Add item `Expand videos` in `Image Expansion` menu, which enables expansion of videos by `Expand All Images`. Disabled by default. Previously videos were expanded.
|
||||
- Disable autoplay for videos expanded by `Expand All Images`.
|
||||
|
||||
### v1.7.2
|
||||
*2014-04-07*
|
||||
|
||||
>>>>>>> ccd0
|
||||
**ccd0**
|
||||
- Restore thread expansion with JSON navigation disabled.
|
||||
|
||||
@ -36,13 +52,15 @@
|
||||
**ccd0**:
|
||||
- Support hover for .webm videos.
|
||||
- Add .webm to supported posting types.
|
||||
- Add option to enable/disable sound.
|
||||
- Add option `Allow Sound` to enable/disable sound. Enabled by default.
|
||||
|
||||
## v1.5.0
|
||||
*2014-04-04*
|
||||
|
||||
**ccd0**:
|
||||
- Support expansion of .webm videos.
|
||||
- New setting: `Autoplay`, enabled by default. Causes videos to play immediately when expanded.
|
||||
- New setting: `Show Controls`, enabled by default. Shows native controls on videos.
|
||||
|
||||
### v1.4.7
|
||||
*2014-04-03*
|
||||
|
||||
2
LICENSE
2
LICENSE
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 4chan X - Version 1.7.2 - 2014-04-07
|
||||
* 4chan X - Version 1.7.3 - 2014-04-08
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// ==UserScript==
|
||||
// @name 4chan X
|
||||
// @version 1.7.2
|
||||
// @version 1.7.3
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// Generated by CoffeeScript
|
||||
// ==UserScript==
|
||||
// @name 4chan X
|
||||
// @version 1.7.2
|
||||
// @version 1.7.3
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 26
|
||||
// @namespace 4chan-X
|
||||
@ -24,7 +24,7 @@
|
||||
// ==/UserScript==
|
||||
|
||||
/*
|
||||
* 4chan X - Version 1.7.2 - 2014-04-07
|
||||
* 4chan X - Version 1.7.3 - 2014-04-08
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
||||
@ -244,6 +244,7 @@
|
||||
'Fit width': [false, ''],
|
||||
'Fit height': [false, ''],
|
||||
'Expand spoilers': [true, 'Expand all images along with spoilers.'],
|
||||
'Expand videos': [false, 'Expand all images also expands videos (no autoplay).'],
|
||||
'Expand from here': [false, 'Expand all images only from current position to thread end.'],
|
||||
'Advance on contract': [false, 'Advance to next post when contracting an expanded image.']
|
||||
},
|
||||
@ -373,7 +374,7 @@
|
||||
doc = d.documentElement;
|
||||
|
||||
g = {
|
||||
VERSION: '1.7.2',
|
||||
VERSION: '1.7.3',
|
||||
NAMESPACE: '4chan X.',
|
||||
boards: {}
|
||||
};
|
||||
@ -7928,7 +7929,7 @@
|
||||
|
||||
ImageExpand = {
|
||||
init: function() {
|
||||
if (!Conf['Image Expansion']) {
|
||||
if (g.VIEW === 'catalog' || !Conf['Image Expansion']) {
|
||||
return;
|
||||
}
|
||||
this.EAI = $.el('a', {
|
||||
@ -7937,34 +7938,33 @@
|
||||
title: 'Expand All Images',
|
||||
href: 'javascript:;'
|
||||
});
|
||||
$.on(this.EAI, 'click', this.cb.toggleAll);
|
||||
$.on(this.EAI, 'click', ImageExpand.cb.toggleAll);
|
||||
Header.addShortcut(this.EAI, 3);
|
||||
$.on(d, 'scroll visibilitychange', this.cb.playVideos);
|
||||
return Post.callbacks.push({
|
||||
name: 'Image Expansion',
|
||||
cb: this.node
|
||||
});
|
||||
},
|
||||
node: function() {
|
||||
var thumb;
|
||||
if (!(this.file && (this.file.isImage || this.file.isVideo))) {
|
||||
var clone, 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;
|
||||
$.on(thumb.parentNode, 'click', ImageExpand.cb.toggle);
|
||||
if (this.isClone) {
|
||||
if (this.file.isImage && this.file.isExpanding) {
|
||||
ImageExpand.contract(this);
|
||||
ImageExpand.expand(this);
|
||||
return;
|
||||
}
|
||||
if (this.file.isExpanded && this.file.isVideo) {
|
||||
ImageExpand.setupVideoControls(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (ImageExpand.on && !this.isHidden && (Conf['Expand spoilers'] || !this.file.isSpoiler)) {
|
||||
if (this.isClone && $.hasClass(thumb, 'expanding')) {
|
||||
ImageExpand.contract(this);
|
||||
return ImageExpand.expand(this);
|
||||
} else if (this.isClone && this.file.isExpanded && this.file.isVideo) {
|
||||
clone = this;
|
||||
ImageExpand.setupVideoControls(clone);
|
||||
if (!clone.origin.file.fullImage.paused) {
|
||||
return $.queueTask(function() {
|
||||
return ImageExpand.startVideo(clone);
|
||||
});
|
||||
}
|
||||
} else if (ImageExpand.on && !this.isHidden && (Conf['Expand spoilers'] || !this.file.isSpoiler) && (Conf['Expand videos'] || !this.file.isVideo)) {
|
||||
return ImageExpand.expand(this, null, true);
|
||||
}
|
||||
},
|
||||
cb: {
|
||||
@ -7981,53 +7981,40 @@
|
||||
return ImageExpand.toggle(post);
|
||||
},
|
||||
toggleAll: function() {
|
||||
var func;
|
||||
var func, toggle;
|
||||
$.event('CloseMenu');
|
||||
toggle = function(post) {
|
||||
var file;
|
||||
file = post.file;
|
||||
if (!(file && (file.isImage || file.isVideo) && doc.contains(post.nodes.root))) {
|
||||
return;
|
||||
}
|
||||
if (ImageExpand.on && (!Conf['Expand spoilers'] && file.isSpoiler || !Conf['Expand videos'] && file.isVideo || Conf['Expand from here'] && Header.getTopOf(file.thumb) < 0)) {
|
||||
return;
|
||||
}
|
||||
return $.queueTask(func, post);
|
||||
};
|
||||
if (ImageExpand.on = $.hasClass(ImageExpand.EAI, 'expand-all-shortcut')) {
|
||||
ImageExpand.EAI.className = 'contract-all-shortcut fa fa-compress';
|
||||
ImageExpand.EAI.title = 'Contract All Images';
|
||||
func = ImageExpand.expand;
|
||||
func = function(post) {
|
||||
return ImageExpand.expand(post, null, true);
|
||||
};
|
||||
} else {
|
||||
ImageExpand.EAI.className = 'expand-all-shortcut fa fa-expand';
|
||||
ImageExpand.EAI.title = 'Expand All Images';
|
||||
func = ImageExpand.contract;
|
||||
}
|
||||
return g.posts.forEach(function(post) {
|
||||
var file, _i, _len, _ref;
|
||||
_ref = [post].concat(post.clones);
|
||||
var _i, _len, _ref;
|
||||
toggle(post);
|
||||
_ref = post.clones;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
post = _ref[_i];
|
||||
file = post.file;
|
||||
if (!(file && (file.isImage || file.isVideo) && doc.contains(post.nodes.root))) {
|
||||
return;
|
||||
}
|
||||
if (ImageExpand.on && (post.isHidden || !Conf['Expand spoilers'] && post.file.isSpoiler || !doc.contains(post.nodes.root) || Conf['Expand from here'] && Header.getTopOf(post.file.thumb) < 0)) {
|
||||
return;
|
||||
}
|
||||
$.queueTask(func, post);
|
||||
toggle(post);
|
||||
}
|
||||
});
|
||||
},
|
||||
playVideos: function(e) {
|
||||
var fullID, play, post, _i, _len, _ref, _ref1;
|
||||
_ref = g.posts;
|
||||
for (fullID in _ref) {
|
||||
post = _ref[fullID];
|
||||
if (!(post.file && post.file.isVideo && post.file.isExpanded)) {
|
||||
continue;
|
||||
}
|
||||
_ref1 = [post].concat(post.clones);
|
||||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
||||
post = _ref1[_i];
|
||||
play = !d.hidden && !post.isHidden && doc.contains(post.nodes.root) && Header.isNodeVisible(post.nodes.root);
|
||||
if (play) {
|
||||
post.file.fullImage.play();
|
||||
} else {
|
||||
post.file.fullImage.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
setFitness: function() {
|
||||
return (this.checked ? $.addClass : $.rmClass)(doc, this.name.toLowerCase().replace(/\s+/g, '-'));
|
||||
}
|
||||
@ -8035,7 +8022,7 @@
|
||||
toggle: function(post) {
|
||||
var headRect, left, root, thumb, top, x, y, _ref;
|
||||
thumb = post.file.thumb;
|
||||
if (!(post.file.isExpanded || post.file.isExpanding)) {
|
||||
if (!(post.file.isExpanded || $.hasClass(thumb, 'expanding'))) {
|
||||
ImageExpand.expand(post);
|
||||
return;
|
||||
}
|
||||
@ -8083,10 +8070,9 @@
|
||||
}
|
||||
$.rmClass(post.nodes.root, 'expanded-image');
|
||||
$.rmClass(post.file.thumb, 'expanding');
|
||||
delete post.file.isExpanding;
|
||||
return post.file.isExpanded = false;
|
||||
},
|
||||
expand: function(post, src) {
|
||||
expand: function(post, src, disableAutoplay) {
|
||||
var el, isVideo, thumb, _ref;
|
||||
_ref = post.file, thumb = _ref.thumb, isVideo = _ref.isVideo;
|
||||
if (post.isHidden || post.file.isExpanded || $.hasClass(thumb, 'expanding')) {
|
||||
@ -8109,42 +8095,49 @@
|
||||
$.after(thumb, el);
|
||||
}
|
||||
return $.asap((function() {
|
||||
return el.videoHeight || el.naturalHeight;
|
||||
if (isVideo) {
|
||||
return el.videoHeight;
|
||||
} else {
|
||||
return el.naturalHeight;
|
||||
}
|
||||
}), function() {
|
||||
return ImageExpand.completeExpand(post);
|
||||
return ImageExpand.completeExpand(post, disableAutoplay);
|
||||
});
|
||||
},
|
||||
completeExpand: function(post) {
|
||||
var bottom, complete, thumb;
|
||||
completeExpand: function(post, disableAutoplay) {
|
||||
var bottom, thumb;
|
||||
thumb = post.file.thumb;
|
||||
if (!$.hasClass(thumb, 'expanding')) {
|
||||
return;
|
||||
}
|
||||
delete post.file.isExpanding;
|
||||
post.file.isExpanded = true;
|
||||
complete = function() {
|
||||
$.addClass(post.nodes.root, 'expanded-image');
|
||||
$.rmClass(post.file.thumb, 'expanding');
|
||||
if (post.file.isVideo) {
|
||||
return ImageExpand.setupVideo(post);
|
||||
}
|
||||
};
|
||||
if (!post.nodes.root.parentNode) {
|
||||
complete();
|
||||
ImageExpand.completeExpand2(post);
|
||||
return;
|
||||
}
|
||||
if (post.file.isVideo && !d.hidden && Header.isNodeVisible(post.nodes.root)) {
|
||||
post.file.fullImage.play();
|
||||
}
|
||||
bottom = post.nodes.root.getBoundingClientRect().bottom;
|
||||
return $.queueTask(function() {
|
||||
complete();
|
||||
ImageExpand.completeExpand2(post, disableAutoplay);
|
||||
if (!(bottom <= 0)) {
|
||||
return;
|
||||
}
|
||||
return window.scrollBy(0, post.nodes.root.getBoundingClientRect().bottom - bottom);
|
||||
});
|
||||
},
|
||||
completeExpand2: function(post, disableAutoplay) {
|
||||
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) {
|
||||
ImageExpand.setupVideoControls(post);
|
||||
post.file.fullImage.muted = !Conf['Allow Sound'];
|
||||
post.file.fullImage.controls = Conf['Show Controls'];
|
||||
if (Conf['Autoplay'] && !disableAutoplay) {
|
||||
return ImageExpand.startVideo(post);
|
||||
}
|
||||
}
|
||||
},
|
||||
videoCB: {
|
||||
click: function(e) {
|
||||
if (this.paused && !this.controls) {
|
||||
@ -8199,34 +8192,29 @@
|
||||
}
|
||||
return $.add(file.text, file.videoControls);
|
||||
},
|
||||
setupVideo: function(post) {
|
||||
var file, video;
|
||||
ImageExpand.setupVideoControls(post);
|
||||
startVideo: function(post) {
|
||||
var controls, file, video;
|
||||
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']) {
|
||||
return $.asap((function() {
|
||||
return (video.readyState >= 3 && video.currentTime <= Math.max(0.1, video.duration - 0.5)) || !file.isExpanded;
|
||||
}), function() {
|
||||
if (file.isExpanded) {
|
||||
return video.controls = true;
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
controls = video.controls;
|
||||
video.controls = false;
|
||||
video.play();
|
||||
if (controls) {
|
||||
return $.asap((function() {
|
||||
return (video.readyState >= 3 && video.currentTime <= Math.max(0.1, video.duration - 0.5)) || !file.isExpanded;
|
||||
}), function() {
|
||||
if (file.isExpanded) {
|
||||
return video.controls = true;
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
var URL, post, src, timeoutID;
|
||||
post = Get.postFromNode(this);
|
||||
post.file.isReady = false;
|
||||
$.rm(this);
|
||||
delete post.file.fullImage;
|
||||
if (!(post.file.isExpanding || post.file.isExpanded)) {
|
||||
if (!($.hasClass(post.file.thumb, 'expanding') || $.hasClass(post.nodes.root, 'expanded-image'))) {
|
||||
return;
|
||||
}
|
||||
ImageExpand.contract(post);
|
||||
@ -8271,7 +8259,7 @@
|
||||
menu: {
|
||||
init: function() {
|
||||
var conf, createSubEntry, el, name, subEntries, _ref;
|
||||
if (!Conf['Image Expansion']) {
|
||||
if (g.VIEW === 'catalog' || !Conf['Image Expansion']) {
|
||||
return;
|
||||
}
|
||||
el = $.el('span', {
|
||||
@ -12964,7 +12952,7 @@
|
||||
return;
|
||||
}
|
||||
$.event('CloseMenu');
|
||||
html = "<nav><div class=sections-list></div><p class='imp-exp-result warning'></p><div class=credits><a class=export>Export</a> | <a class=import>Import</a> | <a class=reset>Reset Settings</a> | <input type=file hidden><a href='https://github.com/ccd0/4chan-x' target=_blank>4chan X</a> |<a href='https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md' target=_blank>" + g.VERSION + "</a> |<a href='https://github.com/ccd0/4chan-x/blob/master/README.md#reporting-bugs-and-suggestions' target=_blank>Issues</a> |<a href=javascript:; class='close fa fa-times' title=Close></a></div></nav><div class=section-container><section></section></div>";
|
||||
html = "<nav><div class=sections-list></div><p class='imp-exp-result warning'></p><div class=credits><a class=export>Export</a> | <a class=import>Import</a> | <a class=reset>Reset Settings</a> | <input type=file hidden><a href='https://github.com/ccd0/4chan-x' target=_blank>4chan X</a> | <a href='https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md' target=_blank>" + g.VERSION + "</a> | <a href='https://github.com/ccd0/4chan-x/issues' target=_blank>Issues</a> | <a href=javascript:; class='close fa fa-times' title=Close></a></div></nav><div class=section-container><section></section></div>";
|
||||
Settings.overlay = overlay = $.el('div', {
|
||||
id: 'overlay'
|
||||
});
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "4chan X",
|
||||
"version": "1.7.2",
|
||||
"version": "1.7.3",
|
||||
"manifest_version": 2,
|
||||
"description": "Cross-browser userscript for maximum lurking on 4chan.",
|
||||
"icons": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// Generated by CoffeeScript
|
||||
/*
|
||||
* 4chan X - Version 1.7.2 - 2014-04-07
|
||||
* 4chan X - Version 1.7.3 - 2014-04-08
|
||||
*
|
||||
* Licensed under the MIT license.
|
||||
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
||||
@ -220,6 +220,7 @@
|
||||
'Fit width': [false, ''],
|
||||
'Fit height': [false, ''],
|
||||
'Expand spoilers': [true, 'Expand all images along with spoilers.'],
|
||||
'Expand videos': [false, 'Expand all images also expands videos (no autoplay).'],
|
||||
'Expand from here': [false, 'Expand all images only from current position to thread end.'],
|
||||
'Advance on contract': [false, 'Advance to next post when contracting an expanded image.']
|
||||
},
|
||||
@ -349,7 +350,7 @@
|
||||
doc = d.documentElement;
|
||||
|
||||
g = {
|
||||
VERSION: '1.7.2',
|
||||
VERSION: '1.7.3',
|
||||
NAMESPACE: '4chan X.',
|
||||
boards: {}
|
||||
};
|
||||
@ -7967,7 +7968,7 @@
|
||||
|
||||
ImageExpand = {
|
||||
init: function() {
|
||||
if (!Conf['Image Expansion']) {
|
||||
if (g.VIEW === 'catalog' || !Conf['Image Expansion']) {
|
||||
return;
|
||||
}
|
||||
this.EAI = $.el('a', {
|
||||
@ -7976,34 +7977,33 @@
|
||||
title: 'Expand All Images',
|
||||
href: 'javascript:;'
|
||||
});
|
||||
$.on(this.EAI, 'click', this.cb.toggleAll);
|
||||
$.on(this.EAI, 'click', ImageExpand.cb.toggleAll);
|
||||
Header.addShortcut(this.EAI, 3);
|
||||
$.on(d, 'scroll visibilitychange', this.cb.playVideos);
|
||||
return Post.callbacks.push({
|
||||
name: 'Image Expansion',
|
||||
cb: this.node
|
||||
});
|
||||
},
|
||||
node: function() {
|
||||
var thumb;
|
||||
if (!(this.file && (this.file.isImage || this.file.isVideo))) {
|
||||
var clone, 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;
|
||||
$.on(thumb.parentNode, 'click', ImageExpand.cb.toggle);
|
||||
if (this.isClone) {
|
||||
if (this.file.isImage && this.file.isExpanding) {
|
||||
ImageExpand.contract(this);
|
||||
ImageExpand.expand(this);
|
||||
return;
|
||||
}
|
||||
if (this.file.isExpanded && this.file.isVideo) {
|
||||
ImageExpand.setupVideoControls(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (ImageExpand.on && !this.isHidden && (Conf['Expand spoilers'] || !this.file.isSpoiler)) {
|
||||
if (this.isClone && $.hasClass(thumb, 'expanding')) {
|
||||
ImageExpand.contract(this);
|
||||
return ImageExpand.expand(this);
|
||||
} else if (this.isClone && this.file.isExpanded && this.file.isVideo) {
|
||||
clone = this;
|
||||
ImageExpand.setupVideoControls(clone);
|
||||
if (!clone.origin.file.fullImage.paused) {
|
||||
return $.queueTask(function() {
|
||||
return ImageExpand.startVideo(clone);
|
||||
});
|
||||
}
|
||||
} else if (ImageExpand.on && !this.isHidden && (Conf['Expand spoilers'] || !this.file.isSpoiler) && (Conf['Expand videos'] || !this.file.isVideo)) {
|
||||
return ImageExpand.expand(this, null, true);
|
||||
}
|
||||
},
|
||||
cb: {
|
||||
@ -8020,53 +8020,40 @@
|
||||
return ImageExpand.toggle(post);
|
||||
},
|
||||
toggleAll: function() {
|
||||
var func;
|
||||
var func, toggle;
|
||||
$.event('CloseMenu');
|
||||
toggle = function(post) {
|
||||
var file;
|
||||
file = post.file;
|
||||
if (!(file && (file.isImage || file.isVideo) && doc.contains(post.nodes.root))) {
|
||||
return;
|
||||
}
|
||||
if (ImageExpand.on && (!Conf['Expand spoilers'] && file.isSpoiler || !Conf['Expand videos'] && file.isVideo || Conf['Expand from here'] && Header.getTopOf(file.thumb) < 0)) {
|
||||
return;
|
||||
}
|
||||
return $.queueTask(func, post);
|
||||
};
|
||||
if (ImageExpand.on = $.hasClass(ImageExpand.EAI, 'expand-all-shortcut')) {
|
||||
ImageExpand.EAI.className = 'contract-all-shortcut fa fa-compress';
|
||||
ImageExpand.EAI.title = 'Contract All Images';
|
||||
func = ImageExpand.expand;
|
||||
func = function(post) {
|
||||
return ImageExpand.expand(post, null, true);
|
||||
};
|
||||
} else {
|
||||
ImageExpand.EAI.className = 'expand-all-shortcut fa fa-expand';
|
||||
ImageExpand.EAI.title = 'Expand All Images';
|
||||
func = ImageExpand.contract;
|
||||
}
|
||||
return g.posts.forEach(function(post) {
|
||||
var file, _i, _len, _ref;
|
||||
_ref = [post].concat(post.clones);
|
||||
var _i, _len, _ref;
|
||||
toggle(post);
|
||||
_ref = post.clones;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
post = _ref[_i];
|
||||
file = post.file;
|
||||
if (!(file && (file.isImage || file.isVideo) && doc.contains(post.nodes.root))) {
|
||||
return;
|
||||
}
|
||||
if (ImageExpand.on && (post.isHidden || !Conf['Expand spoilers'] && post.file.isSpoiler || !doc.contains(post.nodes.root) || Conf['Expand from here'] && Header.getTopOf(post.file.thumb) < 0)) {
|
||||
return;
|
||||
}
|
||||
$.queueTask(func, post);
|
||||
toggle(post);
|
||||
}
|
||||
});
|
||||
},
|
||||
playVideos: function(e) {
|
||||
var fullID, play, post, _i, _len, _ref, _ref1;
|
||||
_ref = g.posts;
|
||||
for (fullID in _ref) {
|
||||
post = _ref[fullID];
|
||||
if (!(post.file && post.file.isVideo && post.file.isExpanded)) {
|
||||
continue;
|
||||
}
|
||||
_ref1 = [post].concat(post.clones);
|
||||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
||||
post = _ref1[_i];
|
||||
play = !d.hidden && !post.isHidden && doc.contains(post.nodes.root) && Header.isNodeVisible(post.nodes.root);
|
||||
if (play) {
|
||||
post.file.fullImage.play();
|
||||
} else {
|
||||
post.file.fullImage.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
setFitness: function() {
|
||||
return (this.checked ? $.addClass : $.rmClass)(doc, this.name.toLowerCase().replace(/\s+/g, '-'));
|
||||
}
|
||||
@ -8074,7 +8061,7 @@
|
||||
toggle: function(post) {
|
||||
var headRect, left, root, thumb, top, x, y, _ref;
|
||||
thumb = post.file.thumb;
|
||||
if (!(post.file.isExpanded || post.file.isExpanding)) {
|
||||
if (!(post.file.isExpanded || $.hasClass(thumb, 'expanding'))) {
|
||||
ImageExpand.expand(post);
|
||||
return;
|
||||
}
|
||||
@ -8122,10 +8109,9 @@
|
||||
}
|
||||
$.rmClass(post.nodes.root, 'expanded-image');
|
||||
$.rmClass(post.file.thumb, 'expanding');
|
||||
delete post.file.isExpanding;
|
||||
return post.file.isExpanded = false;
|
||||
},
|
||||
expand: function(post, src) {
|
||||
expand: function(post, src, disableAutoplay) {
|
||||
var el, isVideo, thumb, _ref;
|
||||
_ref = post.file, thumb = _ref.thumb, isVideo = _ref.isVideo;
|
||||
if (post.isHidden || post.file.isExpanded || $.hasClass(thumb, 'expanding')) {
|
||||
@ -8148,42 +8134,49 @@
|
||||
$.after(thumb, el);
|
||||
}
|
||||
return $.asap((function() {
|
||||
return el.videoHeight || el.naturalHeight;
|
||||
if (isVideo) {
|
||||
return el.videoHeight;
|
||||
} else {
|
||||
return el.naturalHeight;
|
||||
}
|
||||
}), function() {
|
||||
return ImageExpand.completeExpand(post);
|
||||
return ImageExpand.completeExpand(post, disableAutoplay);
|
||||
});
|
||||
},
|
||||
completeExpand: function(post) {
|
||||
var bottom, complete, thumb;
|
||||
completeExpand: function(post, disableAutoplay) {
|
||||
var bottom, thumb;
|
||||
thumb = post.file.thumb;
|
||||
if (!$.hasClass(thumb, 'expanding')) {
|
||||
return;
|
||||
}
|
||||
delete post.file.isExpanding;
|
||||
post.file.isExpanded = true;
|
||||
complete = function() {
|
||||
$.addClass(post.nodes.root, 'expanded-image');
|
||||
$.rmClass(post.file.thumb, 'expanding');
|
||||
if (post.file.isVideo) {
|
||||
return ImageExpand.setupVideo(post);
|
||||
}
|
||||
};
|
||||
if (!post.nodes.root.parentNode) {
|
||||
complete();
|
||||
ImageExpand.completeExpand2(post);
|
||||
return;
|
||||
}
|
||||
if (post.file.isVideo && !d.hidden && Header.isNodeVisible(post.nodes.root)) {
|
||||
post.file.fullImage.play();
|
||||
}
|
||||
bottom = post.nodes.root.getBoundingClientRect().bottom;
|
||||
return $.queueTask(function() {
|
||||
complete();
|
||||
ImageExpand.completeExpand2(post, disableAutoplay);
|
||||
if (!(bottom <= 0)) {
|
||||
return;
|
||||
}
|
||||
return window.scrollBy(0, post.nodes.root.getBoundingClientRect().bottom - bottom);
|
||||
});
|
||||
},
|
||||
completeExpand2: function(post, disableAutoplay) {
|
||||
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) {
|
||||
ImageExpand.setupVideoControls(post);
|
||||
post.file.fullImage.muted = !Conf['Allow Sound'];
|
||||
post.file.fullImage.controls = Conf['Show Controls'];
|
||||
if (Conf['Autoplay'] && !disableAutoplay) {
|
||||
return ImageExpand.startVideo(post);
|
||||
}
|
||||
}
|
||||
},
|
||||
videoCB: {
|
||||
click: function(e) {
|
||||
if (this.paused && !this.controls) {
|
||||
@ -8238,34 +8231,29 @@
|
||||
}
|
||||
return $.add(file.text, file.videoControls);
|
||||
},
|
||||
setupVideo: function(post) {
|
||||
var file, video;
|
||||
ImageExpand.setupVideoControls(post);
|
||||
startVideo: function(post) {
|
||||
var controls, file, video;
|
||||
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']) {
|
||||
return $.asap((function() {
|
||||
return (video.readyState >= 3 && video.currentTime <= Math.max(0.1, video.duration - 0.5)) || !file.isExpanded;
|
||||
}), function() {
|
||||
if (file.isExpanded) {
|
||||
return video.controls = true;
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
controls = video.controls;
|
||||
video.controls = false;
|
||||
video.play();
|
||||
if (controls) {
|
||||
return $.asap((function() {
|
||||
return (video.readyState >= 3 && video.currentTime <= Math.max(0.1, video.duration - 0.5)) || !file.isExpanded;
|
||||
}), function() {
|
||||
if (file.isExpanded) {
|
||||
return video.controls = true;
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
var URL, post, src, timeoutID;
|
||||
post = Get.postFromNode(this);
|
||||
post.file.isReady = false;
|
||||
$.rm(this);
|
||||
delete post.file.fullImage;
|
||||
if (!(post.file.isExpanding || post.file.isExpanded)) {
|
||||
if (!($.hasClass(post.file.thumb, 'expanding') || $.hasClass(post.nodes.root, 'expanded-image'))) {
|
||||
return;
|
||||
}
|
||||
ImageExpand.contract(post);
|
||||
@ -8284,7 +8272,7 @@
|
||||
}
|
||||
}
|
||||
timeoutID = setTimeout(ImageExpand.expand, 10000, post);
|
||||
return $.ajax(post.file.URL, {
|
||||
return $.ajax(this.src, {
|
||||
onloadend: function() {
|
||||
if (this.status !== 404) {
|
||||
return;
|
||||
@ -8299,7 +8287,7 @@
|
||||
menu: {
|
||||
init: function() {
|
||||
var conf, createSubEntry, el, name, subEntries, _ref;
|
||||
if (!Conf['Image Expansion']) {
|
||||
if (g.VIEW === 'catalog' || !Conf['Image Expansion']) {
|
||||
return;
|
||||
}
|
||||
el = $.el('span', {
|
||||
@ -12985,7 +12973,7 @@
|
||||
return;
|
||||
}
|
||||
$.event('CloseMenu');
|
||||
html = "<nav><div class=sections-list></div><p class='imp-exp-result warning'></p><div class=credits><a class=export>Export</a> | <a class=import>Import</a> | <a class=reset>Reset Settings</a> | <input type=file hidden><a href='https://github.com/ccd0/4chan-x' target=_blank>4chan X</a> |<a href='https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md' target=_blank>" + g.VERSION + "</a> |<a href='https://github.com/ccd0/4chan-x/blob/master/README.md#reporting-bugs-and-suggestions' target=_blank>Issues</a> |<a href=javascript:; class='close fa fa-times' title=Close></a></div></nav><div class=section-container><section></section></div>";
|
||||
html = "<nav><div class=sections-list></div><p class='imp-exp-result warning'></p><div class=credits><a class=export>Export</a> | <a class=import>Import</a> | <a class=reset>Reset Settings</a> | <input type=file hidden><a href='https://github.com/ccd0/4chan-x' target=_blank>4chan X</a> | <a href='https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md' target=_blank>" + g.VERSION + "</a> | <a href='https://github.com/ccd0/4chan-x/issues' target=_blank>Issues</a> | <a href=javascript:; class='close fa fa-times' title=Close></a></div></nav><div class=section-container><section></section></div>";
|
||||
Settings.overlay = overlay = $.el('div', {
|
||||
id: 'overlay'
|
||||
});
|
||||
|
||||
@ -1,7 +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.7.2' />
|
||||
<updatecheck codebase='https://ccd0.github.io/4chan-x/builds/crx.crx' version='1.7.3' />
|
||||
</app>
|
||||
</gupdate>
|
||||
|
||||
|
||||
@ -1 +1 @@
|
||||
postMessage({version:'1.7.2'},'*')
|
||||
postMessage({version:'1.7.3'},'*')
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "4chan-X",
|
||||
"version": "1.7.2",
|
||||
"version": "1.7.3",
|
||||
"description": "Cross-browser userscript for maximum lurking on 4chan.",
|
||||
"meta": {
|
||||
"name": "4chan X",
|
||||
|
||||
@ -409,6 +409,10 @@ Config =
|
||||
true
|
||||
'Expand all images along with spoilers.'
|
||||
]
|
||||
'Expand videos': [
|
||||
false
|
||||
'Expand all images also expands videos (no autoplay).'
|
||||
]
|
||||
'Expand from here': [
|
||||
false
|
||||
'Expand all images only from current position to thread end.'
|
||||
|
||||
@ -6,10 +6,10 @@
|
||||
<a class=import>Import</a> | 
|
||||
<a class=reset>Reset Settings</a> | 
|
||||
<input type=file hidden>
|
||||
<a href='<%= meta.page %>' target=_blank><%= meta.name %></a> |
|
||||
<a href='<%= meta.repo %>blob/<%= meta.mainBranch %>/CHANGELOG.md' target=_blank>#{g.VERSION}</a> |
|
||||
<a href='<%= meta.repo %>blob/<%= meta.mainBranch %>/README.md#reporting-bugs-and-suggestions' target=_blank>Issues</a> |
|
||||
<a href='<%= meta.page %>' target=_blank><%= meta.name %></a> | 
|
||||
<a href='<%= meta.repo %>blob/<%= meta.mainBranch %>/CHANGELOG.md' target=_blank>#{g.VERSION}</a> | 
|
||||
<a href='<%= meta.repo %>issues' target=_blank>Issues</a> | 
|
||||
<a href=javascript:; class='close fa fa-times' title=Close></a>
|
||||
</div>
|
||||
</nav>
|
||||
<div class=section-container><section></section></div>
|
||||
<div class=section-container><section></section></div>
|
||||
|
||||
@ -1,37 +1,36 @@
|
||||
ImageExpand =
|
||||
init: ->
|
||||
return if !Conf['Image Expansion']
|
||||
return if g.VIEW is 'catalog' or !Conf['Image Expansion']
|
||||
|
||||
@EAI = $.el 'a',
|
||||
className: 'expand-all-shortcut fa fa-expand'
|
||||
textContent: 'EAI'
|
||||
title: 'Expand All Images'
|
||||
href: 'javascript:;'
|
||||
$.on @EAI, 'click', @cb.toggleAll
|
||||
$.on @EAI, 'click', ImageExpand.cb.toggleAll
|
||||
Header.addShortcut @EAI, 3
|
||||
$.on d, 'scroll visibilitychange', @cb.playVideos
|
||||
|
||||
Post.callbacks.push
|
||||
name: 'Image Expansion'
|
||||
cb: @node
|
||||
|
||||
node: ->
|
||||
return unless @file and (@file.isImage or @file.isVideo)
|
||||
return unless @file?.isImage or @file?.isVideo
|
||||
{thumb} = @file
|
||||
$.on thumb.parentNode, 'click', ImageExpand.cb.toggle
|
||||
if @isClone
|
||||
if @file.isImage and @file.isExpanding
|
||||
# If we clone a post where the image is still loading,
|
||||
# make it loading in the clone too.
|
||||
ImageExpand.contract @
|
||||
ImageExpand.expand @
|
||||
return
|
||||
if @file.isExpanded and @file.isVideo
|
||||
ImageExpand.setupVideoControls @
|
||||
return
|
||||
if ImageExpand.on and !@isHidden and (Conf['Expand spoilers'] or !@file.isSpoiler)
|
||||
if @isClone and $.hasClass thumb, 'expanding'
|
||||
# If we clone a post where the image is still loading,
|
||||
# make it loading in the clone too.
|
||||
ImageExpand.contract @
|
||||
ImageExpand.expand @
|
||||
|
||||
else if @isClone and @file.isExpanded and @file.isVideo
|
||||
clone = @
|
||||
ImageExpand.setupVideoControls clone
|
||||
unless clone.origin.file.fullImage.paused
|
||||
$.queueTask -> ImageExpand.startVideo clone
|
||||
else if ImageExpand.on and !@isHidden and
|
||||
(Conf['Expand spoilers'] or !@file.isSpoiler) and
|
||||
(Conf['Expand videos'] or !@file.isVideo)
|
||||
ImageExpand.expand @, null, true
|
||||
cb:
|
||||
toggle: (e) ->
|
||||
return if e.shiftKey or e.altKey or e.ctrlKey or e.metaKey or e.button isnt 0
|
||||
@ -42,42 +41,36 @@ ImageExpand =
|
||||
|
||||
toggleAll: ->
|
||||
$.event 'CloseMenu'
|
||||
toggle = (post) ->
|
||||
{file} = post
|
||||
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 videos'] and file.isVideo or
|
||||
Conf['Expand from here'] and Header.getTopOf(file.thumb) < 0)
|
||||
return
|
||||
$.queueTask func, post
|
||||
|
||||
if ImageExpand.on = $.hasClass ImageExpand.EAI, 'expand-all-shortcut'
|
||||
ImageExpand.EAI.className = 'contract-all-shortcut fa fa-compress'
|
||||
ImageExpand.EAI.title = 'Contract All Images'
|
||||
func = ImageExpand.expand
|
||||
func = (post) -> ImageExpand.expand post, null, true
|
||||
else
|
||||
ImageExpand.EAI.className = 'expand-all-shortcut fa fa-expand'
|
||||
ImageExpand.EAI.title = 'Expand All Images'
|
||||
func = ImageExpand.contract
|
||||
|
||||
g.posts.forEach (post) ->
|
||||
for post in [post].concat post.clones
|
||||
{file} = post
|
||||
return unless file and (file.isImage or file.isVideo) and doc.contains post.nodes.root
|
||||
if ImageExpand.on and (
|
||||
post.isHidden or
|
||||
!Conf['Expand spoilers'] and post.file.isSpoiler or
|
||||
!doc.contains(post.nodes.root) or
|
||||
Conf['Expand from here'] and Header.getTopOf(post.file.thumb) < 0)
|
||||
return
|
||||
$.queueTask func, post
|
||||
toggle post
|
||||
toggle post for post in post.clones
|
||||
return
|
||||
|
||||
playVideos: (e) ->
|
||||
for fullID, post of g.posts
|
||||
continue unless post.file and post.file.isVideo and post.file.isExpanded
|
||||
for post in [post].concat post.clones
|
||||
play = !d.hidden and !post.isHidden and doc.contains(post.nodes.root) and Header.isNodeVisible post.nodes.root
|
||||
if play then post.file.fullImage.play() else post.file.fullImage.pause()
|
||||
return
|
||||
|
||||
setFitness: ->
|
||||
(if @checked then $.addClass else $.rmClass) doc, @name.toLowerCase().replace /\s+/g, '-'
|
||||
|
||||
toggle: (post) ->
|
||||
{thumb} = post.file
|
||||
unless post.file.isExpanded or post.file.isExpanding
|
||||
unless post.file.isExpanded or $.hasClass thumb, 'expanding'
|
||||
ImageExpand.expand post
|
||||
return
|
||||
|
||||
@ -117,10 +110,9 @@ ImageExpand =
|
||||
delete post.file.videoControls
|
||||
$.rmClass post.nodes.root, 'expanded-image'
|
||||
$.rmClass post.file.thumb, 'expanding'
|
||||
delete post.file.isExpanding
|
||||
post.file.isExpanded = false
|
||||
|
||||
expand: (post, src) ->
|
||||
expand: (post, src, disableAutoplay) ->
|
||||
# Do not expand images of hidden/filtered replies, or already expanded pictures.
|
||||
{thumb, isVideo} = post.file
|
||||
return if post.isHidden or post.file.isExpanded or $.hasClass thumb, 'expanding'
|
||||
@ -135,33 +127,34 @@ ImageExpand =
|
||||
$.on el, 'error', ImageExpand.error
|
||||
el.src = src or post.file.URL
|
||||
$.after thumb, el unless el is thumb.nextSibling
|
||||
$.asap (-> el.videoHeight or el.naturalHeight), ->
|
||||
ImageExpand.completeExpand post
|
||||
$.asap (-> if isVideo then el.videoHeight else el.naturalHeight), ->
|
||||
ImageExpand.completeExpand post, disableAutoplay
|
||||
|
||||
completeExpand: (post) ->
|
||||
completeExpand: (post, disableAutoplay) ->
|
||||
{thumb} = post.file
|
||||
return unless $.hasClass thumb, 'expanding' # contracted before the image loaded
|
||||
delete post.file.isExpanding
|
||||
post.file.isExpanded = true
|
||||
|
||||
complete = ->
|
||||
$.addClass post.nodes.root, 'expanded-image'
|
||||
$.rmClass post.file.thumb, 'expanding'
|
||||
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.
|
||||
complete()
|
||||
ImageExpand.completeExpand2 post
|
||||
return
|
||||
|
||||
post.file.fullImage.play() if post.file.isVideo and !d.hidden and Header.isNodeVisible post.nodes.root
|
||||
{bottom} = post.nodes.root.getBoundingClientRect()
|
||||
$.queueTask ->
|
||||
complete()
|
||||
ImageExpand.completeExpand2 post, disableAutoplay
|
||||
return unless bottom <= 0
|
||||
window.scrollBy 0, post.nodes.root.getBoundingClientRect().bottom - bottom
|
||||
|
||||
completeExpand2: (post, disableAutoplay) ->
|
||||
{thumb} = post.file
|
||||
$.addClass post.nodes.root, 'expanded-image'
|
||||
$.rmClass post.file.thumb, 'expanding'
|
||||
post.file.isExpanded = true
|
||||
if post.file.isVideo
|
||||
ImageExpand.setupVideoControls post
|
||||
post.file.fullImage.muted = !Conf['Allow Sound']
|
||||
post.file.fullImage.controls = Conf['Show Controls']
|
||||
ImageExpand.startVideo post if Conf['Autoplay'] and not disableAutoplay
|
||||
|
||||
videoCB:
|
||||
click: (e) ->
|
||||
if @paused and not @controls
|
||||
@ -170,9 +163,9 @@ ImageExpand =
|
||||
|
||||
# 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
|
||||
mouseup: (e) -> @dataset.mousedown = 'false' if e.button is 0
|
||||
mouseover: (e) -> @dataset.mousedown = 'false'
|
||||
mouseout: (e) ->
|
||||
mouseout: (e) ->
|
||||
if @dataset.mousedown is 'true' and e.clientX <= @getBoundingClientRect().left
|
||||
ImageExpand.contract (Get.postFromNode @)
|
||||
|
||||
@ -200,30 +193,26 @@ ImageExpand =
|
||||
$.add file.videoControls, [$.tn('\u00A0'), contract]
|
||||
$.add file.text, file.videoControls
|
||||
|
||||
setupVideo: (post) ->
|
||||
ImageExpand.setupVideoControls post
|
||||
startVideo: (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 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
|
||||
{controls} = video
|
||||
video.controls = false
|
||||
video.play()
|
||||
# Hacky workaround for Firefox forever-loading bug for very short videos
|
||||
if 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
|
||||
|
||||
error: ->
|
||||
post = Get.postFromNode @
|
||||
post.file.isReady = false
|
||||
$.rm @
|
||||
delete post.file.fullImage
|
||||
# Images can error:
|
||||
# - before the image started loading.
|
||||
# - after the image started loading.
|
||||
unless post.file.isExpanding or post.file.isExpanded
|
||||
unless $.hasClass(post.file.thumb, 'expanding') or $.hasClass post.nodes.root, 'expanded-image'
|
||||
# Don't try to re-expend if it was already contracted.
|
||||
return
|
||||
ImageExpand.contract post
|
||||
@ -241,7 +230,7 @@ ImageExpand =
|
||||
|
||||
timeoutID = setTimeout ImageExpand.expand, 10000, post
|
||||
<% if (type === 'crx') { %>
|
||||
$.ajax post.file.URL,
|
||||
$.ajax @src,
|
||||
onloadend: ->
|
||||
return if @status isnt 404
|
||||
clearTimeout timeoutID
|
||||
@ -264,7 +253,7 @@ ImageExpand =
|
||||
|
||||
menu:
|
||||
init: ->
|
||||
return if !Conf['Image Expansion']
|
||||
return if g.VIEW is 'catalog' or !Conf['Image Expansion']
|
||||
|
||||
el = $.el 'span',
|
||||
textContent: 'Image Expansion'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user