// ==UserScript==
// @name Block external 2-0
// @author Simon Houston (shoust) & Mark Wilton Jones (TarquinWJ , original author)
// @version 2.5
// @description see http://www.howtocreate.co.uk/operaStuff/userJavaScript.html for details of the original script.
// ==/UserScript==

/* Changes: 

1. Added offsitecornercase variable for sites that use offsite resources often for their sites, like blogger, blogsmithmedia, photobucket, imageshack and paypal to name a few. 

2. Added allowvideo variable for sites that use online video sites content like youtube, revver, break, dailymotion and google videos.

3. Removed domain name extracter part and I've tried an alternative to getting a shortened domain name(like getting opera.com from my.opera.com), but so far will work on domains not ending in .co.uk(or equivalent).
*/
 (function() {
    var blockexternal = true;
    //determines if you should block the external resources if not. nothing will run.
    if (blockexternal && !window.name.match(/\-ext\-off/)) {
        var domaininsideurl = true;
        // if you want to match domains inside urls like in http://www.blogsmithmedia.com/www.joystiq.com/media/logo.gif where www.joystiq.com would be matched
        var subdomains = true;
        //if you want to match subdomains, like allow resources from my.opera.com on opera.com for example
        var showips = true;
        //if you want to match ip addresses, like for example resources from 127.0.0.1
        var enabledatauris = false;
        var exceptions = "";
        //enter hostnames that you don't want to block here and seperate each with a |
        var blcked = [];
        var blockimages = true;
        var allowvideo = true;
        var offsitecornercase = true;
        //resources that come from common sites, like images in popular blogs, or image sharing sites, or paypal buttons for example.
        var blockscripts = true;
        var hmm = location.hostname;
        if(hmm.substr(0,4)=='www.')
        {hmm=hmm.substr(4);
        }
        if(!hmm.match(/\.co\.\w{2,4}$/) && hmm.split('.').length>2)
        {
        hmm=hmm.replace(/^\w*\./,'');
        }
        //gives domain name
        var listofdomains='(';
        if (exceptions) {
        listofdomains+=exceptions;
        }
        if(showips)
        {listofdomains+='|\\d{1,3}.\\d{1,3}.\\d{1,3}.\\d{1,3}'}
        if(allowvideo)
        {listofdomains+='|youtube.com|dailymotion.com|video.google.com|break.com|putfile.com|veoh.com|revver.com';}
        if(offsitecornercase)
        {
        listofdomains+='|\\w*.imageshack.us|paypal.com|blogger.com|photobucket.com|blogsmithmedia.com|ytimg.com|cache.gawker.com';
        }
        listofdomains+=')';
        if(listofdomains.length==2)
        {delete listofdomains;}
        else {
        listofdomains=listofdomains.replace('(','('+hmm+'|');
        listofdomains=listofdomains.replace(/\./g, '\\.');}
        function ujsblockable(y) {
        var matchThis = new RegExp('('+(enabledatauris?'^data:|':'')+'^'+location.protocol+'\\\/\\\/'+listofdomains+'\\\/|\\\/?'+hmm+'\\\/?)','i');
        if(!y.match(matchThis) || !y.match(/^(http|ftp|ftps|https)/i))
        {return true;}
        else {return false}
        }
        if (blockscripts) {
            window.opera.addEventListener(
            'BeforeExternalScript',
            function(e) {
                if (ujsblockable(e.element.src)) {
                    e.preventDefault();
                    blcked[blcked.length] = e.element.src;
                }
            },
            false
            )
        }
        document.addEventListener(
        'DOMContentLoaded',
        function() {
            if (blockimages) {
            var t=document.selectNodes('//img[@src]');
            for(var x=0;x<t.length;x++)
            {
            if (ujsblockable(t[x].src)) {
                        blcked[blcked.length] = t[x].src;
                        addplaceholder(t[x]);
                    }
            }}
            var x = 0,
            y = document.selectNodes('//iframe[@src]');
            while (y[x]) {
                if (ujsblockable(y[x].src)) {
                    blcked[blcked.length] = y[x].src;
                    addplaceholder(y[x]);
                } else {
                    x++;
                }
            }
            var y = [document.selectNodes('//object'), document.selectNodes('//embed'), document.selectNodes('//applet')];
            for (var x = 0; y[x]; x++) {
                for (var z = 0; y[x][z]; z++) {
                    var oSrc = y[x][z].data;
                    if (!oSrc) {
                        oSrc = y[x][z].src;
                    }
                    if (!oSrc) {
                        for (var g = 0, h; h = y[x][z].childNodes[g]; g++) {
                            if (!h.tagName) {
                                continue;
                            }
                            var pName = h.name;
                            if ((pName == 'data') || (pName == 'movie') || (pName == 'src')) {
                                oSrc = h.value;
                                if (oSrc) {
                                    break;
                                }
                            }
                        }
                    }
                    if (!oSrc) {
                        oSrc = y[x][z].code
                    }
                    if (ujsblockable(oSrc)) {
                        blcked[blcked.length] = oSrc;
                        addplaceholder(y[x][z]);
                        z--;
                    }
                }
            }
        },
        false
        );

        function addplaceholder(y) {
            var url2 = (y['src'] ? y['src'] : y['data']);
            var hmm = document.createElement('s');
            if (y.tagName == 'IMG') {
                var url = url2;
            }
            else {
                var url = escape(y.outerHTML);
            }
            hmm.textContent = 'Unblock';
            hmm.setAttribute('title', url);
            hmm.style = "width:" + calcdim(y, 'width', hmm) + " !important;height:" + calcdim(y, 'height', hmm) + " !important;background-color:grey;border:3px dotted lightgreen !important;color:white !important;text-decoration:none;display:" + (y.style.display ? y.style.display: 'inline-block') + ";";
            hmm.setAttribute('onclick', 'bringback("' + url + '",this)');
            hmm.setAttribute('title', 'Click to unblock this url : ' + url2);
            y.parentNode.replaceChild(hmm,y);
        }

        function calcdim(z, x, y) {
            c = z.offsetWidth;
            if (c === 0 || c === 1)
            {
                y.textContent = y.textContent.substring(0, 2);
                return '20px';
            }
            else {
if(x=='width'){return (z.hasAttribute('width')?z.getAttribute('width')+'px':(getComputedStyle(z).width?getComputedStyle(z).width:getComputedStyle(z).maxWidth))}
else{return (z.hasAttribute('height')?z.getAttribute('height')+'px':(getComputedStyle(z).height?getComputedStyle(z).height:getComputedStyle(z).maxHeight))}
            }

        }

        document.addEventListener('load',
        function() {
            if (blcked != '') {
                for (var i = 0; i < blcked.length; i++)
                {
                    blcked[i] = '<a href="' + blcked[i] + '">' + blcked[i] + '</a><br/>';
                }
                // function to get totally unique arrays
                function unique(arrg) {
                    var arrT = arrg.split(",");
                    var arrNT = [];
                    var seenT = {};
                    for (var i = 0; i < arrT.length; i++) {
                        if (!seenT[arrT[i]]) {
                            seenT[arrT[i]] = true;
                            arrNT[arrNT.length] = arrT[i];
                        }
                    }
                    return arrNT.join("");
                }
                blcked = blcked.toString();
                blcked = unique(blcked);
            }
            // brings up window with list of blocked items. Press Shift and doubleclick to function.
            document.addEventListener('dblclick',
            function(e) {
                if (e.shiftKey) {
                    if (blcked != '') {
                        var win = window.open();
                        win.document.write('<h1>Items blocked</h1><br/>' + blcked);
                        win.document.close();
                    } else {
                        alert('No items blocked')
                    }
                }
            },
            false);
        },
        false);
    }
})();


function bringback(y, x) {
    y = unescape(y);
    if (!y.match(/^(\<|\x3c)/)) {
        var hmm = document.createElement('img');
        hmm.src = y;
        x.parentNode.replaceChild(hmm, x);
    }
    else {
        x.outerHTML = y;
    }
    var yu = document.getElementsByTagName('s');
    for (var i = 0; i < yu.length, u = yu[i]; i++)
    {
        if (u.getAttribute('onclick') && u.getAttribute('onclick').indexOf(y) != -1)
        {
            bringback(y, u);
        }
    }
}

function ujsbetoggle() {
    if (window.name.match(/\-ext\-off/)) {
        window.name = window.name.replace(/\-ext\-off/, '');
        alert('Block External On');
    } else {
        alert('Block External Off');
        window.name = window.name + '-ext-off';
    }
}