Greasy Fork is available in English.

WebSuckIt!

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

Устаревшая версия за 04.09.2016. Перейдите к последней версии.

// ==UserScript==
// @name         WebSuckIt!
// @namespace    lainscripts_websuckit
// @version      4.1
// @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;

    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-torrents.org^',
            '||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, '…');
                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
            };
        };

    }

    if (/firefox/i.test(navigator.userAgent)) {
        var script = document.createElement('script');
        var WSIstr = '(function(){var win = self||window;'+
            WebSocketWrapper.toString() +
            WorkerWrapper.toString() +
            'WebSocketWrapper();WorkerWrapper();})();';
        script.appendChild(
            document.createTextNode(WSIstr + 'if (document.currentScript) {'+
                                    'document.currentScript.parentNode.removeChild(document.currentScript);'+
                                    '}')
        );
        (document.head || document.body || document.documentElement).appendChild(script);
        return; //exit
    }

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