Instagram: Download Photo & Video

Download photo or video by one button click.

As of 2019-10-06. See the latest version.

// ==UserScript==
// @name         Instagram: Download Photo & Video
// @description  Download photo or video by one button click.
// @namespace	 https://github.com/HayaoGai
// @version      1.0.0
// @icon         https://i.imgur.com/obCmlr9.png
// @author       Hayao-Gai
// @match        https://www.instagram.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    const icon = "https://i.imgur.com/NNpZm8Q.png";

    window.onload = () => {
        condition();
        detectAddress();
    }

    function addButton() {
        // Create
        const outside = document.createElement("span");
        outside.id = "download";
        const middle = document.createElement("button");
        middle.classList.add("dCJp8");
        middle.classList.add("afkep");
        const inside = document.createElement("img");
        inside.src = icon;
        // Append
        middle.appendChild(inside);
        outside.appendChild(middle);
        document.querySelector(".wmtNn").before(outside);
        // Add Event
        middle.addEventListener("click", download);
    }

    function download() {
        let link = "";
        if (!document.querySelector("video")) {
            // Photo
            const ffvads = document.querySelectorAll(".FFVAD");
            ffvads.forEach(ffvad => {
                if (ffvad.srcset.includes("1080w")) {
                    link = ffvad.src;
                }
            });
        } else {
            // Video
            link = document.querySelector("video").src;
        }
        const time = new Date();
        const filename = getTime();
        fetch(link).then(t => {
            return t.blob().then(b => {
                const a = document.createElement("a");
                a.href = URL.createObjectURL(b);
                a.setAttribute("download", filename);
                a.click();
            });
        });
    }

    function getTime() {
        const time = new Date();
        const year = time.getFullYear().toString();
        let month = time.getMonth() + 1;
        let day = time.getDate();
        let hour = time.getHours();
        let minute = time.getMinutes();
        let second = time.getSeconds();
        month = addZero(month);
        day = addZero(day);
        hour = addZero(hour);
        minute = addZero(minute);
        second = addZero(second);
        return year + month + day + hour + minute + second;
    }

    function addZero(value) {
        if (value < 10) value = "0" + value.toString();
        return value;
    }

    function detectAddress() {
        window.addEventListener('locationchange', () => {
            for (let i = 0; i < 10; i++) {
                setTimeout(condition, 500 * i);
            }
        });
        history.pushState = ( f => function pushState(){
            var ret = f.apply(this, arguments);
            window.dispatchEvent(new Event('pushState'));
            window.dispatchEvent(new Event('locationchange'));
            return ret;
        })(history.pushState);
        history.replaceState = ( f => function replaceState(){
            var ret = f.apply(this, arguments);
            window.dispatchEvent(new Event('replaceState'));
            window.dispatchEvent(new Event('locationchange'));
            return ret;
        })(history.replaceState);
        window.addEventListener('popstate', () => {
            window.dispatchEvent(new Event('locationchange'))
        });
    }

    function condition() {
        const button = document.getElementById("download");
        const section = document.querySelectorAll("section").length;
        if (!!button) {
            if (section < 3) {
                button.remove();
            }
        } else {
            if (section > 2) {
                addButton();
            }
        }
    }
})();