// ==UserScript==
// @name Image Board Enhancer (Rule34, Gelbooru, e621, and more)
// @namespace ImageBoardEnhancer
// @version 1.3.1
// @description Auto Resize images and video on multiple image boards and enlarges thumbnails on mouse hover and adds content type icons to them.
// @author DanDanDan
// @match *://rule34.xxx/*
// @match *://chan.sankakucomplex.com/*
// @match *://idol.sankakucomplex.com/*
// @match *://gelbooru.com/*
// @match *://danbooru.donmai.us/*
// @match *://konachan.com/*
// @match *://konachan.net/*
// @match *://yande.re/*
// @match *://safebooru.org/*
// @match *://rule34.paheal.net/*
// @match *://rule34hentai.net/*
// @match *://e621.net/*
// @match *://e926.net/*
// @match *://tbib.org/*
// @match *://behoimi.org/*
// @require https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js
// @require https://greasyfork.org/scripts/420841-image-board-enhancer-icons/code/Image%20Board%20Enhancer%20Icons.js?version=895618
// @require https://greasyfork.org/scripts/420842-vanilla-js-wheel-zoom/code/vanilla-js-wheel-zoom.js?version=895198
// @grant GM.setValue
// @grant GM.getValue
// ==/UserScript==
(async () => {
'use strict';
try {
var resizeImageToFit = await GM.getValue('resizeImageToFit', true);
var resizeVideoToFit = await GM.getValue('resizeVideoToFit', true);
var autoplayVideos = await GM.getValue('autoplayVideos', true);
var autoScrollToContent = await GM.getValue('autoScrollToContent', true);
var updateWithWindowResize = await GM.getValue('updateWithWindowResize', true);
var updateScrollOnWindowResize = await GM.getValue('updateScrollOnWindowResize', true);
var showFitButton = await GM.getValue('showFitButton', true);
var showScrollButton = await GM.getValue('showScrollButton', true);
var showR34XXXLikeAndFavoriteButtons = await GM.getValue('showR34XXXLikeAndFavoriteButtons', true);
var removeFluid = await GM.getValue('removeFluid', false);
var videoVolume = await GM.getValue('videoVolume', 0);
var enableEnhancedThumbnails = await GM.getValue('enableEnhancedThumbnails', true);
var alwaysShowScrollbars = await GM.getValue('alwaysShowScrollbars', false);
var enableZoomableImage = await GM.getValue('enableZoomableImage', true);
var maxZoom = await GM.getValue('maxZoom', 1);
var zoomSpeed = await GM.getValue('zoomSpeed', 7);
var resizeButton = await GM.getValue('resizeButton', 'BracketLeft');
var scrollButton = await GM.getValue('scrollButton', 'BracketRight');
var hiddenIcons = await GM.getValue('hiddenIcons', []);
var customSites = await GM.getValue('customSites', {});
// Create variables.
var currentWindowWidth = 0;
var currentWindowHeight = 0;
var currentWindowAspect = 0;
var contentTrueWidth = 0;
var contentTrueHeight = 0;
var contentTrueAspect = 0;
var resizeReady = false;
var debugMode = false;
var r34buttons = false;
var toolbarDOM = '.sidebar form';
var containerDOM = '#content';
var imageDOM = '#image';
var playerDOM;
var changeKeyboardShortcut = false;
var containerAlignment = '';
var thumbnailDOM = '.thumb';
var thumbnails = [];
var animationTagIsGif = false;
var urlParams = new URLSearchParams(window.location.search);
var unsupportedThumbnailPage = false//(document.location.hostname.toLowerCase() == 'chan.sankakucomplex.com' || document.location.hostname.toLowerCase() == 'idol.sankakucomplex.com');
var waitingForZoom = false;
var wzoom;
// Per-site DOM selection.
if (document.location.hostname.toLowerCase() == 'rule34.xxx') { toolbarDOM = '.space'; r34buttons = showR34XXXLikeAndFavoriteButtons; playerDOM = '#gelcomVideoContainer'; animationTagIsGif = true; }
else if (document.location.hostname.toLowerCase() == 'chan.sankakucomplex.com' || document.location.hostname.toLowerCase() == 'idol.sankakucomplex.com') { toolbarDOM = '#search-form'; }
else if (document.location.hostname.toLowerCase() == 'gelbooru.com') { toolbarDOM = '#tag-list'; containerDOM = '#container'; thumbnailDOM = '.thumbnail-preview'; }
else if (document.location.hostname.toLowerCase() == 'danbooru.donmai.us') { toolbarDOM = '#search-box'; thumbnailDOM = '.post-preview'; }
else if (document.location.hostname.toLowerCase() == 'konachan.com' || document.location.hostname.toLowerCase() == 'konachan.net') { animationTagIsGif = true; }
else if (document.location.hostname.toLowerCase() == 'yande.re') { }
else if (document.location.hostname.toLowerCase() == 'safebooru.org') { }
else if (document.location.hostname.toLowerCase() == 'tbib.org') { }
else if (document.location.hostname.toLowerCase() == 'behoimi.org') { }
else if (document.location.hostname.toLowerCase() == 'rule34.paheal.net') { toolbarDOM = '#Navigationleft'; containerDOM = 'article'; imageDOM = '#main_image'; containerAlignment = 'margin-left: auto;'; }
else if (document.location.hostname.toLowerCase() == 'rule34hentai.net') { toolbarDOM = '#Navigationleft'; containerDOM = 'article'; imageDOM = '#main_image'; playerDOM = '#fluid_video_wrapper_video-id'; containerAlignment = 'margin-left: auto;'; }
else if (document.location.hostname.toLowerCase() == 'e621.net' || document.location.hostname.toLowerCase() == 'e926.net') { toolbarDOM = '#search-box'; thumbnailDOM = '.post-preview'; animationTagIsGif = true; }
// Custom site DOM selection.
else if (customSites[document.location.hostname.toLowerCase()]) {
var obj = customSites[document.location.hostname.toLowerCase()];
if (debugMode) console.log(obj, 'obj')
if (obj.toolbarDOM) toolbarDOM = obj.toolbarDOM;
if (obj.containerDOM) containerDOM = obj.containerDOM;
if (obj.imageDOM) imageDOM = obj.imageDOM;
if (obj.thumbnailDOM) thumbnailDOM = obj.thumbnailDOM
$("body").append("<button id='ibenhancerDeleteConfigButton' style='position: absolute; top: 0px; right: 0px; z-index: 9999999; color: black; background-color: whitesmoke; font-size: 12px;'>Delete site config.</button>");
$("#ibenhancerDeleteConfigButton").click(deleteSiteConfig);
}
// Default site DOM and add setup button.
else {
// Add setup button to websites wihtout a config.
$("body").append("<button id='ibenhancerSetupButton' style='position: absolute; top: 0px; right: 0px; z-index: 9999999; color: black; background-color: whitesmoke; font-size: 12px;'>Setup Image Board Enhancer</button>");
$("#ibenhancerSetupButton").click(addSiteConfig);
console.warn('This site is not supported, but may still work.');
}
// Add site config.
function addSiteConfig() {
var config = JSON.parse(prompt("Enter config in JSON format.", '{"toolbarDOM": ".sidebar form", "containerDOM": "#content", "imageDOM": "#image", "thumbnailDOM": ".thumb" }'));
if (config === null || !config || config == {}) {
alert('Config not valid.');
} else {
customSites[document.location.hostname.toLowerCase()] = config;
if (debugMode) console.log(customSites);
GM.setValue('customSites', customSites);
alert('Config saved.')
location.reload();
}
}
// Delete site config.
function deleteSiteConfig() {
delete customSites[document.location.hostname.toLowerCase()];
GM.setValue('customSites', customSites);
alert('Config deleted.')
location.reload();
}
// Remove the Gelcom Video player.
function removeFluidPlayer() {
if (debugMode) console.log('removeFluidPlayer');
$(playerDOM).replaceWith($(containerDOM + ' video'));
$(containerDOM + ' video').attr('id', 'image');
document.querySelector(imageDOM).outerHTML = document.querySelector(imageDOM).outerHTML; // This removes all event listeners, it seems jquery tries to maintain them.
$(containerDOM + ' video').removeAttr('style');
$(containerDOM + ' video').removeAttr('playsinline');
$(containerDOM + ' video').removeAttr('webkit-playsinline');
$(containerDOM + ' video').attr('controls', 'true');
$(containerDOM + ' video').attr('autoplay', autoplayVideos);
}
// Get window size and aspect ratio.
function getWindowProps() {
if (debugMode) console.log('getWindowProps');
currentWindowWidth = document.documentElement.clientWidth;
currentWindowHeight = document.documentElement.clientHeight;
if (currentWindowWidth !== 0 && currentWindowHeight !== 0)
currentWindowAspect = currentWindowWidth / currentWindowHeight;
}
// Get the real size of the video or image.
function getContentProps() {
if (debugMode) console.log('getContentProps');
if ($(containerDOM + ' video').length) {
contentTrueWidth = $(containerDOM + ' video')[0].videoWidth;
contentTrueHeight = $(containerDOM + ' video')[0].videoHeight;
}
else if ($(containerDOM + ' ' + imageDOM).length) {
var screenImage = $(containerDOM + ' ' + imageDOM);
var theImage = new Image();
theImage.src = screenImage.attr("src");
contentTrueWidth = theImage.width;
contentTrueHeight = theImage.height;
}
if (contentTrueWidth !== 0 && contentTrueHeight !== 0)
contentTrueAspect = contentTrueWidth / contentTrueHeight;
resizeReady = true;
}
// Resize the image (This resizes the video on some sites eg. sankakucomplex.com)
function resizeImage() {
if (debugMode) console.log('resizeImage');
$(containerDOM + ' ' + imageDOM).css('max-width', '');
if (currentWindowAspect > contentTrueAspect) {
$(containerDOM + ' ' + imageDOM)[0].width = currentWindowHeight * contentTrueAspect;
$(containerDOM + ' ' + imageDOM)[0].height = currentWindowHeight;
}
else {
$(containerDOM + ' ' + imageDOM)[0].width = currentWindowWidth;
$(containerDOM + ' ' + imageDOM)[0].height = currentWindowWidth / contentTrueAspect;
}
// Remove css from images.
$(containerDOM + ' ' + imageDOM).removeAttr('style');
if (enableZoomableImage && !$(containerDOM + ' video').length) $(containerDOM + ' ' + imageDOM).css({ cursor: 'zoom-in' });
}
// Resize Fluid video player.
function resizeFluidVideo() {
if (debugMode) console.log('resizeFluidVideo');
$(containerDOM + ' ' + playerDOM).css('max-width', '');
if (currentWindowAspect > contentTrueAspect) {
$(containerDOM + ' ' + playerDOM).css('width', currentWindowHeight * contentTrueAspect);
$(containerDOM + ' ' + playerDOM).css('height', currentWindowHeight);
}
else {
$(containerDOM + ' ' + playerDOM).css('width', currentWindowWidth);
$(containerDOM + ' ' + playerDOM).css('height', currentWindowWidth / contentTrueAspect);
}
}
// Resize default video.
function resizeVideo() {
if (debugMode) console.log('resizeVideo');
$(containerDOM + ' video').css('max-width', '');
if (currentWindowAspect > contentTrueAspect) {
$(containerDOM + ' video')[0].width = currentWindowHeight * contentTrueAspect;
$(containerDOM + ' video')[0].height = currentWindowHeight;
}
else {
$(containerDOM + ' video')[0].width = currentWindowWidth;
$(containerDOM + ' video').height = currentWindowWidth / contentTrueAspect;
}
}
// Scroll the window to the video or image.
function scrollToContent(delay) {
if (debugMode) console.log('scrollToContent');
setTimeout(function () {
var contentID;
if ($(containerDOM + ' ' + imageDOM).length) contentID = containerDOM + ' ' + imageDOM;
else if ($(containerDOM + ' ' + playerDOM).length) contentID = containerDOM + ' ' + playerDOM;
else if ($(containerDOM + ' video').length) contentID = containerDOM + ' video';
$([document.documentElement, document.body]).animate({
scrollTop: $(contentID).offset().top + 1
}, 0);
$([document.documentElement, document.body]).animate({
scrollLeft: $(contentID).offset().left + 1
}, 0);
}, delay);
}
// Check if resize is ready and what type of content to resize.
function fitContent(delay) {
if (debugMode) console.log('fitContent');
setTimeout(function () {
if (resizeReady) {
getWindowProps();
if ($(containerDOM + ' ' + imageDOM).length) {
resizeImage();
}
else if ($(containerDOM + ' ' + playerDOM).length) {
resizeFluidVideo();
}
else if ($(containerDOM + ' video').length) {
resizeVideo();
}
}
}, delay);
}
// Set the video auto play and volume settings.
function videoSettings() {
if (debugMode) console.log('videoSettings');
$(containerDOM + ' video').prop('autoplay', autoplayVideos);
$(containerDOM + ' video').prop('volume', videoVolume);
$(containerDOM + ' video').prop('loop', true);
if (autoplayVideos) $(containerDOM + ' video')[0].play(); else $(containerDOM + ' video')[0].pause();
}
// Remove the Gelcom player if present.
if (removeFluid && $(playerDOM).length) removeFluidPlayer();
// Get the image properties, resize, and scroll as the page is loading.
// If the image loads too quickly it wont fire the event.
if ($(containerDOM + ' video').length || $(containerDOM + ' ' + imageDOM).length) {
// Show Scrollbars
if (alwaysShowScrollbars) $('html').css({ overflow: 'scroll' });
getContentProps();
if (resizeImageToFit) fitContent(200);
if (autoScrollToContent) scrollToContent(200);
}
// Add event listener to the image or video.
if ($(containerDOM + ' video').length) {
if (debugMode) console.log('Create video event listener');
videoSettings();
$(containerDOM + ' video').on('loadedmetadata', function () { //NOTE: replaced 'loadedmetadata' with 'canplay'
getContentProps();
if (resizeVideoToFit) fitContent(200);
if (autoScrollToContent) scrollToContent(200);
$(containerDOM + ' video').play();
});
}
else if ($(containerDOM + ' ' + imageDOM).length) {
if (debugMode) console.log('Create image event listener');
$(containerDOM + ' ' + imageDOM).on('load', function () {
if (waitingForZoom) {
console.log('Waited for zoom');
setTimeout(openZoom, 16);
waitingForZoom = false;
}
getContentProps();
if (resizeImageToFit) fitContent(200);
if (autoScrollToContent) scrollToContent(200);
});
}
// Add the event listener to the window.
if (updateWithWindowResize) {
$(window).resize(function () {
fitContent(0);
if (updateScrollOnWindowResize) scrollToContent(0);
});
}
// Setting Functions
function showSettings() {
$("#ibenhancerSettings").addClass('show');
$("#ibenhancerSettings-blocker").addClass('show');
$("html").addClass('ibenhancerSettingVisible');
}
function hideSettings() {
$("#ibenhancerSettings").removeClass('show');
$("#ibenhancerSettings-blocker").removeClass('show');
$("html").removeClass('ibenhancerSettingVisible');
$("#resizeImageToFitCheckbox").prop('checked', resizeImageToFit);
$("#resizeVideoToFitCheckbox").prop('checked', resizeVideoToFit);
$("#autoplayVideosCheckbox").prop('checked', autoplayVideos);
$("#autoScrollToContentCheckbox").prop('checked', autoScrollToContent);
$("#updateWithWindowResizeCheckbox").prop('checked', updateWithWindowResize);
$("#updateScrollOnWindowResizeCheckbox").prop('checked', updateScrollOnWindowResize);
$("#showFitButtonCheckbox").prop('checked', showFitButton);
$("#showScrollButtonCheckbox").prop('checked', showScrollButton);
$("#showR34XXXLikeAndFavoriteButtonsCheckbox").prop('checked', showR34XXXLikeAndFavoriteButtons);
$("#removeFluidCheckbox").prop('checked', removeFluid);
$("#enableEnhancedThumbnailsCheckbox").prop('checked', enableEnhancedThumbnails);
$("#alwaysShowScrollbarsCheckbox").prop('checked', alwaysShowScrollbars);
$("#enableZoomableImageCheckbox").prop('checked', enableZoomableImage);
$("#maxZoomInput").val(maxZoom);
$("#zoomSpeedInput").val(zoomSpeed);
$("#videoVolumeInput").val(videoVolume);
$("#hideIconGifCheckbox").prop('checked', hiddenIcons.includes("gif"));
$("#hideIconVideoCheckbox").prop('checked', hiddenIcons.includes("video"));
$("#hideIconSoundCheckbox").prop('checked', hiddenIcons.includes("sound"));
$("#hideIconFlashCheckbox").prop('checked', hiddenIcons.includes("flash"));
$("#hideIconStraightCheckbox").prop('checked', hiddenIcons.includes("straight"));
$("#hideIconGayCheckbox").prop('checked', hiddenIcons.includes("gay"));
$("#hideIconLesbianCheckbox").prop('checked', hiddenIcons.includes("lesbian"));
$("#hideIconTransCheckbox").prop('checked', hiddenIcons.includes("trans"));
$("#hideIconTrapCheckbox").prop('checked', hiddenIcons.includes("trap"));
$("#hideIconThreeDCheckbox").prop('checked', hiddenIcons.includes("threeD"));
$("#hideIconLoliShotaCheckbox").prop('checked', hiddenIcons.includes("loliShota"));
$("#hideIconGoreDeathCheckbox").prop('checked', hiddenIcons.includes("goreDeath"));
$("#hideIconPregnantCheckbox").prop('checked', hiddenIcons.includes("pregnant"));
$("#hideIconBestialityCheckbox").prop('checked', hiddenIcons.includes("bestiality"));
$("#hideIconFeetCheckbox").prop('checked', hiddenIcons.includes("feet"));
$("#hideIconBondageCheckbox").prop('checked', hiddenIcons.includes("bondage"));
$("#hideIconPoopCheckbox").prop('checked', hiddenIcons.includes("poop"));
$("#hideIconPissCheckbox").prop('checked', hiddenIcons.includes("piss"));
$("#hideIconGroupCheckbox").prop('checked', hiddenIcons.includes("group"));
$("#hideIconIncestCheckbox").prop('checked', hiddenIcons.includes("incest"));
$("#hideIconSafeCheckbox").prop('checked', hiddenIcons.includes("safe"));
$("#hideIconQuestionableCheckbox").prop('checked', hiddenIcons.includes("questionable"));
$("#hideIconExplicitCheckbox").prop('checked', hiddenIcons.includes("explicit"));
}
function changeResizeButtonClicked() {
$('#resizeButton').html('?');
changeKeyboardShortcut = 'resizeButton';
}
function changeScrollButtonClicked() {
$('#scrollButton').html('?');
changeKeyboardShortcut = 'scrollButton';
}
function saveSettings() {
GM.setValue('resizeImageToFit', $('#resizeImageToFitCheckbox').is(':checked'));
GM.setValue('resizeVideoToFit', $('#resizeVideoToFitCheckbox').is(':checked'));
GM.setValue('autoplayVideos', $('#autoplayVideosCheckbox').is(':checked'));
GM.setValue('autoScrollToContent', $('#autoScrollToContentCheckbox').is(':checked'));
GM.setValue('updateScrollOnWindowResize', $('#updateScrollOnWindowResizeCheckbox').is(':checked'));
GM.setValue('updateWithWindowResize', $('#updateWithWindowResizeCheckbox').is(':checked'));
GM.setValue('showFitButton', $('#showFitButtonCheckbox').is(':checked'));
GM.setValue('showScrollButton', $('#showScrollButtonCheckbox').is(':checked'));
GM.setValue('showR34XXXLikeAndFavoriteButtons', $('#showR34XXXLikeAndFavoriteButtonsCheckbox').is(':checked'));
GM.setValue('removeFluid', $('#removeFluidCheckbox').is(':checked'));
GM.setValue('videoVolume', $('#videoVolumeInput').val());
GM.setValue('enableEnhancedThumbnails', $('#enableEnhancedThumbnailsCheckbox').is(':checked'));
GM.setValue('alwaysShowScrollbars', $('#alwaysShowScrollbarsCheckbox').is(':checked'));
GM.setValue('enableZoomableImage', $('#enableZoomableImageCheckbox').is(':checked'));
GM.setValue('maxZoom', $('#maxZoomInput').val());
GM.setValue('zoomSpeed', $('#zoomSpeedInput').val());
GM.setValue('resizeButton', resizeButton);
GM.setValue('scrollButton', scrollButton);
var newHiddenIcons = [];
if($('#hideIconGifCheckbox').is(':checked')) newHiddenIcons.push('gif');
if($('#hideIconVideoCheckbox').is(':checked')) newHiddenIcons.push('video');
if($('#hideIconSoundCheckbox').is(':checked')) newHiddenIcons.push('sound');
if($('#hideIconFlashCheckbox').is(':checked')) newHiddenIcons.push('flash');
if($('#hideIconStraightCheckbox').is(':checked')) newHiddenIcons.push('straight');
if($('#hideIconGayCheckbox').is(':checked')) newHiddenIcons.push('gay');
if($('#hideIconLesbianCheckbox').is(':checked')) newHiddenIcons.push('lesbian');
if($('#hideIconTransCheckbox').is(':checked')) newHiddenIcons.push('trans');
if($('#hideIconTrapCheckbox').is(':checked')) newHiddenIcons.push('trap');
if($('#hideIconThreeDCheckbox').is(':checked')) newHiddenIcons.push('threeD');
if($('#hideIconLoliShotaCheckbox').is(':checked')) newHiddenIcons.push('loliShota');
if($('#hideIconGoreDeathCheckbox').is(':checked')) newHiddenIcons.push('goreDeath');
if($('#hideIconPregnantCheckbox').is(':checked')) newHiddenIcons.push('pregnant');
if($('#hideIconBestialityCheckbox').is(':checked')) newHiddenIcons.push('bestiality');
if($('#hideIconFeetCheckbox').is(':checked')) newHiddenIcons.push('feet');
if($('#hideIconBondageCheckbox').is(':checked')) newHiddenIcons.push('bondage');
if($('#hideIconPoopCheckbox').is(':checked')) newHiddenIcons.push('poop');
if($('#hideIconPissCheckbox').is(':checked')) newHiddenIcons.push('piss');
if($('#hideIconGroupCheckbox').is(':checked')) newHiddenIcons.push('group');
if($('#hideIconIncestCheckbox').is(':checked')) newHiddenIcons.push('incest');
if($('#hideIconSafeCheckbox').is(':checked')) newHiddenIcons.push('safe');
if($('#hideIconQuestionableCheckbox').is(':checked')) newHiddenIcons.push('questionable');
if($('#hideIconExplicitCheckbox').is(':checked')) newHiddenIcons.push('explicit');
GM.setValue('hiddenIcons', newHiddenIcons);
location.reload();
}
function hideAllIcons() {
$("#hideIconGifCheckbox").prop('checked', true);
$("#hideIconVideoCheckbox").prop('checked', true);
$("#hideIconSoundCheckbox").prop('checked', true);
$("#hideIconFlashCheckbox").prop('checked', true);
$("#hideIconStraightCheckbox").prop('checked', true);
$("#hideIconGayCheckbox").prop('checked', true);
$("#hideIconLesbianCheckbox").prop('checked', true);
$("#hideIconTransCheckbox").prop('checked', true);
$("#hideIconTrapCheckbox").prop('checked', true);
$("#hideIconThreeDCheckbox").prop('checked', true);
$("#hideIconLoliShotaCheckbox").prop('checked', true);
$("#hideIconGoreDeathCheckbox").prop('checked', true);
$("#hideIconPregnantCheckbox").prop('checked', true);
$("#hideIconBestialityCheckbox").prop('checked', true);
$("#hideIconFeetCheckbox").prop('checked', true);
$("#hideIconBondageCheckbox").prop('checked', true);
$("#hideIconPoopCheckbox").prop('checked', true);
$("#hideIconPissCheckbox").prop('checked', true);
$("#hideIconGroupCheckbox").prop('checked', true);
$("#hideIconIncestCheckbox").prop('checked', true);
$("#hideIconSafeCheckbox").prop('checked', true);
$("#hideIconQuestionableCheckbox").prop('checked', true);
$("#hideIconExplicitCheckbox").prop('checked', true);
}
function unhideAllIcons() {
$("#hideIconGifCheckbox").prop('checked', false);
$("#hideIconVideoCheckbox").prop('checked', false);
$("#hideIconSoundCheckbox").prop('checked', false);
$("#hideIconFlashCheckbox").prop('checked', false);
$("#hideIconStraightCheckbox").prop('checked', false);
$("#hideIconGayCheckbox").prop('checked', false);
$("#hideIconLesbianCheckbox").prop('checked', false);
$("#hideIconTransCheckbox").prop('checked', false);
$("#hideIconTrapCheckbox").prop('checked', false);
$("#hideIconThreeDCheckbox").prop('checked', false);
$("#hideIconLoliShotaCheckbox").prop('checked', false);
$("#hideIconGoreDeathCheckbox").prop('checked', false);
$("#hideIconPregnantCheckbox").prop('checked', false);
$("#hideIconBestialityCheckbox").prop('checked', false);
$("#hideIconFeetCheckbox").prop('checked', false);
$("#hideIconBondageCheckbox").prop('checked', false);
$("#hideIconPoopCheckbox").prop('checked', false);
$("#hideIconPissCheckbox").prop('checked', false);
$("#hideIconGroupCheckbox").prop('checked', false);
$("#hideIconIncestCheckbox").prop('checked', false);
$("#hideIconSafeCheckbox").prop('checked', false);
$("#hideIconQuestionableCheckbox").prop('checked', false);
$("#hideIconExplicitCheckbox").prop('checked', false);
}
// Create the toolbar.
if ($(containerDOM + ' ' + imageDOM).length || $(containerDOM + ' video').length) {
if (debugMode) console.log('Create toolbar');
$(toolbarDOM).after("<div id='ibenhancer'>Image Board Enhancer<br></div>");
if (showFitButton) {
$("#ibenhancer").append("<button id='fitContentButton' style='margin-top: 3px;'>Fit</button>");
$("#fitContentButton").click(function () { getContentProps(); fitContent(0); });
}
if (showScrollButton) {
$("#ibenhancer").append("<button id='scrollContentButton' style='margin-top: 3px;'>Scroll</button>");
$("#scrollContentButton").click(scrollToContent);
}
// Create settings.
$("#ibenhancer").append("<br><button id='ibenhancerSettingsButton' style='margin-top: 3px;'>Settings</button>");
$("#ibenhancerSettingsButton").click(showSettings);
$("#ibenhancer").append(`
<div id="ibenhancerSettings-blocker"></div>
<div id="ibenhancerSettings">
<div id="ibenhancerSettings-options">
<label><input id="resizeImageToFitCheckbox" type="checkbox" ` + (resizeImageToFit ? `checked` : ``) + `>Resize images to fit screen.</label>
<br>
<label><input id="resizeVideoToFitCheckbox" type="checkbox" ` + (resizeVideoToFit ? `checked` : ``) + `>Resize videos to fit screen.</label>
<br>
<label><input id="autoplayVideosCheckbox" type="checkbox" ` + (autoplayVideos ? `checked` : ``) + `>Autoplay videos.</label>
<br>
<label><input id="autoScrollToContentCheckbox" type="checkbox" ` + (autoScrollToContent ? `checked` : ``) + `>Scroll to content.</label>
<br>
<label><input id="updateWithWindowResizeCheckbox" type="checkbox" ` + (updateWithWindowResize ? `checked` : ``) + `>Resize content with window.</label>
<br>
<label><input id="updateScrollOnWindowResizeCheckbox" type="checkbox" ` + (updateScrollOnWindowResize ? `checked` : ``) + `>Scroll to content on window resize.</label>
<br>
<label><input id="showFitButtonCheckbox" type="checkbox" ` + (showFitButton ? `checked` : ``) + `>Show fit button.</label>
<br>
<label><input id="showScrollButtonCheckbox" type="checkbox" ` + (showScrollButton ? `checked` : ``) + `>Show scroll button.</label>
<br>
<label><input id="showR34XXXLikeAndFavoriteButtonsCheckbox" type="checkbox" ` + (showR34XXXLikeAndFavoriteButtons ? `checked` : ``) + `>Show like and favorite buttons on rule34.xxx.</label>
<br>
<label><input id="removeFluidCheckbox" type="checkbox" ` + (removeFluid ? `checked` : ``) + `>Remove fluid video player.</label>
<br>
<label><input id="enableEnhancedThumbnailsCheckbox" type="checkbox" ` + (enableEnhancedThumbnails ? `checked` : ``) + `>Enable enhanced thumbnails.</label>
<br>
<label><input id="alwaysShowScrollbarsCheckbox" type="checkbox" ` + (alwaysShowScrollbars ? `checked` : ``) + `>Always show scrollbars. (Fixes resize issue.)</label>
<br>
<label><input id="enableZoomableImageCheckbox" type="checkbox" ` + (enableZoomableImage ? `checked` : ``) + `>Enable zoomable image.</label>
<br>
<label>Max zoom: <input id="maxZoomInput" type="number" min="1" max="5" step="1" value="` + maxZoom + `" style="width:60px;">1 - 5</label>
<br>
<label>Zoom speed: <input id="zoomSpeedInput" type="number" min="1" max="15" step="1" value="` + zoomSpeed + `" style="width:60px;">1 - 15</label>
<br>
<label>Video volume: <input id="videoVolumeInput" type="number" min="0" max="1" step="0.01" value="` + videoVolume + `" style="width:60px;">0 - 1</label>
<br>
<label>Resize keyboard shurtcut: <button id="resizeButton">` + resizeButton + `</button></label>
<br>
<label>Scroll keyboard shurtcut: <button id="scrollButton">` + scrollButton + `</button></label>
<br>
Hide icons: <button id="hideAllIconsButton">Hide All</button> <button id="unhideAllIconsButton">Unhide All</button>
<br>
<label><input id="hideIconGifCheckbox" type="checkbox" ` + (hiddenIcons.includes("gif") ? `checked` : ``) + `>GIF</label>
<label><input id="hideIconVideoCheckbox" type="checkbox" ` + (hiddenIcons.includes("video") ? `checked` : ``) + `>Video</label>
<label><input id="hideIconSoundCheckbox" type="checkbox" ` + (hiddenIcons.includes("sound") ? `checked` : ``) + `>Sound</label>
<label><input id="hideIconFlashCheckbox" type="checkbox" ` + (hiddenIcons.includes("flash") ? `checked` : ``) + `>Flash</label>
<label><input id="hideIconStraightCheckbox" type="checkbox" ` + (hiddenIcons.includes("straight") ? `checked` : ``) + `>Straight</label>
<label><input id="hideIconGayCheckbox" type="checkbox" ` + (hiddenIcons.includes("gay") ? `checked` : ``) + `>Yaoi/Gay</label>
<label><input id="hideIconLesbianCheckbox" type="checkbox" ` + (hiddenIcons.includes("lesbian") ? `checked` : ``) + `>Yuri/Lesbian</label>
<label><input id="hideIconTransCheckbox" type="checkbox" ` + (hiddenIcons.includes("trans") ? `checked` : ``) + `>Futanari/Transsexual</label>
<label><input id="hideIconTrapCheckbox" type="checkbox" ` + (hiddenIcons.includes("trap") ? `checked` : ``) + `>Trap</label>
<label><input id="hideIconThreeDCheckbox" type="checkbox" ` + (hiddenIcons.includes("threeD") ? `checked` : ``) + `>3D</label>
<label><input id="hideIconLoliShotaCheckbox" type="checkbox" ` + (hiddenIcons.includes("loliShota") ? `checked` : ``) + `>Loli/Shota</label>
<label><input id="hideIconGoreDeathCheckbox" type="checkbox" ` + (hiddenIcons.includes("goreDeath") ? `checked` : ``) + `>Gore/Death</label>
<label><input id="hideIconPregnantCheckbox" type="checkbox" ` + (hiddenIcons.includes("pregnant") ? `checked` : ``) + `>Pregnant</label>
<label><input id="hideIconBestialityCheckbox" type="checkbox" ` + (hiddenIcons.includes("bestiality") ? `checked` : ``) + `>Bestiality</label>
<label><input id="hideIconFeetCheckbox" type="checkbox" ` + (hiddenIcons.includes("feet") ? `checked` : ``) + `>Feet/Footjob</label>
<label><input id="hideIconBondageCheckbox" type="checkbox" ` + (hiddenIcons.includes("bondage") ? `checked` : ``) + `>Bondage/BDSM</label>
<label><input id="hideIconPoopCheckbox" type="checkbox" ` + (hiddenIcons.includes("poop") ? `checked` : ``) + `>Scat</label>
<label><input id="hideIconPissCheckbox" type="checkbox" ` + (hiddenIcons.includes("piss") ? `checked` : ``) + `>Piss/Golden Shower</label>
<label><input id="hideIconGroupCheckbox" type="checkbox" ` + (hiddenIcons.includes("group") ? `checked` : ``) + `>Group Sex/Gangbang</label>
<label><input id="hideIconIncestCheckbox" type="checkbox" ` + (hiddenIcons.includes("incest") ? `checked` : ``) + `>Incest</label>
<label><input id="hideIconSafeCheckbox" type="checkbox" ` + (hiddenIcons.includes("safe") ? `checked` : ``) + `>Rating: Safe</label>
<label><input id="hideIconQuestionableCheckbox" type="checkbox" ` + (hiddenIcons.includes("questionable") ? `checked` : ``) + `>Rating: Questionable</label>
<label><input id="hideIconExplicitCheckbox" type="checkbox" ` + (hiddenIcons.includes("explicit") ? `checked` : ``) + `>Rating: Explicit</label>
</div>
<button id="ibenhancerSettingsSave">Save</button><button id="ibenhancerSettingsCancel">Cancel</button>
<a href="https://icons8.com/">Icons by Icons8</a>
</div>
` );
$("#ibenhancerSettingsSave").click(saveSettings);
$("#ibenhancerSettingsCancel").click(hideSettings);
$("#resizeButton").click(changeResizeButtonClicked);
$("#scrollButton").click(changeScrollButtonClicked);
$("#hideAllIconsButton").click(hideAllIcons);
$("#unhideAllIconsButton").click(unhideAllIcons);
addGlobalStyle(`
html.ibenhancerSettingVisible {
overflow: hidden !important;
}
#ibenhancer {
background: white !important;
color: black !important;
border: solid 1px grey;
border-radius: 4px;
padding: 5px;
width: 170px;
text-align: center !important;
margin-top: 5px;
margin-bottom: 5px;
margin-right: auto;
` + containerAlignment + `
}
#ibenhancer, #ibenhancer label {
font-size: 15px !important;
font-family: Arial, Helvetica, sans-serif !important;
font-style: normal !important;
font-weight: normal !important;
}
#ibenhancerSettings-blocker {
position: fixed;
content: '';
background-color: rgba(0, 0, 0, .5);
width: 100vw;
height: 100vh;
top: 0;
left: 0;
z-index: 1;
display: none;
}
#ibenhancerSettings-blocker.show {
display: block;
}
#ibenhancerSettings {
position: fixed;
width: 400px;
height: 400px;
left: calc(50vw - 155px);
top: calc(50vh - 165px);
background-color: white;
border: 2px solid black;
border-radius: 3px;
padding: 10px;
text-align: left;
z-index: 999999;
display: none;
-webkit-box-sizing: unset;
-moz-box-sizing: unset;
box-sizing: unset;
color: black;
padding-bottom: 0px;
}
#ibenhancerSettings-options {
overflow-y: auto;
overflow-x: hidden;
width: 100%;
height: calc(100% - 32px);
}
#ibenhancerSettings input {
margin: 5px;
width: auto;
}
#ibenhancerSettings input[type=number] {
border: solid 1px darkgrey;
}
#ibenhancer button {
padding: 3px !important;
width: auto;
border: solid 1px darkgrey !important;
margin: 2px !important;
border-radius 2px !important;
background: WhiteSmoke !important;
cursor: pointer;
}
#ibenhancerSettings.show {
display: block;
}
#fitContentButton {
width: 73px !important;
}
#scrollContentButton {
width: 73px !important;
}
#ibenhancerSettingsButton {
width: 150px !important;
}
`);
// Add the like and favorite button to rule34.xxx
if (r34buttons) {
if (debugMode) console.log('r34buttons');
$("#ibenhancer").append('<br><img id="like-butt" class="custom-button" src="' + likeButtonImage + '" alt="like"><img id="favorite-butt" class="custom-button" src="' + favoriteButtonImage + '" alt="favorite">');
$("#like-butt").click(function () {
$("#stats > ul > li:contains('(vote up)') > a:contains('up')").click();
});
$("#favorite-butt").click(function () {
$("#stats + div > ul > li > a:contains('Add to favorites')").click();
});
addGlobalStyle(`
img.custom-button {
cursor: pointer;
width: 35px;
padding: 3px;
margin: 0;
border-radius: 20px;
}
.custom-button:hover {
background-color: rgba(255,255,255,.5);
}
.custom-button:active {
background-color: rgba(255,255,255,1);
}
`);
}
}
function addGlobalStyle(css) {
if (debugMode) console.log('addGlobalStyle');
var head, style;
head = document.getElementsByTagName('head')[0];
if (!head) { return; }
style = document.createElement('style');
style.type = 'text/css';
style.innerHTML = css;
head.appendChild(style);
}
// Keyboard shortcuts
document.addEventListener('keyup', (e) => {
if (debugMode) console.log(e.code)
if (!changeKeyboardShortcut) {
if (e.code === resizeButton) { getContentProps(0); fitContent(0); }
else if (e.code === scrollButton) scrollToContent(0);
}
else if (changeKeyboardShortcut == 'resizeButton') {
resizeButton = e.code;
$('#resizeButton').html(e.code);
changeKeyboardShortcut = false;
}
else if (changeKeyboardShortcut == 'scrollButton') {
scrollButton = e.code;
$('#scrollButton').html(e.code);
changeKeyboardShortcut = false;
}
});
if (urlParams.get('page') && urlParams.get('page').toLowerCase() == 'favorites') unsupportedThumbnailPage = true; // Add method to remove favorite.
// Get Thumbnails
if (enableEnhancedThumbnails) thumbnails = $(thumbnailDOM);
function checkForMoreThumbnails() {
var oldNumber = thumbnails.length;
thumbnails = $(thumbnailDOM);
return (thumbnails.length > oldNumber);
}
if (!unsupportedThumbnailPage && thumbnails.length > 0) {
$('body').append(`
<a href="#" id="thumbPlusPreviewLink" style="">
<div id="thumbPlusPreview" class="">
<div id="thumbPlusPreviewImage"></div>
<div style="position: relative;">
<span id="thumbPlusPreviewGif" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("gif") ? `` : `show`) + `" title="GIF">` + icons['gif'] + `</span>
<span id="thumbPlusPreviewVideo" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("video") ? `` : `show`) + `" title="Video">` + icons['video'] + `</span>
<span id="thumbPlusPreviewFlash" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("flash") ? `` : `show`) + `" title="Flash Animation">` + icons['flash'] + `</span>
<span id="thumbPlusPreviewSound" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("sound") ? `` : `show`) + `" title="Has Sound">` + icons['sound'] + `</span>
<span id="thumbPlusPreview3D" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("threeD") ? `` : `show`) + `" title="3D">` + icons['threeD'] + `</span>
<span id="thumbPlusPreviewStraight" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("straight") ? `` : `show`) + `" title="Straight">` + icons['straight'] + `</span>
<span id="thumbPlusPreviewGay" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("gay") ? `` : `show`) + `" title="Yaoi/Gay">` + icons['gay'] + `</span>
<span id="thumbPlusPreviewLesbian" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("lesbian") ? `` : `show`) + `" title="Yuri/Lesbian">` + icons['lesbian'] + `</span>
<span id="thumbPlusPreviewTrans" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("trans") ? `` : `show`) + `" title="Futanari/Transsexual">` + icons['trans'] + `</span>
<span id="thumbPlusPreviewTrap" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("trap") ? `` : `show`) + `" title="Trap">` + icons['trap'] + `</span>
<span id="thumbPlusPreviewLoliShota" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("loliShota") ? `` : `show`) + `" title="Loli/Shota">` + icons['loliShota'] + `</span>
<span id="thumbPlusPreviewGoreDeath" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("goreDeath") ? `` : `show`) + `" title="Gore/Death">` + icons['goreDeath'] + `</span>
<span id="thumbPlusPreviewPregnant" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("pregnant") ? `` : `show`) + `" title="Pregnant">` + icons['pregnant'] + `</span>
<span id="thumbPlusPreviewBestiality" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("bestiality") ? `` : `show`) + `" title="Bestiality">` + icons['bestiality'] + `</span>
<span id="thumbPlusPreviewFeet" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("feet") ? `` : `show`) + `" title="Feet/Footjob">` + icons['feet'] + `</span>
<span id="thumbPlusPreviewBondage" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("bondage") ? `` : `show`) + `" title="Bondage/BDSM">` + icons['bondage'] + `</span>
<span id="thumbPlusPreviewPoop" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("poop") ? `` : `show`) + `" title="Scat">` + icons['poop'] + `</span>
<span id="thumbPlusPreviewPiss" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("piss") ? `` : `show`) + `" title="Piss/Golden Shower">` + icons['piss'] + `</span>
<span id="thumbPlusPreviewGroup" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("group") ? `` : `show`) + `" title="Group Sex/Gangbang">` + icons['group'] + `</span>
<span id="thumbPlusPreviewIncest" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("incest") ? `` : `show`) + `" title="Incest">` + icons['incest'] + `</span>
<span id="thumbPlusPreviewSafe" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("safe") ? `` : `show`) + `" title="Rating: Safe">` + icons['safe'] + `</span>
<span id="thumbPlusPreviewQuestionable" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("questionable") ? `` : `show`) + `" title="Rating: Questionable">` + icons['questionable'] + `</span>
<span id="thumbPlusPreviewExplicit" class="thumbPlusPreviewIcon ` + (hiddenIcons.includes("explicit") ? `` : `show`) + `" title="Rating: Explicit">` + icons['explicit'] + `</span>
</div>
</div>
</a>
`);
$('#thumbPlusPreview').css({ backgroundColor: $('body').css("background-color") != "rgba(0, 0, 0, 0)" ? $('body').css("background-color") : 'white' });
$('#thumbPlusPreviewContextMenuRemoveFavorite').click(function () { alert('Clicked') });
$('#thumbPlusPreview').mouseout(function () {
$('#thumbPlusPreviewLink').removeClass('show');
$('#thumbPlusPreview').removeClass('show gif video sound flash straight gay lesbian trans threed trap lolishota gore pregnant bestiality feet bondage poop piss group incest safe questionable explicit');
})
function addThumbnailEnhancement() {
if (debugMode) console.log('Add thumbnails');
if (enableEnhancedThumbnails) thumbnails = $(thumbnailDOM);
var tmp = 0;
thumbnails.each(function () {
if (!$(this).hasClass('ibeThumbnail')) {
$(this).mouseover(function (e) {
thumbnailMouseOver(this);
})
$(this).addClass('ibeThumbnail');
tmp++;
}
});
console.log('Added', tmp, 'thumbnails.');
}
addThumbnailEnhancement();
setInterval(function () {
if (checkForMoreThumbnails()) addThumbnailEnhancement()
}, 100);
function thumbnailMouseOver(thumb) {
if ($('img', thumb).attr('oldtitle') && $('img', thumb).attr('oldtitle') != '') // oldtitle is used for gelbooru
var title = $('img', thumb).attr('oldtitle');
else
var title = $('img', thumb).attr('title');
var tags = title.split(' ');
for (let i = 0; i < tags.length; i++) {
tags[i] = tags[i].toLowerCase().split(',').join('');
}
if (tags.includes("webm")) $('#thumbPlusPreview').addClass('video');
else if (tags.includes("mp4")) $('#thumbPlusPreview').addClass('video');
else if (tags.includes("animated_gif")) $('#thumbPlusPreview').addClass('gif');
else if (tags.includes("flash")) $('#thumbPlusPreview').addClass('flash');
else if (tags.includes("flash_animation")) $('#thumbPlusPreview').addClass('flash');
else if (tags.includes("video")) $('#thumbPlusPreview').addClass('video');
else if (tags.includes("animated") && animationTagIsGif && !tags.includes("sound")) $('#thumbPlusPreview').addClass('gif');
else if (tags.includes("animated")) $('#thumbPlusPreview').addClass('video');
if (tags.includes("sound")) $('#thumbPlusPreview').addClass('sound');
else if (tags.includes("audio")) $('#thumbPlusPreview').addClass('sound');
else if (tags.includes("has_sound")) $('#thumbPlusPreview').addClass('sound');
else if (tags.includes("has_audio")) $('#thumbPlusPreview').addClass('sound');
else if (tags.includes("video_with_sound")) $('#thumbPlusPreview').addClass('sound');
if (tags.includes("hetero")) $('#thumbPlusPreview').addClass('straight');
else if (tags.includes("straight")) $('#thumbPlusPreview').addClass('straight');
else if (tags.includes("male/female")) $('#thumbPlusPreview').addClass('straight');
if (tags.includes("yaoi")) $('#thumbPlusPreview').addClass('gay');
else if (tags.includes("gay")) $('#thumbPlusPreview').addClass('gay');
else if (tags.includes("male/male")) $('#thumbPlusPreview').addClass('gay');
if (tags.includes("yuri")) $('#thumbPlusPreview').addClass('lesbian');
else if (tags.includes("lesbian")) $('#thumbPlusPreview').addClass('lesbian');
else if (tags.includes("female/female")) $('#thumbPlusPreview').addClass('lesbian');
if (tags.includes("futanari")) $('#thumbPlusPreview').addClass('trans');
else if (tags.includes("newhalf")) $('#thumbPlusPreview').addClass('trans');
else if (tags.includes("dickgirl")) $('#thumbPlusPreview').addClass('trans');
else if (tags.includes("shemale")) $('#thumbPlusPreview').addClass('trans');
else if (tags.includes("intersex")) $('#thumbPlusPreview').addClass('trans');
if (tags.includes("trap")) $('#thumbPlusPreview').addClass('trap');
else if (tags.includes("otoko no ko")) $('#thumbPlusPreview').addClass('trap');
if (tags.includes("3d")) $('#thumbPlusPreview').addClass('threed');
if (tags.includes("loli")) $('#thumbPlusPreview').addClass('lolishota');
else if (tags.includes("shota")) $('#thumbPlusPreview').addClass('lolishota');
if (tags.includes("guro")) $('#thumbPlusPreview').addClass('gore');
else if (tags.includes("gore")) $('#thumbPlusPreview').addClass('gore');
else if (tags.includes("death")) $('#thumbPlusPreview').addClass('gore');
else if (tags.includes("snuf")) $('#thumbPlusPreview').addClass('gore');
if (tags.includes("pregnant")) $('#thumbPlusPreview').addClass('pregnant');
else if (tags.includes("pregnant_futa")) $('#thumbPlusPreview').addClass('pregnant');
else if (tags.includes("pregnant_loli")) $('#thumbPlusPreview').addClass('pregnant');
if (tags.includes("bestiality")) $('#thumbPlusPreview').addClass('bestiality');
// A lot seem to be tagged with feet when it is not the main focus and many foot fetish posts are only tagged as feet.
if (tags.includes("foot_fetish")) $('#thumbPlusPreview').addClass('feet');
else if (tags.includes("pov_feet")) $('#thumbPlusPreview').addClass('feet');
else if (tags.includes("foot_focus")) $('#thumbPlusPreview').addClass('feet');
else if (tags.includes("foot_worship")) $('#thumbPlusPreview').addClass('feet');
else if (tags.includes("footjob")) $('#thumbPlusPreview').addClass('feet');
else if (tags.includes("ashikoki")) $('#thumbPlusPreview').addClass('feet');
// else if (tags.includes("feet")) $('#thumbPlusPreview').addClass('feet');
if (tags.includes("bondage")) $('#thumbPlusPreview').addClass('bondage');
else if (tags.includes("bdsm")) $('#thumbPlusPreview').addClass('bondage');
if (tags.includes("scat")) $('#thumbPlusPreview').addClass('poop');
else if (tags.includes("defecating")) $('#thumbPlusPreview').addClass('poop');
else if (tags.includes("feces")) $('#thumbPlusPreview').addClass('poop');
else if (tags.includes("coprophagia")) $('#thumbPlusPreview').addClass('poop');
else if (tags.includes("soiling")) $('#thumbPlusPreview').addClass('poop');
if (tags.includes("urine")) $('#thumbPlusPreview').addClass('piss');
else if (tags.includes("urinating")) $('#thumbPlusPreview').addClass('piss');
else if (tags.includes("peeing")) $('#thumbPlusPreview').addClass('piss');
else if (tags.includes("golden_shower")) $('#thumbPlusPreview').addClass('piss');
else if (tags.includes("watersports")) $('#thumbPlusPreview').addClass('piss');
if (tags.includes("group_sex")) $('#thumbPlusPreview').addClass('group');
else if (tags.includes("gangbang")) $('#thumbPlusPreview').addClass('group');
else if (tags.includes("threesome")) $('#thumbPlusPreview').addClass('group');
else if (tags.includes("orgy")) $('#thumbPlusPreview').addClass('group');
else if (tags.includes("foursome")) $('#thumbPlusPreview').addClass('group');
if (tags.includes("incest")) $('#thumbPlusPreview').addClass('incest');
if (tags.includes("rating:safe")) $('#thumbPlusPreview').addClass('safe');
else if (tags.includes("safe")) $('#thumbPlusPreview').addClass('safe');
else if (tags.includes("rating:questionable")) $('#thumbPlusPreview').addClass('questionable');
else if (tags.includes("questionable")) $('#thumbPlusPreview').addClass('questionable');
else if (tags.includes("rating:explicit")) $('#thumbPlusPreview').addClass('explicit');
else if (tags.includes("explicit")) $('#thumbPlusPreview').addClass('explicit');
$('#thumbPlusPreviewLink').css({ top: cumulativeOffset(thumb).top, left: cumulativeOffset(thumb).left });
$('#thumbPlusPreviewImage').css({ backgroundImage: 'url(' + $('img', thumb).attr('src') + ')' });
$('#thumbPlusPreviewImage').attr('title', title);
var height = $('img', thumb).height() * 1.555;
if (height) $('#thumbPlusPreviewImage').css({ height: $('img', thumb).height() * 1.555 });
if ($(thumb).attr('href'))
$('#thumbPlusPreviewLink').attr('href', $(thumb).attr('href'));
else
$('#thumbPlusPreviewLink').attr('href', $('a', thumb).attr('href'));
$('#thumbPlusPreviewLink').addClass('show');
}
addGlobalStyle(`
#thumbPlusPreviewLink {
background-color: white;
position: absolute;
top: 0px;
left: 0px;
display: none;
z-index: 999999;
}
#thumbPlusPreviewLink.show {
display: block;
}
#thumbPlusPreview {
display: flex;
top: 0;
left: 0;
border: 2px solid black;
border-radius: 5px;
flex-direction: column !important;
align-content: center !important;
justify-content: center !important;
align-items: center !important;
flex-grow: 4 !important;
margin-left: -50px;
margin-top: -50px;
width: 280px;
min-height: 280px;
max-height: 380px;
}
#thumbPlusPreviewImage {
width: calc(100% * 0.833);
height: calc(100% * 0.833);
margin-left: auto;
margin-right: auto;
background-repeat: no-repeat;
background-position: center top;
background-size: contain;
}
.thumbPlusPreviewIcon {
display: none;
height: 32px;
width: 32px;
background-color: #fff5;
border-radius: 3px;
padding: 0px;
}
#thumbPlusPreview.gif #thumbPlusPreviewGif.show,
#thumbPlusPreview.video #thumbPlusPreviewVideo.show,
#thumbPlusPreview.sound #thumbPlusPreviewSound.show,
#thumbPlusPreview.flash #thumbPlusPreviewFlash.show,
#thumbPlusPreview.straight #thumbPlusPreviewStraight.show,
#thumbPlusPreview.gay #thumbPlusPreviewGay.show,
#thumbPlusPreview.lesbian #thumbPlusPreviewLesbian.show,
#thumbPlusPreview.trans #thumbPlusPreviewTrans.show,
#thumbPlusPreview.trap #thumbPlusPreviewTrap.show,
#thumbPlusPreview.threed #thumbPlusPreview3D.show,
#thumbPlusPreview.lolishota #thumbPlusPreviewLoliShota.show,
#thumbPlusPreview.gore #thumbPlusPreviewGoreDeath.show,
#thumbPlusPreview.pregnant #thumbPlusPreviewPregnant.show,
#thumbPlusPreview.bestiality #thumbPlusPreviewBestiality.show,
#thumbPlusPreview.feet #thumbPlusPreviewFeet.show,
#thumbPlusPreview.bondage #thumbPlusPreviewBondage.show,
#thumbPlusPreview.poop #thumbPlusPreviewPoop.show,
#thumbPlusPreview.piss #thumbPlusPreviewPiss.show,
#thumbPlusPreview.group #thumbPlusPreviewGroup.show,
#thumbPlusPreview.incest #thumbPlusPreviewIncest.show,
#thumbPlusPreview.safe #thumbPlusPreviewSafe.show,
#thumbPlusPreview.questionable #thumbPlusPreviewQuestionable.show,
#thumbPlusPreview.explicit #thumbPlusPreviewExplicit.show {
display: inline-block;
}
`);
}
var xIcon = '<svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewBox="0 0 24 24"><path d="M24 20.188l-8.315-8.209 8.2-8.282-3.697-3.697-8.212 8.318-8.31-8.203-3.666 3.666 8.321 8.24-8.206 8.313 3.666 3.666 8.237-8.318 8.285 8.203z"/></svg>';
function closeZoom() {
$("#IBEZoomableImageContainer").remove();
if (alwaysShowScrollbars)
$("html").css({ overflowX: 'scroll', overflowY: 'scroll' });
else
$("html").css({ overflowX: 'auto', overflowY: 'auto' });
}
function openZoom() {
addZoomable();
$("html").css({ overflowX: 'hidden', overflowY: 'hidden' });
}
function addZoomable() {
if ($(containerDOM + ' ' + imageDOM)[0].tagName == "IMG") {
$('body').append(`
<div id="IBEZoomableImageContainer" class="show">
<div id="IBEZoomableImage">
<div id="IBEZoomableContent">
<img src="` + $(containerDOM + ' ' + imageDOM).attr('src') + `"/>
</div>
</div>
<div id="IBEZoomableImageClose">`+ xIcon + `</div>
</div>
`);
$("#IBEZoomableImageClose").click(function () { history.back(); });
$('#IBEZoomableContent img').on('load', function(){
if(wzoom) setTimeout(function(){
getWindowProps();
$('#IBEZoomableContent').css({width: contentTrueWidth + 'px', height: contentTrueHeight + 'px'});
wzoom.prepare();
}, 0);
});
addGlobalStyle(`
#IBEZoomableImageContainer {
position: fixed;
margin: 0px;
width: 100vw;
height: 100vh;
left: 0px;
top: 0px;
background-color: #0009;
z-index: 999999;
display: none;
}
#IBEZoomableImageContainer.show {
display: block;
}
#IBEZoomableImage {
position: absolute;
width: 100%;
height: 100%;
background-color:blue;
cursor: grab;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
border: 0;
background-color: gray;
overflow: hidden;
}
#IBEZoomableContent {
//width: `+ contentTrueWidth + `px;
//height: `+ contentTrueHeight + `px;
}
#IBEZoomableImageContainer img {
display: block;
height: auto;
margin: auto;
}
#IBEZoomableImageClose {
position: absolute;
width: 30px;
height: 30px;
background-color: #0005;
color: white;
cursor: pointer;
fill: white;
}
#IBEZoomableImageClose:hover {
background-color: black;
}
#IBEZoomableImageClose svg {
margin: 5px;
}
`);
var imageElement = document.getElementById('IBEZoomableContent').querySelector('img');
if (imageElement.complete) {
init();
} else {
imageElement.onload = init;
}
function init() {
var maxScale = parseInt(maxZoom);
wzoom = WZoom.create('#IBEZoomableContent', {
type: 'html',
width: imageElement.naturalWidth,
height: imageElement.naturalHeight,
maxScale: maxScale,
speed: zoomSpeed,
dragScrollableOptions: {
onGrab: function () {
document.getElementById('IBEZoomableImage').style.cursor = 'grabbing';
},
onDrop: function () {
document.getElementById('IBEZoomableImage').style.cursor = 'grab';
}
}
});
window.addEventListener('resize', function () {
wzoom.prepare();
});
}
}
}
if (enableZoomableImage && $(containerDOM + ' ' + imageDOM).length && !$(containerDOM + ' video').length) {
window.addEventListener('popstate', function (event) {
if (event.state && event.state.id && event.state.id == 'default') closeZoom();
else if (event.state && event.state.id && event.state.id == 'zoom') openZoom();
});
$(containerDOM + ' ' + imageDOM).click(function () {
var currentSrc = $(containerDOM + ' ' + imageDOM).attr('src');
history.replaceState({ id: "default" }, 'title');
history.pushState({ id: "zoom" }, '');
setTimeout(function () {
if (currentSrc == $(containerDOM + ' ' + imageDOM).attr('src')) openZoom();
else {
waitingForZoom = true;
}
}, 0)
})
}
var cumulativeOffset = function (element) {
var top = 0, left = 0;
do {
top += element.offsetTop || 0;
left += element.offsetLeft || 0;
element = element.offsetParent;
} while (element);
return {
top: top,
left: left
};
};
}
catch (e) {
console.error(e);
}
if (debugMode) console.log('End of script.');
})();