Greasy Fork

FIXED Pinterest - Save Original Image

Save the original (largest) image in a new tab by pressing 'z' while hovering over a pin

// ==UserScript==
// @name         FIXED Pinterest - Save Original Image
// @namespace    http://tampermonkey.net/
// @version      5.2.1
// @description  Save the original (largest) image in a new tab by pressing 'z' while hovering over a pin
// @author       creve
// @include      https://*.pinterest.tld/*
// @grant        GM_openInTab
// @grant        GM_download

// @noframes
// @license      MIT
// @compatible   firefox Firefox
// @compatible   chrome Chrome
// ==/UserScript==

(function() {
    'use strict';

    // Custom key. Only single letters.
    const KEY_TO_OPEN = "z";
    function showImage()
    {
        const imageUrl = getOriginalImage();
        if (imageUrl && /\.(?:jpe?g|png|gif|webp)$/.test(imageUrl)) {
            var fileName = CurentTime() + "—" + imageUrl.substr(imageUrl.lastIndexOf("/"));
            download3(imageUrl, fileName);
        }

        // } else {
        // 	let fileName = CurentTime() + "—" + imageUrl.substr(imageUrl.lastIndexOf("/"));
        // 	saveBlob(imageUrl, fileName);
        // }
    }

    function download3(data, strFileName){
        var x=new XMLHttpRequest();
        x.open("GET", data, true);
        x.responseType = 'blob';
        x.onload=function(e){download(x.response, strFileName, "image/gif" ); }
        x.send();
    }

    function download(data, strFileName, strMimeType) {
        var self = window, // this script is only for browsers anyway...
            u = "application/octet-stream", // this default mime also triggers iframe downloads
            m = strMimeType || u,
            x = data,
            D = document,
            a = D.createElement("a"),
            z = function(a){return String(a);},


            B = self.Blob || self.MozBlob || self.WebKitBlob || z,
            BB = self.MSBlobBuilder || self.WebKitBlobBuilder || self.BlobBuilder,
            fn = strFileName || "download",
            blob,
            b,
            fr;

        //if(typeof B.bind === 'function' ){ B=B.bind(self); }

        if(String(this)==="true"){ //reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback
            x=[x, m];
            m=x[0];
            x=x[1];
        }
        //go ahead and download dataURLs right away
        if(String(x).match(/^data\:[\w+\-]+\/[\w+\-]+[,;]/)){
            return navigator.msSaveBlob ?  // IE10 can't do a[download], only Blobs:
                navigator.msSaveBlob(d2b(x), fn) :
            saver(x) ; // everyone else can save dataURLs un-processed
        }//end if dataURL passed?

        try{

            blob = x instanceof B ?
                x :
            new B([x], {type: m}) ;
        }catch(y){
            if(BB){
                b = new BB();
                b.append([x]);
                blob = b.getBlob(m); // the blob
            }

        }
        function d2b(u) {
            var p= u.split(/[:;,]/),
                t= p[1],
                dec= p[2] == "base64" ? atob : decodeURIComponent,
                bin= dec(p.pop()),
                mx= bin.length,
                i= 0,
                uia= new Uint8Array(mx);

            for(i;i<mx;++i) uia[i]= bin.charCodeAt(i);

            return new B([uia], {type: t});
        }
        function saver(url, winMode){
            if ('download' in a) { //html5 A[download]
                a.href = url;
                a.setAttribute("download", fn);
                a.innerHTML = "downloading...";
                D.body.appendChild(a);
                setTimeout(function() {
                    a.click();
                    D.body.removeChild(a);
                    if(winMode===true){setTimeout(function(){ self.URL.revokeObjectURL(a.href);}, 250 );}
                }, 66);
                return true;
            }

            //do iframe dataURL download (old ch+FF):
            var f = D.createElement("iframe");
            D.body.appendChild(f);
            if(!winMode){ // force a mime that will download:
                url="data:"+url.replace(/^data:([\w\/\-\+]+)/, u);
            }


            f.src = url;
            setTimeout(function(){ D.body.removeChild(f); }, 333);

        }//end saver


        if (navigator.msSaveBlob) { // IE10+ : (has Blob, but not a[download] or URL)
            return navigator.msSaveBlob(blob, fn);
        }

        if(self.URL){ // simple fast and modern way using Blob and URL:
            saver(self.URL.createObjectURL(blob), true);
        }else{
            // handle non-Blob()+non-URL browsers:
            if(typeof blob === "string" || blob.constructor===z ){
                try{
                    return saver( "data:" +  m   + ";base64,"  +  self.btoa(blob)  );
                }catch(y){
                    return saver( "data:" +  m   + "," + encodeURIComponent(blob)  );
                }
            }

            // Blob but not URL:
            fr=new FileReader();
            fr.onload=function(e){
                saver(this.result);
            };
            fr.readAsDataURL(blob);
        }
        return true;

    } /* end download() */

    function CurentTime() {
        const now = new Date();
        const pad = n => n < 10 ? `0${n}` : n;
        return `${now.getFullYear()}${pad(now.getMonth()+1)}${pad(now.getDate())}-${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
    }

    function getOriginalImage()
    {
        let save_btn_el = document.querySelector('[data-test-id="PinBetterSaveButton"]')
        let img_el = save_btn_el.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentElement.firstChild.getElementsByTagName("img")[0]; // I am not a JS dev, this is pizdec a kostil, but it works ig
        console.debug("img_el", img_el);
        if (save_btn_el && img_el) {
            let srcset = img_el.srcset.split(/,\s*/);
            for (let src of srcset) {
                if (src.includes('originals')) {
                    let imageOrig = src.split(/\s+/)[0];
                    return imageOrig;
                }
            }
            return img_el.src;
        }
    }

    window.addEventListener("keydown",
                            function(event) {
        console.debug("pressed");
        if (event.defaultPrevented ||
            /(input|textarea)/i.test(document.activeElement.nodeName) ||
            document.activeElement.matches('[role="textarea"]') ||
            document.activeElement.matches('[role="textbox"]'))
        {
            return;
        }
        switch (event.key) {
            case KEY_TO_OPEN.toLowerCase():
                showImage();
                break;
            case KEY_TO_OPEN.toUpperCase():
                showImage();
                break;
            default:
                return;
        }
        event.preventDefault();
    }, true);

})();