Skip to content

Instantly share code, notes, and snippets.

@felixfong227
Last active September 1, 2019 05:38
Show Gist options
  • Save felixfong227/2eb443635952b763c356ebca1ae5d00b to your computer and use it in GitHub Desktop.
Save felixfong227/2eb443635952b763c356ebca1ae5d00b to your computer and use it in GitHub Desktop.
// 1.3.0
'use strict';
var APP_NAME_SPACE = 'ext_e621_helper';
// Credit: https://stackoverflow.com/a/4379864
function getNextSiblings(elem, filter) {
var sibs = [];
while (elem = elem.nextSibling) {
if (elem.nodeType === 3) continue; // text node
if (!filter || filter(elem)) sibs.push(elem);
}
return sibs;
}
// credit: https://davidwalsh.name/javascript-debounce-function
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
function errLocateEl(elID) {
if(!elID) throw new Error('Missing argument elID');
console.error('[E621 Helper] Fail to locate ' + elID +' element');
}
function nameSpaceFormat(name) {
return APP_NAME_SPACE + "_" + name;
}
function saveOption(opt) {
if(!opt) throw new Error('No option object are given');
if(typeof opt !== 'object') throw new Error('Argument opt must be typeof object');
window.localStorage.settItem( nameSpaceFormat('options'), JSON.stringify(opt));
}
function getOption() {
var optStr = window.localStorage.getItem( nameSpaceFormat('options') );
// Return a JSON object
if(optStr) return JSON.parse(optStr);
// Return null
return optStr;
}
// All case handlers
// Post handlers
function handler_post_imgOnClickNewScreen(event) {
var target = event.target;
if(target.tagName === 'IMG') {
var pageURL = target.parentElement.href;
// Users is indeed clicking on an image element OwO
window.open(pageURL);
return event.preventDefault();
}
}
function favClick(el) {
el.querySelector('a').click();
}
var previewButton = document.querySelector('input[type=button][value=Preview]');
var postCommentBox = document.querySelector('textarea[id^=reply-text]');
var livePreviewButtonPress = debounce(function() {
if(previewButton) previewButton.click();
}, 500);
let cache_beforeFocusWidth = null;
// var options = {
// openInNewTab: true,
// autoPlayVid: true,
// };
// Add hotkey to the page
window.addEventListener('keydown', function(e) {
var currentActiveElm = document.activeElement.tagName;
if(currentActiveElm === 'INPUT' || currentActiveElm === 'TEXTAREA' || currentActiveElm.contentEditable == "true" || currentActiveElm.contentEditable === true) return 0;
switch(e.key) {
case 'f': {
// Fav/unfavorite that post
// Check if this page support fav and unfav action
var favButtons = [document.querySelector('#add-to-favs'), document.querySelector('#remove-from-favs')];
var favAble = favButtons[0] !== null && favButtons[1] !== null;
if(favAble) {
// This page does support "favorite" action
// Check if this post fav's status
var isUnFav = favButtons[1].style.display === 'none';
isUnFav === true ? favClick(favButtons[0]) : favClick(favButtons[1]);
isUnFav = !isUnFav;
}
break;
}
case 'F': {
// Toggle "Focus Mode"
var elms = [
// The website side bar
document.querySelector('.sidebar'),
// The comment session for this post
document.querySelector('#comments'),
// Website header
document.querySelector('#header'),
// The news banner
document.querySelector('#news'),
// Ads
document.querySelector('#ad-leaderboard'),
// All notifications
document.querySelector('#notices'),
// Pending notify bar
document.querySelector('#pending-notice'),
];
// NOTE: Video will soon be supported
var theImage = document.querySelector('#image');
var editButton = document.querySelector('[name=edit]');
if(editButton) {
// Media bar and descriptions
var mediaBar = editButton.previousElementSibling;
elms.push(
mediaBar,
mediaBar.previousElementSibling,
);
}
for(var index = 0; index < elms.length; index++) Utils.toggleDisplayNone(elms[index]);
// Move the image to the the cetenr of the screen
if(theImage) {
// Save the origin size for resotring the the normal look of the web page
if(cache_beforeFocusWidth === null) cache_beforeFocusWidth = theImage.width;
theImage.parentElement.style.width = theImage.parentElement.style.width === '100vw' ? 'auto' : '100vw';
theImage.style.left = theImage.style.left === '50%' ? 'auto' : '50%';
theImage.style.transform = theImage.style.transform == 'translateX(-50%)' ? 'none' : 'translateX(-50%)' ;
theImage.style.position = theImage.style.position === 'relative' ? 'initial' : 'relative';
theImage.style.width = theImage.style.width === '35%' ? cache_beforeFocusWidth + 'px' : '35%';
}
}
}
});
// Live preview for comment box
if(postCommentBox) postCommentBox.addEventListener('keydown', livePreviewButtonPress);
var quickEditEl = document.querySelector('#quick-edit');
if(quickEditEl) {
var postsDiv = getNextSiblings(quickEditEl);
if(postsDiv && postsDiv[0]) {
var target = postsDiv[0];
target.addEventListener('click', handler_post_imgOnClickNewScreen);
} else {
errLocateEl('The Posts Container Element');
}
} else {
// errLocateEl('#quick-edit');
}
// ==UserScript==
// @name e621.net Helper
// @namespace RainbowTheDashie
// @version 1.2.0
// @description Little util script to help make e621.net a much better place then it already is :P
// @author RainbowTheDashie
// @match https://e621.net/post/*
// @match http://e621.net/post/*
// @match https://e621.net/post
// @match http://e621.net/post
// @grant none
// ==/UserScript==
(function(){
var Utils = {
errorConsole: function(msg) {
if(msg) console.error('[e621.net Helper Utils Error] ' + msg);
},
_notifyConstru(opertor, msg, prefix) {
if(!opertor) throw new Error('Missing argument operator OwO');
var prefixMsg = '[e621.net Helper] ';
if(prefix === null || prefix === false) prefixMsg = '';
if(window[opertor] && typeof window.notice === 'function') return window[opertor].call(null, prefixMsg + msg);
return Utils.error('window.notice is not a valid function any more QvQ, WHYYYYYY DEV FROM E621!!!!!!!!!!!!!');
},
notice: function(msg, prefix) {
Utils._notifyConstru('notice', msg, prefix)
},
error: function(msg, prefix) {
Utils._notifyConstru('error', msg, prefix);
},
toggleDisplayNone(elm) {
elm.style.display = elm.style.display === 'none' ? '' : 'none';
}
};
try {
ext_e621_helper_MAIN(Utils);
} catch (err) {
console.error('[e621.net Helper Global Error]', err);
}
})();
function ext_e621_helper_MAIN(Utils) {
'use strict';
var APP_NAME_SPACE = 'ext_e621_helper';
// Credit: https://stackoverflow.com/a/4379864
function getNextSiblings(elem, filter) {
var sibs = [];
while (elem = elem.nextSibling) {
if (elem.nodeType === 3) continue; // text node
if (!filter || filter(elem)) sibs.push(elem);
}
return sibs;
}
// credit: https://davidwalsh.name/javascript-debounce-function
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
function errLocateEl(elID) {
if(!elID) throw new Error('Missing argument elID');
console.error('[E621 Helper] Fail to locate ' + elID +' element');
}
function nameSpaceFormat(name) {
return APP_NAME_SPACE + "_" + name;
}
function saveOption(opt) {
if(!opt) throw new Error('No option object are given');
if(typeof opt !== 'object') throw new Error('Argument opt must be typeof object');
window.localStorage.settItem( nameSpaceFormat('options'), JSON.stringify(opt));
}
function getOption() {
var optStr = window.localStorage.getItem( nameSpaceFormat('options') );
// Return a JSON object
if(optStr) return JSON.parse(optStr);
// Return null
return optStr;
}
// All case handlers
// Post handlers
function handler_post_imgOnClickNewScreen(event) {
var target = event.target;
if(target.tagName === 'IMG') {
var pageURL = target.parentElement.href;
// Users is indeed clicking on an image element OwO
window.open(pageURL);
return event.preventDefault();
}
}
function favClick(el) {
el.querySelector('a').click();
}
var previewButton = document.querySelector('input[type=button][value=Preview]');
var postCommentBox = document.querySelector('textarea[id^=reply-text]');
var livePreviewButtonPress = debounce(function() {
if(previewButton) previewButton.click();
}, 500);
let cache_beforeFocusWidth = null;
// var options = {
// openInNewTab: true,
// autoPlayVid: true,
// };
// Add hotkey to the page
window.addEventListener('keydown', function(e) {
var currentActiveElm = document.activeElement.tagName;
if(currentActiveElm === 'INPUT' || currentActiveElm === 'TEXTAREA' || currentActiveElm.contentEditable == "true" || currentActiveElm.contentEditable === true) return 0;
switch(e.key) {
case 'f': {
// Fav/unfavorite that post
// Check if this page support fav and unfav action
var favButtons = [document.querySelector('#add-to-favs'), document.querySelector('#remove-from-favs')];
var favAble = favButtons[0] !== null && favButtons[1] !== null;
if(favAble) {
// This page does support "favorite" action
// Check if this post fav's status
var isUnFav = favButtons[1].style.display === 'none';
isUnFav === true ? favClick(favButtons[0]) : favClick(favButtons[1]);
isUnFav = !isUnFav;
}
break;
}
case 'F': {
// Toggle "Focus Mode"
var elms = [
// The website side bar
document.querySelector('.sidebar'),
// The comment session for this post
document.querySelector('#comments'),
// Website header
document.querySelector('#header'),
// The news banner
document.querySelector('#news'),
// Ads
document.querySelector('#ad-leaderboard'),
// All notifications
document.querySelector('#notices'),
// Pending notify bar
document.querySelector('#pending-notice'),
];
// NOTE: Video will soon be supported
var theImage = document.querySelector('#image');
var editButton = document.querySelector('[name=edit]');
if(editButton) {
// Media bar and descriptions
var mediaBar = editButton.previousElementSibling;
elms.push(
mediaBar,
mediaBar.previousElementSibling,
);
}
for(var index = 0; index < elms.length; index++) Utils.toggleDisplayNone(elms[index]);
// Move the image to the the cetenr of the screen
if(theImage) {
// Save the origin size for resotring the the normal look of the web page
if(cache_beforeFocusWidth === null) cache_beforeFocusWidth = theImage.width;
theImage.parentElement.style.width = theImage.parentElement.style.width === '100vw' ? 'auto' : '100vw';
theImage.style.left = theImage.style.left === '50%' ? 'auto' : '50%';
theImage.style.transform = theImage.style.transform == 'translateX(-50%)' ? 'none' : 'translateX(-50%)' ;
theImage.style.position = theImage.style.position === 'relative' ? 'initial' : 'relative';
theImage.style.width = theImage.style.width === '35%' ? cache_beforeFocusWidth + 'px' : '35%';
}
}
}
});
// Live preview for comment box
if(postCommentBox) postCommentBox.addEventListener('keydown', livePreviewButtonPress);
var quickEditEl = document.querySelector('#quick-edit');
if(quickEditEl) {
var postsDiv = getNextSiblings(quickEditEl);
if(postsDiv && postsDiv[0]) {
var target = postsDiv[0];
target.addEventListener('click', handler_post_imgOnClickNewScreen);
} else {
errLocateEl('The Posts Container Element');
}
} else {
// errLocateEl('#quick-edit');
}
}
// All custom effects for the webpage
var warpBefore = false;
var Effects = {
instagramLike(elm, isLike) {
if(typeof isLike === 'undefined') isLike = true;
if(elm) {
var canvasTargetPoint = document.createElement('div');
var wrapper = document.createElement('div');
canvasTargetPoint.id = 'ext_e621_helper_like_canvas';
canvasTargetPoint.style.position = 'absolute';
canvasTargetPoint.style.top = '50%';
canvasTargetPoint.style.left = '50%';
canvasTargetPoint.style.width = '20%';
if(!warpBefore) {
wrapper.className = 'ext_e621_helper_like_overlay_container';
wrapper.style.position = 'relative';
elm.parentNode.insertBefore(wrapper, elm);
wrapper.appendChild(elm);
warpBefore = true;
}
elm.parentNode.insertBefore(canvasTargetPoint, elm);
if(isLike) {
// Show like animation
bodymovin.loadAnimation({
container: canvasTargetPoint,
renderer: 'svg',
loop: true,
autoplay: true,
path: 'https://assets5.lottiefiles.com/datafiles/d9bc9kYC2VttaKb/data.json'
});
} else {
// Show heart broken animation
bodymovin.loadAnimation({
container: canvasTargetPoint,
renderer: 'svg',
loop: true,
autoplay: true,
path: 'https://assets5.lottiefiles.com/datafiles/tdCLmdmRpULFtsT/data.json',
}).setSpeed(2.5)
}
setTimeout(function() {
canvasTargetPoint.remove();
}, 1000)
}
}
}
// ==UserScript==
// @name e621.net Helper
// @namespace RainbowTheDashie
// @version 1.0.0
// @description Little util script to help make e621.net a much better place then it already is :P
// @author RainbowTheDashie
// @match https://e621.net/post/*
// @match http://e621.net/post/*
// @match https://e621.net/post
// @match http://e621.net/post
// @run-at document-end
// @require Utils.js
// @require Effects.js
// @require https://cdnjs.cloudflare.com/ajax/libs/bodymovin/4.4.27/bodymovin.min.js
// @require https://unpkg.com/tocca@2.0.4/Tocca.min.js
// ==/UserScript==
window.tocca({
useJquery: false
});
'use strict';
var APP_NAME_SPACE = 'ext_e621_helper';
// credit: https://davidwalsh.name/javascript-debounce-function
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
function errLocateEl(elID) {
if(!elID) throw new Error('Missing argument elID');
console.error('[E621 Helper] Fail to locate ' + elID +' element');
}
function nameSpaceFormat(name) {
return APP_NAME_SPACE + "_" + name;
}
function saveOption(opt) {
if(!opt) throw new Error('No option object are given');
if(typeof opt !== 'object') throw new Error('Argument opt must be typeof object');
window.localStorage.settItem( nameSpaceFormat('options'), JSON.stringify(opt));
}
function getOption() {
var optStr = window.localStorage.getItem( nameSpaceFormat('options') );
// Return a JSON object
if(optStr) return JSON.parse(optStr);
// Return null
return optStr;
}
// All case handlers
// Post handlers
function handler_post_imgOnClickNewScreen(event) {
var target = event.target;
if(target.tagName === 'IMG') {
var pageURL = target.parentElement.href;
// Users is indeed clicking on an image element OwO
window.open(pageURL);
return event.preventDefault();
}
}
function favClick(el) {
el.querySelector('a').click();
}
var previewButton = document.querySelector('input[type=button][value=Preview]');
var postCommentBox = document.querySelector('textarea[id^=reply-text]');
var livePreviewButtonPress = debounce(function() {
if(previewButton) previewButton.click();
}, 500);
let cache_beforeFocusWidth = null;
function likeThisPost() {
// Fav/unfavorite that post
// Check if this page support fav and unfav action
var favButtons = [document.querySelector('#add-to-favs'), document.querySelector('#remove-from-favs')];
var favAble = favButtons[0] !== null && favButtons[1] !== null;
if(favAble) {
// This page does support "favorite" action
// Check if this post fav's status
var isUnFav = favButtons[1].style.display === 'none';
isUnFav === true ? favClick(favButtons[0]) : favClick(favButtons[1]);
isUnFav = !isUnFav;
}
return isUnFav;
}
var theImage = document.querySelector('#image');
// var options = {
// openInNewTab: true,
// autoPlayVid: true,
// };
// Add hotkey to the page
window.addEventListener('keydown', function(e) {
var currentActiveElm = document.activeElement.tagName;
if(currentActiveElm === 'INPUT' || currentActiveElm === 'TEXTAREA' || currentActiveElm.contentEditable == "true" || currentActiveElm.contentEditable === true) return 0;
switch(e.key) {
case 'f': {
// Cancel action if either CTRL or CMD key are pressed as well
if(event.ctrlKey || event.metaKey) return false;
// Otherwise like the post
likeThisPost();
break;
}
case 'F': {
// Toggle "Focus Mode"
var elms = [
// The website side bar
document.querySelector('.sidebar'),
// The comment session for this post
document.querySelector('#comments'),
// Website header
document.querySelector('#header'),
// The news banner
document.querySelector('#news'),
// Ads
document.querySelector('#ad-leaderboard'),
// All notifications
document.querySelector('#notices'),
// Pending notify bar
document.querySelector('#pending-notice'),
];
// NOTE: Video will soon be supported
var editButton = document.querySelector('[name=edit]');
if(editButton) {
// Media bar and descriptions
var mediaBar = editButton.previousElementSibling;
elms.push(
mediaBar,
mediaBar.previousElementSibling,
);
}
// Move the image to the the cetenr of the screen
try {
for(var index = 0; index < elms.length; index++) Utils.toggleDisplayNone(elms[index]);
if(theImage) {
// Save the origin size for resotring the the normal look of the web page
if(cache_beforeFocusWidth === null) cache_beforeFocusWidth = theImage.width;
theImage.parentElement.style.width = theImage.parentElement.style.width === '100vw' ? 'auto' : '100vw';
theImage.style.left = theImage.style.left === '50%' ? 'auto' : '50%';
theImage.style.transform = theImage.style.transform == 'translateX(-50%)' ? 'none' : 'translateX(-50%)' ;
theImage.style.position = theImage.style.position === 'relative' ? 'initial' : 'relative';
theImage.style.width = theImage.style.width === '35%' ? cache_beforeFocusWidth + 'px' : '35%';
}
} catch (err) {
// Suppress any error message related to imssing element
if(!err.message.startsWith('Cannot read property')) throw new Error(err);
}
}
}
});
if(theImage) {
// Tocca custom event
theImage.addEventListener('dbltap', function() {
// User has double the image, time to inst-like this pic :3
var isUnFav = likeThisPost();
Effects.instagramLike(theImage, !isUnFav);
});
}
// Live preview for comment box
if(postCommentBox) postCommentBox.addEventListener('keydown', livePreviewButtonPress);
var quickEditEl = document.querySelector('#quick-edit');
if(quickEditEl) {
var postsDiv = quickEditEl.nextSibling.nextSibling;
return postsDiv ? postsDiv.addEventListener('click', handler_post_imgOnClickNewScreen) : errLocateEl('The Posts Container Element');
}
var Utils = {
errorConsole: function(msg) {
if(msg) console.error('[e621.net Helper Utils Error] ' + msg);
},
_notifyConstru(opertor, msg, prefix) {
if(!opertor) throw new Error('Missing argument operator OwO');
var prefixMsg = '[e621.net Helper] ';
if(prefix === null || prefix === false) prefixMsg = '';
if(window[opertor] && typeof window.notice === 'function') return window[opertor].call(null, prefixMsg + msg);
return Utils.error('window.notice is not a valid function any more QvQ, WHYYYYYY DEV FROM E621!!!!!!!!!!!!!');
},
notice: (msg, prefix) => {
Utils._notifyConstru('notice', msg, prefix)
},
error: (msg, prefix) => {
Utils._notifyConstru('error', msg, prefix);
},
toggleDisplayNone: elm => {
elm.style.display = elm.style.display === 'none' ? '' : 'none';
},
versionIncomparableErr: (msg, local, remote) => {
Utils.errorConsole(''+ msg + ', might lead to bugger or even leak of features, Running ' + local + ' but executing ' + remote + ' code! Be ware!');
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment