Show the sub-studio of a Brazzers scene.
Installation requires a browser extension such as Violentmonkey / Tampermonkey / Greasemonkey.
Show the sub-studio of a Brazzers scene.
Installation requires a browser extension such as Violentmonkey / Tampermonkey / Greasemonkey.
// ==UserScript== | |
// @name Brazzers sub-studio | |
// @author peolic | |
// @version 0.4 | |
// @description Show the sub-studio of a Brazzers scene. | |
// @icon https://images-assets-ht.project1content.com/Brazzers/Common/Logos/5cdee386f183d3.00246963.png | |
// @namespace https://github.com/peolic | |
// @match https://www.brazzers.com/video/* | |
// @grant none | |
// @homepageURL https://gist.github.com/peolic/6f5cfc69251e36c755c2948d82529460 | |
// @downloadURL https://gist.github.com/peolic/6f5cfc69251e36c755c2948d82529460/raw/brazzers-sub-studio.user.js | |
// @updateURL https://gist.github.com/peolic/6f5cfc69251e36c755c2948d82529460/raw/brazzers-sub-studio.user.js | |
// ==/UserScript== | |
const main = async () => { | |
injectSubStudio(); | |
window.addEventListener(locationChanged, async () => { | |
removeSubStudio(); | |
await wait(500); | |
injectSubStudio(); | |
}); | |
}; | |
const removeSubStudio = () => document.querySelector('#userscript-sub-studio')?.remove(); | |
const injectSubStudio = async () => { | |
const getter = () => { | |
const playerSection = Array.from(document.querySelectorAll('section')).find((section) => !!section.querySelector('video')); | |
if (!playerSection) return undefined; | |
const reactInstance = playerSection[Object.getOwnPropertyNames(playerSection).find((p) => p.startsWith('__reactInternalInstance$'))]; | |
if (!reactInstance) return undefined; | |
return reactInstance.return?.return?.return?.return?.return?.return?.memoizedProps?.release; | |
}; | |
let attempt = 0; | |
let release = getter(); | |
while (!release) { | |
if (attempt === 10) return undefined; | |
attempt++; | |
await wait(500); | |
release = getter(); | |
} | |
if (!release) | |
return; | |
const collections = release.getCollections(); | |
const collectionName = collections.map((c) => c.name).join(' [or] '); | |
const titleSection = Array.from(document.querySelectorAll('section')).find((section) => !!section.querySelector('h2')); | |
const dateEl = titleSection.querySelector('h2').previousElementSibling; | |
const collectionEl = dateEl.cloneNode(true); | |
collectionEl.id = 'userscript-sub-studio'; | |
collectionEl.innerText = collectionName; | |
Object.assign(collectionEl.style, { | |
placeSelf: 'center', | |
fontWeight: 'bold', | |
color: '#70bf44', | |
}); | |
dateEl.after(collectionEl); | |
}; | |
const wait = (/** @type {number} */ ms) => new Promise((resolve) => setTimeout(resolve, ms)); | |
// Based on: https://dirask.com/posts/JavaScript-on-location-changed-event-on-url-changed-event-DKeyZj | |
const locationChanged = (function() { | |
const { pushState, replaceState } = history; | |
// @ts-expect-error | |
const prefix = GM.info.script.name | |
.toLowerCase() | |
.trim() | |
.replace(/[^a-z0-9 -]/g, '') | |
.replace(/\s+/g, '-'); | |
const eventLocationChange = new Event(`${prefix}$locationchange`); | |
history.pushState = function(...args) { | |
pushState.apply(history, args); | |
window.dispatchEvent(new Event(`${prefix}$pushstate`)); | |
window.dispatchEvent(eventLocationChange); | |
} | |
history.replaceState = function(...args) { | |
replaceState.apply(history, args); | |
window.dispatchEvent(new Event(`${prefix}$replacestate`)); | |
window.dispatchEvent(eventLocationChange); | |
} | |
window.addEventListener('popstate', function() { | |
window.dispatchEvent(eventLocationChange); | |
}); | |
return eventLocationChange.type; | |
})(); | |
main(); |