Tumblr Always HQ Media

Always load highest resolution version of images on any Tumblr page, not just direct URL

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name        Tumblr Always HQ Media
// @description Always load highest resolution version of images on any Tumblr page, not just direct URL
// @version     1.4.0
// @require     https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js
// @namespace   https://greasyfork.org/en/scripts/32294-tumblr-always-hq-media
// @supportURL http://invertex.xyz
// @match	*://*.tumblr.com/*
// @grant       none
// ==/UserScript==
//oldinclude     /^https?://\d+\.media\.tumblr\.com/(.+/)*tumblr_.+_\d+\.(jpe?g|gif|png|bmp)(\?.*)?$/

var sizes = ['_raw.', '_1280.', '_540.', '_500.', '_400.', '_250.', '_100.' ];
var postCount = 0;
var thisJQ = $;

function checkIfJustImgURL(index) {
    if (index >= sizes.length) return;
    var url = window.location.href;
    if(!url.includes("media.")) { return; }
   // url = url.replace(/(.*(?=_))(_\d*.)(.*)/, '$1' + sizes[index] + '$3');
     for (var s = 1; s < sizes.length; s++)
    {
        url = url.replace(sizes[s], sizes[index]); //Replace any size with the max size.
    }
    if(index === 0)
    {
        url = "http://" + url.substring(url.indexOf(".") + 1).replace("media.", "data."); //remove sub-domain number if trying to access RAW image
    }
    if (url == window.location.href) {return;}
    thisJQ.ajax({
        url: url,
        type: 'HEAD',
        complete: function(data, textStatus, jqXHR) {
            window.location.replace(url);
        },
        error: function(jqXHR, textStatus, errorThrown) {
           // console.log(url + " failed to laod");
            checkIfJustImgURL(index + 1);
        }
    });
}
checkIfJustImgURL(0);

function decreaseURL(imgURL)
{
    var newURL = imgURL;

    if(imgURL.includes(".gif"))
    {
         for (var s = 1; s < sizes.length; s++)
         {
             newURL = newURL.replace(sizes[s], "_500."); //Replace any size with the max size.
         }

    }
    else
    {
        for (var s = 1; s < sizes.length; s++)
         {
             newURL = newURL.replace(sizes[s], "_1280."); //Replace any size with the max size.
         }
    }
    return newURL;
}

function processImages(element)
{
    var imgs = element.getElementsByTagName("img");
    
    for (var i = 0; i < imgs.length; i++)
    {
        if(!imgs[i].src.includes("inline")/* && !imgs[i].src.includes(".gif")*/)
        {
            var preSrc = imgs[i].src;
            
            for (var s = 1; s < sizes.length; s++)
            {
                imgs[i].src = imgs[i].src.replace(sizes[s], "_raw."); //Replace any size with the max size.
            }
        
            if(preSrc != imgs[i].src && imgs[i].src.includes(".media."))
            {
                imgs[i].src = "http://" + imgs[i].src.substring(imgs[i].src.indexOf(".") + 1).replace("media.", "data.");

                //Set the link wrapped around our image to point to the same image so as to not confuse people when they hover over it. Or if they do a save link as.
                thisJQ(imgs[i]).attr('data-highres', imgs[i].src);
                var p1 =  thisJQ(imgs[i]).parent();
                var attr = thisJQ(p1).attr('href');

                if(attr == null)
                {
                    p1 = thisJQ(p1).parent();
                }
                p1.attr('href', imgs[i].src);
                imgs[i].setAttribute('oldURL', preSrc);
               /* if(!imgs[i].complete)
                {
                    console.log(imgs[i].src + " failed to load");
                    imgs[i].src = preSrc;
                    thisJQ(imgs[i]).attr('data-highres', preSrc);
                }*/
                imgs[i].onerror = function ()
                {
                    var lowerURL = decreaseURL(this.getAttribute('oldURL'));
                    this.src = lowerURL;
                    thisJQ(imgs[i]).attr('data-highres', lowerURL);
                    thisJQ(this).parent().attr('href', lowerURL);
                };

            }
        }
    }
}

function processVideos()
{
    setTimeout(function()
    {


    var playBars = document.getElementsByClassName("vjs-control-bar");
    var vids = document.getElementsByTagName("video");
    var playButtons = document.getElementsByClassName("vjs-big-play-button");
    var bg = document.getElementsByClassName("vjs-poster");
    
        for(var z = 0; z < playBars.length; z++)
        {
            playBars[z].innerHTML += "<a href='http://google.com' class='vjs-menu-button vjs-control'>©</a>";
        }
        
    for(var b = 0; b < bg.length; b++)
    {
        bg[b].outerHTML = "";
    }
        for(var c = 0; c < playButtons.length; c++)
    {
        playButtons[c].setAttribute("style", "margin-top: 200px;");
    }
    for (var i = 0; i < vids.length; i++)
    {
        var source = vids[i].getElementsByTagName("source")[0];
        if(source.src.slice(-4) === "/480")
        {
            source.src = source.src.slice(0, -4);
        }
        vids[i].load();
       // playButtons[i].setAttribute("style", "margin-top: 100px;");
        
        //thisJQ(bg[i]).wrap('<a href="http://google.ca"></a>');
        
       // processVideoUI(vids[i]);
    }
            }, 1000);
}

function processVideoUI(videoElem)
{
    var parent = videoElem.parentElement;
    
    parent.getElementsByClassName("vjs-big-play-button")[0].setAttribute("style", "margin-top: 100px;");
    var bg = parent.getElementsByClassName("vjs-poster")[0];
    var wrapper = document.createElement("a");
    parent.appendChild(wrapper);
    wrapper.appendChild(bg);
    
    
}

function updatePageLinks(waitTime)
{
    
    setTimeout(function()
    {
        var lightBox = document.getElementsByClassName("tmblr-lightbox");

        processVideos();

        if(lightBox.length > 0)
        {
            console.log("lightbox active");
            processImages(lightBox[0]);
            thisJQ(lightBox[0]).on('click', function(){processImages(lightBox[0]);}); //Watch for lightbox click to update URLs again since they will be refreshed by tumblr back to lower res
        }
            processImages(document.body);

            var photosets = document.body.getElementsByTagName("iframe");
            for(var i = 0; i < photosets.length; i++)
            {
                processImages(photosets[i].contentWindow.document);
            }

        console.log("end change");
    }, waitTime);
}

function doSetup(){
       updatePageLinks(0);

    setTimeout(function() //Experimenting with dashboard scroll updating, but ran into cross-domain issues. Don't really need to resize dashboard previews anyways, still resizes when you click on them to expand or new page.
    {
       // window.jQ = thisJQ;
        var newPosts = document.getElementsByClassName('posts');
        if(newPosts.length > 0)
        {
            newPosts = document.getElementsByClassName('grid');
        }


        if(newPosts.length > 0)
        {
            $(newPosts[0]).bind('DOMSubtreeModified', function()
            {
                var childCnt = 0;
                childCnt = newPosts[0].children.length;
               // if(childCnt > postCount)
               // {
                    postCount = childCnt;
                    //processVideos();
                   // processImages();
                console.log("children changed");
                   updatePageLinks(0);
              //  }

            });
        }
        var observer = new MutationObserver(function(mutations){
    mutations.forEach(function(mutation){
        console.log("start change");
        updatePageLinks(500);
    });
});
observer.observe(document.body, {attributes: true, attributeFilter: ['style', 'class']});
    var grid = document.getElementsByClassName('grid');
    if(grid != null && grid.length > 0){
        observer.observe(grid[0], {attributes: true, attributeFilter: ['style', 'class']});
         console.log("grid watch");
    }
    var posts = document.getElementsByClassName('posts');
    if(posts != null && posts.length > 0){
        observer.observe(posts[0], {attributes: true, childList: true});
         console.log("post watch");
    } 
   var posts2 = document.getElementById('posts');
        if(posts2 != null){
           observer.observe(posts2, {attributes: true, childList: true});
         console.log("post watch"); 
        }
        
        
    }, 2000);

     
}

thisJQ(document).ready(function(){
     doSetup();

});

function checkLightbox(){
    setTimeout(function(){
     var lightBox = document.getElementById("tumblr_lightbox");

console.log("lightbox check");
        if(lightBox != null)
        {
            console.log("lightbox active");
            processImages(lightBox);
            //lightBox.onclick = checkLightbox;
           thisJQ(lightBox).on('click', function(){processImages(lightBox);}); //Watch for lightbox click to update URLs again since they will be refreshed by tumblr back to lower res
        }
       //  updatePageLinks(0);
    }, 200);
}
document.onclick = checkLightbox;

$.noConflict();