// ==UserScript== // @name LightShot (prnt.sc) random screenshot // @description Нажми R на сайте prnt.sc чтобы загрузить какой-то случайный скриншот // @author Konf // @namespace https://greasyfork.org/users/424058 // @icon https://www.google.com/s2/favicons?domain=prnt.sc&sz=32 // @version 1.0.0 // @match https://prnt.sc/* // @compatible Chrome // @compatible Opera // @compatible Firefox // @require https://cdnjs.cloudflare.com/ajax/libs/arrive/2.4.1/arrive.min.js // @run-at document-start // @grant none // @noframes // @downloadURL none // ==/UserScript== /* jshint esversion: 6 */ (function() { 'use strict'; const n = { // nodes and its queries garbage: [ 'div.image__title.image-info-item', 'div.additional', 'div.header-downloads', 'div.social', 'div.image-info' ], needed: { mainImg: { q: 'img.no-click.screenshot-image', node: null }, headerLogo: { q: 'a.header-logo' }, headerLogoParent: { q: 'div.header > div.page-constrain' } } } const garbageNodesStr = n.garbage.join(', '); document.arrive(garbageNodesStr, { existing: true }, (aNode) => { aNode.remove(); }); const css = [` .parser-icon { float: left; width: 28px; height: 28px; margin: 11px 25px 0 0; color: white; font-weight: bold; user-select: none; cursor: pointer; border: 2px solid lightgray; border-radius: 100%; outline: none; background: none; } .parser-icon--loading { /* hide text */ text-indent: -9999em; white-space: nowrap; overflow: hidden; border-top: 5px solid rgba(255, 255, 255, 0.2); border-right: 5px solid rgba(255, 255, 255, 0.2); border-bottom: 5px solid rgba(255, 255, 255, 0.2); border-left: 5px solid #ffffff; transform: translateZ(0); animation: loading 1.1s infinite linear; } @keyframes loading { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } `]; let injected = false; for (const nodeId in n.needed) { const nodeObj = n.needed[nodeId]; document.arrive(nodeObj.q, { existing: true }, (aNode) => { nodeObj.node = aNode; const neededNodesCount = Object.keys(n.needed).length; let arrivedCount = 0; for (const nodeId in n.needed) { const nodeObj = n.needed[nodeId]; if (nodeObj.node) arrivedCount++; } if (!injected && arrivedCount === neededNodesCount) { injected = true; main(); } }); } function main() { addCSS(css[0]); let fetching = false; const b = document.createElement('button'); // fetch button const bParent = n.needed.headerLogoParent.node; const bNeighbour = n.needed.headerLogo.node; b.innerText = 'R'; b.title = 'Загрузить новый случайный скриншот\nГорячая клавиша: R'; b.className = 'parser-icon'; bParent.insertBefore(b, bNeighbour); b.addEventListener('click', loader); document.addEventListener('keydown', ev => { if (ev.code !== 'KeyR') return; loader(); }); function loader() { if (fetching) return; fetching = true; b.className = 'parser-icon parser-icon--loading'; const newImgUrl = 'https://prnt.sc/' + makeId(6); fetch(newImgUrl) .then(res => res.text()) .then(body => { const tempDiv = document.createElement('div'); tempDiv.innerHTML = body; const mainImg = n.needed.mainImg.node; const fetchedImgNode = tempDiv.querySelector(n.needed.mainImg.q); if (fetchedImgNode && fetchedImgNode.src) { mainImg.src = fetchedImgNode.src; mainImg.addEventListener('load', (ev) => { fetching = false; b.className = 'parser-icon'; history.pushState(null, null, newImgUrl); }, { once: true }); } else { throw new Error( 'Failed to find a new image in fetched webpage. ' + 'URL: ' + newImgUrl ); } }) .catch(err => { console.error(err); fetching = false; b.className = 'parser-icon'; setTimeout(loader, 250); }) } window.addEventListener('popstate', (ev) => { window.location.href = window.location.href; }); } // utils --------------------------------------------- function addCSS(cssCode) { const styleEl = document.createElement("style"); styleEl.type = "text/css"; if (styleEl.styleSheet) { styleEl.styleSheet.cssText = cssCode; } else { styleEl.appendChild(document.createTextNode(cssCode)); } document.getElementsByTagName("head")[0].appendChild(styleEl); return styleEl; } function makeId(length) { const chars = 'abcdefghijklmnopqrstuvwxyz0123456789'; let result = ''; for (let i = 0, randNum; i < length; i++) { randNum = Math.floor(Math.random() * chars.length); result += chars.charAt(randNum); } return result; } // --------------------------------------------------- })();