Greasy Fork is available in English.

CheckBoxMate for Greasemonkey

"Check multiple checkboxes with ease by drawing a box around them to automatically select them all." Converted from nrlz's amazing CheckBoxMate Firefox Add-on (https://addons.mozilla.org/en-US/firefox/addon/9740). Works with Firefox 3.6.3.

// ==UserScript==
// @name           CheckBoxMate for Greasemonkey
// @description    "Check multiple checkboxes with ease by drawing a box around them to automatically select them all." Converted from nrlz's amazing CheckBoxMate Firefox Add-on (https://addons.mozilla.org/en-US/firefox/addon/9740). Works with Firefox 3.6.3.
// @author         scottmweaver
// @date           2010-04-07
// @include        http://*
// @include        https://*
// @version 0.0.1.20140509133831
// @namespace https://greasyfork.org/users/54
// ==/UserScript==

const CheckBoxMate = {
    active: false,
    scrollX: 0,
    scrollY: 0,
    pageX: 0,
    pageY: 0,

    addEvt: function(e, f, c) {
        document.addEventListener(e, f, c ? true : false, true);
    },

    delEvt: function(e, f, c) {
        document.removeEventListener(e, f, c ? true : false, true);
    },

    init: function() {
        this.addEvt("mousedown", this.onDown);
    },

    uninit: function() {
        var d = CheckBoxMate;
        d.doc = 0;
        d.boxes = [];
        d.selected = [];
        d.delEvt("mousedown", d.onDown);
        d.delEvt("mousemove", d.onMove, 1);
        d.delEvt("mouseup", d.onUp, 1);
        removeEventListener("unload", arguments.callee, false);
    },

    onDown: function(e) {
        var t = e.target, d = CheckBoxMate;

        if(d.active) {
            d.clear();

        } else if(t && // t instanceof HtmlInputText &&
           (t.type == "checkbox" || t.type == "CHECKBOX")) {

            d.doc = t.ownerDocument;

            if(d.doc.getBoxObjectFor) {
                d.startX = e.screenX;
                d.startY = e.screenY;
                d.scrollX = e.pageX - e.screenX;
                d.scrollY = e.pageY - e.screenY;
            } else {
                d.startX = e.pageX;
                d.startY = e.pageY;
            }

            d.boxes = [];
            d.selected = [];
            d.addEvt("mousemove", d.onMove, 1);
            d.addEvt("mouseup", d.onUp, 1);
            d.active = 0;
        }
    },

    onMove: function(e) {
        var d = CheckBoxMate;

        if(!d.active && !e.nodeType) {
            var delta = (e.pageX - d.startX)*(e.pageY - d.startY);
            if(delta < -2 || delta > 2) {
                d.active = 1;
            } else return;
        }

        if(e.nodeType) {
            var p = --d.pending;
            if(p) {
                setTimeout(d.onMove, 200, e);
            } else {
                if(d.active) d.calc();
            }
            if(d.active) d.update();

        } else {
            if(!d.pending) {
                d.calc();
                setTimeout(d.onMove, 200, e.target);
            }
            d.pending = 2;
            if(d.doc.getBoxObjectFor) {
                d.endX = e.screenX;
                d.endY = e.screenY;
            } else {
                d.endX = e.pageX;
                d.endY = e.pageY;
            }

            var rect = d.doc.getElementById("checkboxmate_24601");
            
            if(!rect) {
              rect = d.doc.documentElement.appendChild(d.doc.createElement("div"));
              rect.id = "checkboxmate_24601";
              rect.style.cssText = "outline:1px dotted #fff; border:1px dotted #000; position:absolute; padding:0px; margin:0px";
            }
            rect = rect.style;
            rect.left = d.scrollX + ((d.startX < d.endX) ? d.startX : d.endX) - 7 + "px";
            rect.top  = d.scrollY + ((d.startY < d.endY) ? d.startY : d.endY) - 7 + "px";
            rect.width  = Math.abs(d.startX - d.endX) + 14 + "px";
            rect.height = Math.abs(d.startY - d.endY) + 14 + "px";
        }
    },

    onUp: function(e) {
        var d = CheckBoxMate;
        if(d.active) {
            d.calc();
            d.update();
        }
        d.clear();
    },

    clear: function() {
        var d = CheckBoxMate;
        d.active = 0;
        d.delEvt("mousemove", d.onMove, 1);
        d.delEvt("mouseup", d.onUp, 1);
        var rect = d.doc.getElementById("checkboxmate_24601");
        if(rect) rect.parentNode.removeChild(rect);
        d.doc = 0;
        d.boxes = [];
        d.selected = [];
    },

    boxes: [],
    selected: [],

    update: function() {
        var arr = this.boxes, y, y2, x, x2, sel = [], n;

        y = this.endY > this.startY;
        y2 = y ? this.endY : this.startY;
        y  = y ? this.startY : this.endY;
        
        // Added scroll offset
        y = y - window.pageYOffset;
        y2 = y2 - window.pageYOffset;
        
        x = this.endX > this.startX;
        x2 = x ? this.endX : this.startX;
        x  = x ? this.startX : this.endX;
        
        // Added side scroll offset
        x = x - window.pageXOffset;
        x2 = x2 - window.pageXOffset;

        var i = this.binary(arr, {key: y});

        while(i > 0 && arr[i - 1].y2 > y) --i;

        while((n = arr[i++]) && y < n.y2 && y2 > n.y) {
            if(x < n.x2 && x2 > n.x) {
                sel.push(n.n);
                n.n.cbm = 1;
            }
        }

        arr = this.selected;
        this.selected = sel;

        for(i = arr.length - 1; i >= 0; i--) {
            if(!arr[i].cbm) {
                var e = this.doc.createEvent("MouseEvents");
                e.initMouseEvent("click", 1, 1, this.doc.defaultView, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, null);
                arr[i].dispatchEvent(e);
            } else {
                arr[i].cbm = 0;
            }
        }

        for(i = sel.length - 1; i >= 0; i--) {
            if(sel[i].cbm) {
                sel[i].cbm = 0;
                var e = this.doc.createEvent("MouseEvents");
                e.initMouseEvent("click", 1, 1, this.doc.defaultView, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, null);
                sel[i].dispatchEvent(e);
            }
        }
    },

    calc: function() {
        var obj, d = this.doc,
            elms = d.getElementsByTagName("input"),
            arr = this.boxes = [],
            gbof = d.getBoxObjectFor && 1;

        for(var i=0, n; (n = elms[i]); i++) {
            if(n.type == "checkbox" || n.type == "CHECKBOX") {
                if(gbof) {
                    obj = d.getBoxObjectFor(n);
                    obj = {y:obj.screenY, y2:obj.height, x:obj.screenX, x2:obj.width, n:n, key:obj.screenY};
                    obj.y2 += obj.y;
                    obj.x2 += obj.x;
                } else {
                    obj = n.getBoundingClientRect();
                    obj = {y:obj.top, y2:obj.bottom, x:obj.left, x2:obj.right, n:n, key:obj.top};
                }
                arr.splice(this.binary(arr, obj), 0, obj);
            }
        }
    },

    binary: function(arr, item, r1, r2) {
        var i = item.key;
        if(arr.length == 0) return 0;
        if(!r2) {
            r1 = 0;
            r2 = arr.length;
            if(i < arr[0].key) return 0;
            if(i >= arr[r2 - 1].key) return r2;
        }
        switch(r2 - r1) {
            case 3: return (i < arr[r1].key) ? r1 : (i > arr[r2 - 1].key) ? r2 : (i < arr[r1 + 1].key) ? r1 + 1 : r2 - 1;
            case 2: return (i < arr[r1].key) ? r1 : (i > arr[r2 - 1].key) ? r2 : r2 - 1;
            case 1: return (i < arr[r1].key) ? r1 : r2;
            default:
                var m = Math.round((r2 + r1)/2);
                return this.binary(arr, item, (i < arr[m].key) ? r1 : m, (i < arr[m].key) ? m : r2);
        }
    }
};

addEventListener("load", function() {
    CheckBoxMate.init();
    addEventListener("unload", CheckBoxMate.uninit, false);
    removeEventListener("load", arguments.callee, false);
}, false);