Redgifs download button

2/2/2026, 7:08:27 PM

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да инсталирате разширение, като например Tampermonkey .

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @name        Redgifs download button
// @namespace   Violentmonkey Scripts
// @match       https://www.redgifs.com/*
// @license       GPL-3.0-or-later
// @version     1.0
// @author      pr0nusr
// @description 2/2/2026, 7:08:27 PM
// ==/UserScript==
async function dl({src}, title) {
    const extension = (document.querySelector("video").src.substring(0, 4) == "blob") ? 'm4s' : 'mp4';
    const u = `${src.substring(0, src.length - 11)}.${extension}`;

    const response = await fetch(u);
    const blob = await response.blob();

    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");

    a.href = url;
    a.download = u;
    document.body.appendChild(a);
    a.click();

    document.body.removeChild(a);
    URL.revokeObjectURL(url);
}

const createButton = (parent) => {
    if (parent.className.includes('StreamateCameraDispatch')) {
      parent.parentNode.remove();
      return;
    }
    if (parent.children.length === 0) {
      parent.dataset.buttonadded = false;
      return
    }
    if (parent.dataset.buttonadded === 'true' && ( parent.className.includes('GifPreview_isVideo') ||  parent.className.includes('GifPreview_isActive'))) {
      return;
    }
    if (parent.dataset.buttonadded === 'true' && !parent.className.includes('GifPreview_isVideo')) {
      parent.dataset.buttonadded = false;
    }

    const dlProps = {
      id: 'redgifs_dl_button',
      className: 'LikeButton',
      style: 'margin-bottom: 20px',
      onclick: () => dl(parent.querySelector('img.Player-Poster'))
    };

    const dl_button = Object.assign(document.createElement("button"), dlProps);
    dl_button.dataset.itemId= parent.dataset.feedItemId;

    const svgElement = document.createElement('svg');
    svgElement.innerHTML = `
        <svg
        width="30"
        height="20"
        viewBox="0 0 24 24"
        fill="none"
        xmlns="http://www.w3.org/2000/svg"
        >
        <path
            d="M5 3h11l3 3v15a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1Z"
            stroke="white"
            stroke-width="1"
            stroke-linejoin="round"
        />
        <path
            d="M7 3v6h8V3"
            stroke="white"
            stroke-width="1"
            stroke-linejoin="round"
        />
        <rect
            x="7"
            y="14"
            width="10"
            height="6"
            stroke="white"
            stroke-width="1"
            rx="1"
        />
        </svg>
    `;
    dl_button.appendChild(svgElement);
    const sidebarChildren = parent.getElementsByClassName('sideBar')[0]?.children;
    if (sidebarChildren) {
        const childrenLength = Object.keys(sidebarChildren).length
        const insertTarget = sidebarChildren.item(childrenLength -1)
        insertTarget.parentNode.insertBefore(dl_button, insertTarget);
        parent.dataset.buttonadded = 'true';
    }
}

let append_dl_button_interval = setInterval(() => {
    const nodes = document.querySelectorAll('.GifPreview')
    nodes.forEach(createButton)
}, 500);