// ==UserScript==
// @author LD
// @version 1.0
// @name xHamster Plus
// @description A kinder xHamster. Because you're worth it.
// @namespace LD
// @date 2018-08-08
// @include *xhamster.com/*
// @run-at document-start
// @grant none
// @license Public Domain
// @icon https://static-cl.xhcdn.com/xh-tpl3/images/favicon/apple-touch-icon.png
// @grant GM_addStyle
// ==/UserScript==
(() => {
/* Available options */
const options = {
autoresizePlayer:
JSON.parse(localStorage.getItem('plus_autoresizePlayer')) || false
}
/* Empty tag function, for VS Code syntax highlight for CSS in literals */
const css = (strings, ...values) => {
/* Re-assemble input string and return untouched */
return strings.reduce((output, string, index) => {
return `${output}${string}${values[index] || ''}`;
}, '');
};
/* Styles - Shared between all "Plus" userscripts */
const sharedStyles = css`
/* Our own elements */
.plus-buttons {
background: rgba(67, 67, 67, 0.85);
box-shadow: 0px 0px 12px rgba(20, 111, 223, 0.85);
font-size: 12px;
position: fixed;
bottom: 10px;
padding: 10px 22px 8px 24px;
right: 0;
z-index: 100;
transition: all 0.3s ease;
/* Negative margin-right calculated later based on width of buttons */
}
.plus-buttons:hover {
box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3);
}
.plus-buttons .plus-button {
margin: 10px 0;
padding: 6px 15px;
border-radius: 4px;
font-weight: 700;
display: block;
position: relative;
text-align: center;
vertical-align: top;
cursor: pointer;
border: none;
text-decoration: none;
}
.plus-buttons a.plus-button {
background: rgb(221, 221, 221);
color: rgb(51, 51, 51);
}
.plus-buttons a.plus-button:hover {
background: rgb(187, 187, 187);
color: rgb(51, 51, 51);
}
.plus-buttons a.plus-button.plus-button-isOn {
background: rgb(20, 111, 223);
color: rgb(255, 255, 255);
}
.plus-buttons a.plus-button.plus-button-isOn:hover {
background: rgb(0, 91, 203);
color: rgb(255, 255, 255);
}
.plus-hidden {
display: none !important;
}
`;
/* Styles - Color theme */
const themeStyles = css`
.plus-buttons {
box-shadow: 0px 0px 18px rgba(227, 68, 73, 1);
}
.plus-buttons:hover {
box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3);
}
.plus-buttons a.plus-button {
background: rgb(218, 218, 218);
color: rgb(48, 48, 48);
}
.plus-buttons a.plus-button:hover {
background: rgb(204, 204, 204);
color: rgb(48, 48, 48);
}
.plus-buttons a.plus-button.plus-button-isOn {
background: rgb(227, 68, 73);
color: rgb(255, 255, 255);
}
.plus-buttons a.plus-button.plus-button-isOn:hover {
background: rgb(212, 32, 37);
color: rgb(255, 255, 255);
}
`;
/* Styles - General site-specific */
const generalStyles = css`
/* Hide elements */
.up-arrow,
.premium-overlay,
.bottom-widget-section,
.clipstore-bottom,
.wid-spot-container,
.wid-banner-container {
display: none !important;
}
/* Increase large player size */
.video-page.video-page--large-mode .player-container__player {
height: 720px;
}
/* Show all playlists without scrolling when adding to favorites */
.favorites-dropdown__list {
max-height: unset !important;
}
.video-page:not(.video-page--large-mode) .player-container {
margin: 10px auto 0;
}
.video-page:not(.video-page--large-mode) .entity-container,
.video-page:not(.video-page--large-mode) .comments-wrap {
margin: 0 auto;
}
/* Minor stylistic improvements */
.entity-container {
margin: 22px 0;
margin-bottom: 22px;
border-top: 1px solid #ccc;
}
`;
/*
* Run after page has loaded
*/
window.addEventListener('DOMContentLoaded', () => {
const player = document.querySelector('#player-container');
const video = document.querySelector('#player-container video');
/*
* Use wide player by default
*/
if (video && options.autoresizePlayer) {
/* Button is not always available right away -- wait for `canplay` */
video.addEventListener('canplay', function onCanPlay() {
let largePlayerButton = document.querySelector('.large-mode');
/* Click large player button */
largePlayerButton.dispatchEvent(new MouseEvent('click'));
/* Only run once */
video.removeEventListener('canplay', onCanPlay, false);
});
}
/*
* Add buttons for certain options
*/
/* Buttons container */
let buttons = document.createElement('div');
let scrollButton = document.createElement('a');
let scrollButtonText = document.createElement('span');
let autoresizeButton = document.createElement('a');
let autoresizeButtonText = document.createElement('span');
let autoresizeButtonState = options.autoresizePlayer ? 'plus-button-isOn' : 'plus-button-isOff';
buttons.classList.add('plus-buttons');
scrollButtonText.textContent = "Scroll to top";
scrollButtonText.classList.add('text');
scrollButton.appendChild(scrollButtonText);
scrollButton.classList.add('plus-button');
scrollButton.addEventListener('click', () => {
window.scrollTo({ top: 0 });
});
buttons.appendChild(scrollButton);
buttons.appendChild(autoresizeButton);
autoresizeButtonText.textContent = 'Auto-resize player';
autoresizeButtonText.classList.add('text');
autoresizeButton.appendChild(autoresizeButtonText);
autoresizeButton.classList.add(autoresizeButtonState, 'plus-button');
autoresizeButton.addEventListener('click', () => {
options.autoresizePlayer = !options.autoresizePlayer;
localStorage.setItem('plus_autoresizePlayer', options.autoresizePlayer);
if (options.autoresizePlayer) {
autoresizeButton.classList.replace('plus-button-isOff', 'plus-button-isOn');
} else {
autoresizeButton.classList.replace('plus-button-isOn', 'plus-button-isOff');
}
});
document.body.appendChild(buttons);
/*
* Add styles
*/
GM_addStyle(sharedStyles);
GM_addStyle(themeStyles);
GM_addStyle(generalStyles);
/*
* Add dynamic styles
*/
const dynamicStyles = css`
.plus-buttons {
margin-right: -${buttons.getBoundingClientRect().width - 23}px;
}
.plus-buttons:hover {
margin-right: 0;
}
.video-page.video-page--large-mode .player-container__player {
max-height: ${window.innerHeight - 60}px;
}
`;
GM_addStyle(dynamicStyles);
if (player) {
window.addEventListener('resize', () => {
if (player.classList.contains('xplayer-large-mode')) {
player.style.maxHeight = `${window.innerHeight - 60}px`;
}
});
}
});
})();