// ==UserScript==
// @name PornHub+
// @namespace -
// @version 1.1.0
// @description Removed ads and analytics. Added filters, boss mode, etc.
// @author NotYou
// @include *pornhub.com/*
// @run-at document-end
// @license GPL-3.0-or-later
// @grant none
// ==/UserScript==
// Nerd Stuff
let style = document.createElement('style'),
h = document.createElement('div'),
fs = document.createElement('div'),
logo = document.querySelector('#headerContainer .logoWrapper'),
bodies = [],
videos = [
'https://yewtu.be/latest_version?id=XyNlqQId-nk&itag=22&local=true',
'https://yewtu.be/latest_version?id=NsUWXo8M7UA&itag=22&local=true',
'https://yewtu.be/latest_version?id=JxS5E-kZc2s&itag=22&local=true'
], images = [
'https://yewtu.be/vi/6FQsIfE7sZM/mqdefault.jpg',
'https://yewtu.be/vi/hY7m5jjJ9mM/mqdefault.jpg',
'https://yewtu.be/vi/iRXJXaLV0n4/mqdefault.jpg',
'https://yewtu.be/vi/jHWKtQHXVJg/mqdefault.jpg',
'https://yewtu.be/vi/rWNKAXAAFmY/mqdefault.jpg',
'https://yewtu.be/vi/9xLo0PBwM9U/hqdefault.jpg',
'https://yewtu.be/vi/46a97ejExuY/mqdefault.jpg',
'https://yewtu.be/vi/48bIZoOQSUI/mqdefault.jpg',
'https://yewtu.be/vi/mcYnMbJwFCA/mqdefault.jpg',
'https://yewtu.be/vi/YHFoYJ7sAlY/mqdefault.jpg',
'https://yewtu.be/vi/sRPXPkFx9wM/hqdefault.jpg',
'https://yewtu.be/vi/B0Mxj4d7lEs/mqdefault.jpg'
], search =document.querySelector('#searchInput'),
srch = search.value,
playerLocal = localStorage.getItem('mgp_player')
if(!localStorage.getItem('pp')) localStorage.setItem('pp', '{"filter": {"step": "0", "getero": "0", "bdsm": "0"}, "options": {"premium": "0", "footer": "0", "net": "0"}}')
// Clean Up Btn
document.querySelector('.networkListContent').insertAdjacentHTML('beforeend', `<li data-id="9">
<a id="cleanup-pp" class="networkTab" href="javascript:;" title="Clean up watched videos, player settings, search requests">Clean</a>
</li>`)
document.querySelector('#cleanup-pp').addEventListener('click', cleanUp)
// Ad Block
for (let i = 0; i < 10; i++) bodies.push(`body > [class*="${i}"]`)
style.textContent = `
.cookiesBanner, #pb_template, .adsbytrafficjunky, .adLinks, .adLink, #hd-rightColVideoPage > .clearfix:first-child, #popsByTrafficJunky, ${bodies.join(',')}, #videoSearchResult > :first-child:not(.userCardLi),
#welcome, .container > div[class=""] > :first-child, #vpContentContainer > div:nth-child(2) > :first-child, .video-wrapper > .hd.clear, #hotVideosSection > :first-child, #js-abContainterMain, .t8fer, .t8fer k0g8,
#footerMenu_advertising, .ad-link, #videoCategory > :first-child, body > *:not(div, template, script, style, link, ins, noscript, iframe), #photosAlbumsSection.withAd > :first-child, .gifsWrapper > ul > :first-child,
#hottestVideosSection > :first-child, .carouselOverlay, .cookiesBanner + * + * {
display: none !important;
}
#header.hasAdAlert {
grid-template-rows: unset !important;
}
#headerContainer {
padding-bottom: 10px;
}
#fast-search-pp {
position: fixed;
z-index: 2147483646;
width: 400px;
height: 40px;
padding: 16px 28px 28px 16px;
background-color: rgba(21, 21, 21, 0.57);
border-radius: 3px;
left: 32vw;
top: 20vh;
}
#fast-seach-input-parent-pp {
padding: 5px;
display: flex;
border: 0;
height: 40px;
width: 100%;
background-color: rgb(61, 54, 49);
border-radius: 3px;
}
#fast-seach-input-parent-pp .ph-icon-search {
margin-top: 10px;
margin-right: 10px;
font-size: 20px;
}
#fast-seach-input-pp {
background-color: unset;
width: 100%;
height: 100%;
font-size: 20px;
border: 0;
}
#fast-seach-input-pp::placeholder {
font-style: italic;
color: rgb(164, 164, 164);
}
#download-panel-pp {
display: grid;
margin-left: 15px;
}
#download-panel-pp .reset {
background-color: rgb(40, 40, 40);
}
#download-panel-pp h2 {
margin-left: 15px;
}
.download-panel-item-pp {
margin-left: 20px;
margin-bottom: 6px;
}
.download-panel-item-pp a {
background-color: rgb(255, 144, 0);
color: rgb(0, 0, 0);
border-radius: 4px;
padding: 2px;
margin-right: 2px;
text-decoration: none !important;
}
#download-panel-pp h2 i {
font-style: italic;
font-weight: bolder;
}`
document.head.appendChild(style)
logo.style.display = 'flex'
logo.insertAdjacentHTML('beforeend', '<i class="ph-icon-add" style="margin-top: 10px;font-size: 20px;"></i>')
// Boss Mode
h.id = 'bossMode'
h.style.width = '100%'
h.style.height = '100vh'
h.style.backgroundColor = 'rgb(255, 255, 255)'
h.style.position = 'fixed'
h.style.left = '0px'
h.style.top = '0px'
h.style.zIndex = '2147483647'
h.style.display = 'none'
h.innerHTML = `
<div style="
height: 70px;
width: 100%;
display: flex;
background: rgb(238, 238, 238);
">
<img src="https://icons.iconarchive.com/icons/papirus-team/papirus-apps/512/anki-icon.png" style="
height: 8vh;
margin-left: 1vw;
margin-top: 1vh;
">
<input type="text" style="
border: 0px !important;
background: rgb(200, 200, 200);
margin: 0 3vw;
width: 70%;
margin-top: 10px !important;
margin-bottom: -10px !important;
color: rgb(15, 15, 15);
padding: 8px;
height: 30px;
border-radius: 25px;
padding-left: 20px;
">
<span style="
border-radius: 20px;
width: 12vw;
height: 20px;
background: rgb(193, 193, 193);
margin-top: 22px;
"></span>
<span style="
border-radius: 50%;
background: rgb(193, 193, 193);
width: 50px;
height: 50px;
margin: 7px 2px 0 2vw;
"></span></div>
<div style="
height: 100%;
width: 100%;
display: flex;
">
<div style="
width: 70%;
height: 60%;
margin-left: 20px;
padding-top: 20px;
">
<video controls="true" src="${videos[~~(Math.random()*videos.length)]}" style="
width: 50vw;
height: 50vh;
"></video>
</div>
<div style="
width: 40vw;
height: 100%;
padding-left: 30px;
padding-top: 30px;
background: rgb(253, 253, 253);
">
<img src="${images[~~(Math.random() * images.length)]}" style="
width: 25vw;
">
<img src="${images[~~(Math.random() * images.length)]}" style="
width: 25vw;
">
<img src="${images[~~(Math.random() * images.length)]}" style="
width: 25vw;
"></div>
</div>`
document.body.appendChild(h)
window.addEventListener('keydown', bossMode)
// No Autoplay
if(playerLocal) {
let p = JSON.parse(playerLocal)
if(p.autoplay != true) p.autoplay = false
localStorage.setItem('mgp_player', JSON.stringify(p))
}
// Remove Analytics / Nerd Stuff v2
document.querySelectorAll('[onclick]').forEach(e => {
if(e.getAttribute('onclick').includes('ga(', '')) e.setAttribute('onclick', e.getAttribute('onclick').replace(/ga\(.+\);?/, ''))
})
document.querySelectorAll('[onclick=""]').forEach(e => e.removeAttribute('onclick'))
// Fast Search
fs.id = 'fast-search-pp'
fs.innerHTML = '<span id="fast-seach-input-parent-pp"><i class="ph-icon-search"></i><input id="fast-seach-input-pp" type="text" placeholder="Fast Search Pornhub"></span>'
fs.style.display = 'none'
let fsi = fs.children[0].children[1],
fsb = fs.children[0].children[0]
fsi.onkeydown = fastSearch
fsb.onclick = fastSearch
document.body.appendChild(fs)
window.addEventListener('keydown', e => {
console.log(e)
if(e.ctrlKey && (e.key === 'k' || e.code === 'KeyK')) {
console.log('EVENT', e)
e.preventDefault()
hide('#fast-search-pp')
fsi.focus()
}
})
// Filters & Better Watch Pages
var step = [
'step',
'mom', 'mother', 'mommy', 'milf',
'dad', 'father', 'daddy',
'bro', 'brother',
'sis', 'sister',
'daughter',
'son',
'brattysis', 'myfamilypies', 'momsteachsex',
'mylf', 'sis loves me', 'mommy\'s girl',
'family sinners', 'pervmom', 'perv mom',
'dad crush', 'spyfam', 'spy fam'
], get = [
'lesbian',
'gay', 'homo', 'homosexual',
' bi ', 'bisexual',
'trans', 'transgender',
'helloladyboy', 'mommy\'s girl', 'girlsway'
], hard = [
'hardcore',
'bdsm',
'biting',
'scratching',
' dom ', 'femdom', 'maledom', 'domination',
' wax ', 'waxing',
' gag ', 'gagging',
' whip ', 'whiping',
' tied ', 'tying',
'bondage'
],
url = new URL(location.href)
if(url.searchParams.has('viewkey')) {
let medDef = window[`flashvars_${window.VIDEO_SHOW.video_id}`].mediaDefinitions, urlToParse = medDef[medDef.length-1].videoUrl
await (async function() {
if(urlToParse) {
await fetch(urlToParse)
.then(c => c.json())
.then(r => window.media = r)
}
})()
document.querySelector('#js-shareData > .tab-menu-wrapper-row').insertAdjacentHTML('beforeend', `
<div class="tab-menu-wrapper-cell">
<a href="https://www.pornhub.com/embed/${window.currentVkey}" target="_self">
<div id="embed_mode-btn" class="flag-btn tab-menu-item tooltipTrig" data-title="Open video in embed mode" role="button" tabindex="0">
<i class="ph-icon-channel"></i>
<span>Embed</span>
</div>
</a>
</div>`.replaceAll('\n', ''))
let dw = document.createElement('div'), t = document.querySelector('.title-container > .title > span')
dw.id = 'download-panel-pp'
t.title = 'Click to copy'
t.onclick = () => navigator.clipboard.writeText(t.innerText)
dw.innerHTML = `<h2>${window.TRANSLATED_MESSAGE.save}</h2>`
window.media.reverse().forEach(e =>
dw.innerHTML += `<span class="download-panel-item-pp"><a href="${e.videoUrl}" target="_blank">${e.quality}p</a>${+e.quality > 719 ? '<i class="ph-icon-hd"></i>' : ''}</span>`
)
dw.innerHTML += '<div class="reset"></div>'
document.querySelector('.video-wrapper > .video-actions-container').insertAdjacentElement('beforebegin', dw)
}
if(url.searchParams.has('search')||url.searchParams.has('page')||url.searchParams.has('o')||(location.pathname === '/video' && url.searchParams.toString() === '')) {
document.querySelector('#duration-wrapper').previousElementSibling.outerHTML = `
<div class="section_bar_sidebar"><div class="section_title"><i class="ph-icon-filter"></i> Filter <span class="subtitle">( PornHub+ )</span></div></div>
<div class="sidebar_wrapper">
<!-- pp = (P)ornhub (P)lus -->
<ul class="nf-categories" id="pp-filter">
<li>
<a class="sidebarIndent pp-a" id="ppStepLike" href="javascript:;">
Hide Step-like
</a>
</li>
<li>
<a class="sidebarIndent pp-a" id="ppNonGetero" href="javascript:;">
Hide Non-Getero
</a>
</li>
<li class="sidebarIndent">
<a class="sidebarIndent pp-a" id="ppHardcore" href="javascript:;">
Hide BDSM & Hardcore
</a>
</li>
</ul>
</div>
<div class="section_bar_sidebar"><div class="section_title"><i class="ph-icon-toolbox"></i> Options <span class="subtitle">( PornHub+ )</span></div></div>
<div class="sidebar_wrapper">
<ul class="nf-categories" id="pp-filter">
<li>
<a class="sidebarIndent pp-a" id="ppPremVids" href="javascript:;">
Hide Paid Premium Videos
</a>
</li>
<li>
<a class="sidebarIndent pp-a" id="ppFooter" href="javascript:;">
Hide Footer
</a>
</li>
<li class="sidebarIndent">
<a class="sidebarIndent pp-a" id="ppNetbar" href="javascript:;">
Hide Networkbar
</a>
</li>
</ul>
</div>
<div class="section_bar_sidebar"><div class="section_title">Duration <span class="subtitle">( minutes )</span></div></div>`
document.querySelectorAll('.pp-a').forEach(e =>
e.addEventListener('click', () => (e.style.color = (e.style.color == 'rgb(255, 153, 0)'||e.style.color == '#f90' ? 'unset' : 'rgb(255, 153, 0)')))
)
let step = document.querySelector('#ppStepLike'),
geter = document.querySelector('#ppNonGetero'),
hardc = document.querySelector('#ppHardcore'),
prem = document.querySelector('#ppPremVids'),
foot = document.querySelector('#ppFooter'),
net = document.querySelector('#ppNetbar'),
pp = JSON.parse(localStorage.getItem('pp'))
for (let i of [
[step, 'step', hideStepLike],
[geter, 'getero', () => hideVideo(get)],
[hardc, 'bdsm', () => hideVideo(hard)],
[prem, 'premium', () => hide('.nf-videos > .sectionWrapper > .reset + .sectionWrapper'), true],
[foot, 'footer', () => hide('#footer'), true],
[net, 'net', () => hide('#js-networkBar'), true]
]) {
let i3 = i[3] ? 'options' : 'filter'
i[0].addEventListener('click', () => {
ppControl(i3, i[1])
i[2]()
})
if(pp[i3][i[1]] === '1') {
i[0].click()
ppControl(i3, i[1])
}
}
}
// Change Stars
if(url.pathname.indexOf('/pornstar/') != -1||url.pathname.indexOf('model') != -1) {
window.addEventListener('keydown', e => {
if((e.key === 'ArrowRight'||e.key === 'ArrowLeft') && e.shiftKey) {
e.preventDefault()
document.querySelector(`.pornstarsNavButtons > a${e.key === 'ArrowRight' ? ':last-child' : ':first-child'}`).click()
}
})
}
// Nerd Stuff v3
function hideStepLike() {
document.querySelectorAll('.clearfix > .title > a').forEach(e => {
step.forEach(i => {
let title = e.innerText.toLowerCase(), video = e.parentNode.parentNode.parentNode.parentNode
if(title.match(`.?step.?${i}.?`)||title.match(`.?${i}.?`)) {
if(video.style.display == 'none') video.style.display = ''
else video.style.display = 'none'
}
})
})
}
function hideVideo(arr) {
document.querySelectorAll('.clearfix > .title > a').forEach(e => {
arr.forEach(i => {
let title = e.innerText.toLowerCase(), video = e.parentNode.parentNode.parentNode.parentNode
if(title.match(`.?${i}.?`)) video.style.display = video.style.display === 'none' ? '' : 'none'
})
})
}
function hide(selector) {
let el = document.querySelector(selector)
if(el) el.style.display = el.style.display == 'none' ? 'unset' : 'none'
}
function bossMode(e) {
if(e.key === '`') {
document.title = 'Funny kitty videos - YouTurb'
document.head.innerHTML += '<link rel="shortcut icon" href="https://icons.iconarchive.com/icons/papirus-team/papirus-apps/512/anki-icon.png" type="image/x-icon">'
hide('#bossMode')
document.querySelectorAll('video').forEach(e => {
if(e && e.pause) e.pause()
})
}
}
function ppControl(parent, child) {
let pp = JSON.parse(localStorage.getItem('pp'))
pp[parent][child] = pp[parent][child] === '0' ? '1' : '0'
localStorage.setItem('pp', JSON.stringify(pp))
}
function cleanUp() {
for (let i of ['watchedVideoStorage', 'watchedVideoIds', 'recentSearch', 'currentTimeStamp', 'mgp_player']) if(localStorage.getItem(i)) localStorage.removeItem(i)
}
function fastSearch(e) {
function search() {
let input = fsi.value.replaceAll(/[^0-9a-zA-Z\s-]+/g, ''),
recSearch = localStorage.getItem('recentSearch')
if(!recSearch) localStorage.setItem('recentSearch', '[]')
let parsed = JSON.parse(recSearch)
parsed.push(input)
localStorage.setItem('recentSearch', JSON.stringify(parsed))
location.replace('https://www.pornhub.com/video/search?search='+input.replaceAll(/\s/g, '+'))
}
if((e.type === 'keydown' && e.key === 'Enter') || e.type === 'click') search()
}
console.log(
`Porn%cHub%c+ Loaded! (Time: ${new Date().toLocaleTimeString()}; Document State: ${document.readyState})`,
'background: #f90;color: #000;border-radius: 3px;padding: 1px;margin-right: -5px;'
)
// There is some eggs...
if([...Array(100).keys()][~~(Math.random() * 100)] === 99) {
logo.querySelector('img').src = [
'https://di.phncdn.com/pics/logos/571.png',
'https://di.phncdn.com/pics/logos/2001.png',
'https://di.phncdn.com/pics/logos/2221.png',
'https://di.phncdn.com/pics/logos/4851.png',
'https://di.phncdn.com/pics/logos/4931.png',
'https://di.phncdn.com/pics/logos/5901.png',
'https://di.phncdn.com/pics/logos/7191.png',
'https://di.phncdn.com/pics/logos/7291.png'
][~~(Math.random() * 8)]
}