WebSuckIt!

Ugh, these Webs these Sockets... Nobody need them.

Fra og med 05.09.2016. Se den nyeste version.

// ==UserScript==
// @name         WebSuckIt!
// @namespace    lainscripts_websuckit
// @version      4.6
// @description  Ugh, these Webs these Sockets... Nobody need them.
// @author       lainverse
// @match        *://*/*
// @grant        unsafeWindow
// @run-at       document-start
// ==/UserScript==
(function() {
    'use strict';
    var win = unsafeWindow||window;

    var scriptText = '';

    function WebSocketWrapper() {
        // check if the browser supports Proxy and WebSocket
        if (typeof Proxy !== 'function' ||
            typeof WebSocket !== 'function') {
            return;
        }
        var to_block = [
            '||adlabs.ru',
            '||bgrndi.com^',
            '||brokeloy.com^',
            '||dreadfula.ru^',
            '||et-code.ru^',
            '||free-torrent.org^',
            '||free-torrent.pw^',
            '||free-torrents.org^',
            '||free-torrents.pw^',
            '||game-torrent.info^',
            '||gocdn.ru^',
            '||hghit.com^',
            '||kinotochka.net^',
            '||kuveres.com^',
            '||lepubs.com^',
            '||luxup.ru^',
            '||mail.ru^',
            '||marketgid.com^',
            '||mxtads.com^',
            '||oconner.biz^',
            '||poolnoodle.tech',
            '||psma01.com^',
            '||psma02.com^',
            '||psma03.com^',
            '||recreativ.ru^',
            '||regpole.com^',
            '||skidl.ru^',
            '||torvind.com^',
            '||trafmag.com^',
            '||xxuhter.ru^',
            '||yuiout.online^'
        ];
        var masks = [];
        to_block.forEach(function(m){
            masks.push(new RegExp(
                m.replace(/([\\\/\[\].*+?(){}$])/g, '\\$1')
                .replace(/\^(?!$)/g,'\\.?[^\\w%._-]')
                .replace(/\^$/,'\\.?([^\\w%._-]|$)')
                .replace(/^\|\|/,'^wss?:\\/+([^\/.]+\\.)*'),
                'i'));
        });
        var realWS = win.WebSocket,
            closingFunctions = ['close', 'send'];
        function wsGetter(tgt, nm) {
            console.log('[WSI] Registered call to property "', nm, '"');
            try {
                if (typeof realWS.prototype[nm] === 'function') {
                    if (closingFunctions.indexOf(nm) > -1) {
                        tgt.readyState = realWS.CLOSED;
                    }
                    return function(){return;};
                }
                if (typeof realWS.prototype[nm] === 'number') {
                    return realWS[nm];
                }
            } catch(ignore) {}
            return tgt[nm];
        }
        win.WebSocket = (new Proxy(realWS, {
            construct: function(target, args) {
                var url = args[0];
                console.log('[WSI] Opening socket on', url, '\u2026');
                var i = masks.length;
                while(i--) {
                    if (masks[i].test(url)) {
                        console.log("[WSI] Blocked.");
                        return new Proxy({url: url, readyState: realWS.OPEN}, {
                            get: wsGetter
                        });
                    }
                }
                return new target(args[0], args[1]);
            }
        }));
    }

    function WorkerWrapper(){
        var wr = win.Worker;
        win.Worker = function(resourceURI) {
            var _promise = new Promise(function(resolve,reject){
                var xhr = new XMLHttpRequest();
                xhr.open('GET', resourceURI, true);
                xhr.responseType = 'blob';
                xhr.onload = function(){
                    if (this.status == 200) {
                        var reader = new FileReader();
                        reader.addEventListener("loadend", function() {
                            resolve(
                                new wr(
                                    URL.createObjectURL(
                                        new Blob(['(function(){var win = self;'+
                                                  WebSocketWrapper.toString()+
                                                  ' WebSocketWrapper();})();'+this.result])
                                    )
                                )
                            );
                        });
                        reader.readAsText(this.response);
                    }
                };
                xhr.send();
            });
            var _worker = null,
                _terminate = false,
                _onerror = null,
                _onmessage = null,
                _messages = [],
                _events = [];
            var setWorker = function(val) {
                _worker = val;
                _worker.onerror = _onerror;
                _worker.onmessage = _onmessage;
                if (_terminate) {
                    _worker.terminate();
                }
                while(_messages.length) {
                    _worker.postMessage(_messages.shift());
                }
                while(_events.length) {
                    _worker.addEventListener.apply(_worker, _events.pop());
                }
            };
            _promise.then(setWorker);
            this.terminate = function(){
                _terminate = true;
                if (_worker) {
                    _worker.terminate();
                }
            };
            Object.defineProperty(this, 'onmessage', {
                get:function(){
                    return _onmessage;
                },
                set:function(val){
                    _onmessage = val;
                    if (_worker) {
                        _worker.onmessage = val;
                    }
                }
            });
            Object.defineProperty(this, 'onerror', {
                get:function(){
                    return _onerror;
                },
                set:function(val){
                    _onerror = val;
                    if (_worker) {
                        _worker.onmessage = val;
                    }
                }
            });
            this.postMessage = function(message){
                if (_worker) {
                    _worker.postMessage(message);
                } else {
                    _messages.push(message);
                }
            };
            this.terminate = function() {
                _terminate = true;
                if (_worker) {
                    _worker.terminate();
                }
            };
            this.addEventListener = function(){
                if (_worker) {
                    _worker.addEventListener.apply(_worker, arguments);
                } else {
                    _events.push(arguments);
                }
            };
            this.removeEventListener = function(){
                if (_worker) {
                    _worker.removeEventListener.apply(_worker, arguments);
                } // I don't think I should care to remove events here,
                // normally it shouldn't be invoked before _worker is created
            };
        };
    }

    function CreateElementWrapper() {
        var _ce = document.createElement.bind(document),
            dataText = /^data:text/i,
            key = '"'+Math.random().toString(36).substr(2)+'";',
            eskey = escape(key);
        document.createElement = function(name, opts) {
            if (name && name.toUpperCase &&
                name.toUpperCase() === 'IFRAME') {
                var ifr = _ce.apply(document, arguments);
                ifr.addEventListener('load', function(e) {
                    var f = e.target;
                    if(dataText.test(f.src) && f.src.indexOf(eskey) < 0) {
                        f.src = f.src.replace(',',','+escape('<scr'+'ipt>'+key+scriptText+'</scr'+'ipt>'));
                    }
                },false);
                return ifr;
            }
            return _ce.apply(document, arguments);
        };
    }

    function GenerateScriptText() {
        scriptText = '(function(){var win = self||window, scriptText = "";'+
            WebSocketWrapper.toString()+
            WorkerWrapper.toString()+
            CreateElementWrapper.toString()+
            GenerateScriptText.toString()+
            'GenerateScriptText();'+
            'WebSocketWrapper();'+
            'WorkerWrapper();'+
            'CreateElementWrapper();'+
            '})();'+
            'var s = document.currentScript; if (s) {s.parentNode.removeChild(s);}';
    }

    GenerateScriptText();
    scriptText = scriptText.replace(/\/\/[^\r\n]*/g,'').replace(/[\s\r\n]+/g,' ');

    if (/firefox/i.test(navigator.userAgent)) {
        var script = document.createElement('script');
        script.appendChild(document.createTextNode(scriptText));
        (document.head || document.body || document.documentElement).appendChild(script);
        return; //we don't want to call functions on page from here in Fx, so exit
    }

    WebSocketWrapper();
    WorkerWrapper();
    CreateElementWrapper();
})();