LightShot (prnt.sc) random screenshot

Press R on prnt.sc website to load some random screenshot

当前为 2021-11-24 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name             LightShot (prnt.sc) random screenshot
// @description      Press R on prnt.sc website to load some random screenshot
//
// @name:ru          Lightshot (prnt.sc) случайный скриншот
// @description:ru   Нажми 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.1.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-body
// @grant            GM_addStyle
// @noframes
// ==/UserScript==

/* jshint esversion: 6 */

(function() {
  'use strict';

  const langStrings = {
    en: {
      getNewRandImg: 'Load new random screenshot',
      hotkey: 'Hotkey',
    },
    ru: {
      getNewRandImg: 'Загрузить новый случайный скриншот',
      hotkey: 'Горячая клавиша',
    },
  };
  const userLang = navigator.language.slice(0, 2);
  const i18n = langStrings[userLang || 'en'];

  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);
      }
    }
  `].join();

  // node queries
  const qs = {
    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',
        node: null,
      },
      headerLogoParent: {
        q: 'div.header > div.page-constrain',
        node: null,
      },
    }
  };

  document.arrive(qs.garbage.join(', '), { existing: true }, n => n.remove());

  let injected = false;

  for (const nodeId in qs.needed) {
    const nodeObj = qs.needed[nodeId];

    // eslint-disable-next-line no-loop-func
    document.arrive(nodeObj.q, { existing: true }, (aNode) => {
      nodeObj.node = aNode;

      const neededNodesCount = Object.keys(qs.needed).length;
      let arrivedCount = 0;

      for (const nodeId in qs.needed) {
        const nodeObj = qs.needed[nodeId];

        if (nodeObj.node) arrivedCount++;
      }

      if (injected === false && arrivedCount === neededNodesCount) {
        injected = true;
        main();
      }
    });
  }


  function main() {
    GM_addStyle(css);

    const b = document.createElement('button'); // fetch button
    const bParent = qs.needed.headerLogoParent.node;
    const bNeighbour = qs.needed.headerLogo.node;

    b.innerText = 'R';
    b.title = `${i18n.getNewRandImg}\n${i18n.hotkey}: R`;
    b.className = 'parser-icon';
    bParent.insertBefore(b, bNeighbour);

    b.addEventListener('click', loader);
    document.addEventListener('keydown', ev => {
      if (ev.code !== 'KeyR') return;

      loader();
    });

    let fetching = false;

    async function loader() {
      if (fetching) return;

      fetching = true;
      b.className = 'parser-icon parser-icon--loading';

      const newImgUrl = 'https://prnt.sc/' + makeId(6);

      try {
        const response = await fetch(newImgUrl);
        const tempDiv = document.createElement('div');

        tempDiv.innerHTML = await response.text();

        const mainImg = qs.needed.mainImg.node;
        const fetchedImgNode = tempDiv.querySelector(qs.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 (e) {
        console.error(e);

        fetching = false;
        b.className = 'parser-icon';

        setTimeout(loader, 250);
      }
    }

    window.addEventListener('popstate', reloadPage);
  }


  // utils ---------------------------------------------

  function reloadPage() {
    window.location.href = window.location.href;
  }

  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;
  }

  // ---------------------------------------------------
})();