<commit_before>/* ========================================================================
 * ZUI: selectable.js [1.5.0+]
 * http://openzui.com
 * ========================================================================
 * Copyright (c) 2016 <EMAIL>; Licensed MIT
 * ======================================================================== */


(function($) {
    'use strict';

    var name = 'zui.selectable'; // module name

    // The selectable modal class
    var Selectable = function(element, options) {
        this.name = name;
        this.$ = $(element);
        this.id = $.zui.uuid();
        this.selectOrder = 1;
        this.selections = {};

        this.getOptions(options);
        this._init();
    };

    var isPointInner = function(x, y, a) {
        return x >= a.left && x <= (a.left + a.width) && y >= a.top && y <= (a.top + a.height);
    };

    var isIntersectArea = function(a, b) {
        var x1 = Math.max(a.left, b.left),
            y1 = Math.max(a.top, b.top),
            x2 = Math.min(a.left + a.width, b.left + b.width),
            y2 = Math.min(a.top + a.height, b.top + b.height);

        return isPointInner(x1, y1, a) && isPointInner(x2, y2, a) && isPointInner(x1, y1, b) && isPointInner(x2, y2, b);
    };

    // default options
    Selectable.DEFAULTS = {
        selector: 'li,tr,div',
        trigger: '',
        selectClass: 'active',
        rangeStyle: {
            border: '1px solid ' + ($.zui.colorset ? $.zui.colorset.primary : '#3280fc'),
            backgroundColor: $.zui.colorset ? (new $.zui.Color($.zui.colorset.primary).fade(20).toCssStr()) : 'rgba(50, 128, 252, 0.2)'
        },
        clickBehavior: 'toggle',
        ignoreVal: 3,
        listenClick: true
        // mouseButton: -1 // 0, 1, 2, -1, all, left,  right, middle
    };

    // Get and init options
    Selectable.prototype.getOptions = function(options) {
        this.options = $.extend({}, Selectable.DEFAULTS, this.$.data(), options);
    };

    Selectable.prototype.select = function(elementOrid) {
        this.toggle(elementOrid, true);
    };

    Selectable.prototype.unselect = function(elementOrid) {
        this.toggle(elementOrid, false);
    };

    Selectable.prototype.toggle = function(elementOrid, isSelect, handle) {
        var $element, id, selector = this.options.selector, that = this;
        if(elementOrid === undefined) {
            this.$.find(selector).each(function() {
                that.toggle(this, isSelect);
            });
            return;
        } else if(typeof elementOrid === 'object') {
            $element = $(elementOrid).closest(selector);
            id = $element.data('id');
        } else {
            id = elementOrid;
            $element = that.$.find('.selectable-item[data-id="' + id + '"]');
        }
        if($element && $element.length) {
            if(!id) {
                id = $.zui.uuid();
                $element.attr('data-id', id);
            }
            if(isSelect === undefined || isSelect === null) {
                isSelect = !that.selections[id];
            }
            if(!!isSelect !== !!that.selections[id]) {
                var handleResult;
                if(typeof handle === 'function') {
                    handleResult = handle(isSelect);
                }
                if(handleResult !== true) {
                    that.selections[id] = isSelect ? that.selectOrder++ : false;
                    that.callEvent(isSelect ? 'select' : 'unselect', {id: id, selections: that.selections, target: $element, selected: that.getSelectedArray()}, that);
                }
            }
            if (that.options.selectClass) {
                $element.toggleClass(that.options.selectClass, isSelect);
            }
        }
    };

    Selectable.prototype.getSelectedArray = function() {
        var selected = [];
        $.each(this.selections, function(thisId, thisIsSelected) {
            if(thisIsSelected) selected.push(thisId);
        });
        return selected;
    };

    Selectable.prototype.syncSelectionsFromClass = function() {
        var that = this;
        var $children = that.$children = that.$.find(that.options.selector);
        that.selections = {};
        $children.each(function() {
            var $item = $(this);
            that.selections[$item.data('id')] = $item.hasClass(that.options.selectClass);
        });
    };

    Selectable.prototype._init = function() {
        var options = this.options, that = this;
        var ignoreVal = options.ignoreVal;
        var isIgnoreMove = true;
        var eventNamespace = '.' + this.name + '.' + this.id;
        var startX, startY, $range, range, x, y, checkRangeCall;
        var checkFunc = typeof options.checkFunc === 'function' ? options.checkFunc : null;
        var rangeFunc = typeof options.rangeFunc === 'function' ? options.rangeFunc : null;
        var isMouseDown    = false;
        var mouseDownBackEventCall = null;
        var mouseDownEventName = 'mousedown' + eventNamespace;

        var checkRange = function() {
            if(!range) return;
            that.$children.each(function() {
                var $item = $(this);
                var offset = $item.offset();
                offset.width = $item.outerWidth();
                offset.height = $item.outerHeight();
                var isIntersect = rangeFunc ? rangeFunc.call(this, range, offset) : isIntersectArea(range, offset);
                if(checkFunc) {
                    var result = checkFunc.call(that, {
                        intersect: isIntersect,
                        target: $item,
                        range: range,
                        targetRange: offset
                    });
                    if(result === true) {
                        that.select($item);
                    } else if(result === false) {
                        that.unselect($item);
                    }
                } else {
                    if(isIntersect) {
                        that.select($item);
                    } else if(!that.multiKey) {
                        that.unselect($item);
                    }
                }
            });
        };

        var mousemove = function(e) {
            if(!isMouseDown) return;
            x = e.pageX;
            y = e.pageY;
            range = {
                width: Math.abs(x - startX),
                height: Math.abs(y - startY),
                left: x > startX ? startX : x,
                top: y > startY ? startY : y
            };

            if(isIgnoreMove && range.width < ignoreVal && range.height < ignoreVal) return;
            if(!$range) {
                $range = $('.selectable-range[data-id="' + that.id + '"]');
                if(!$range.length) {
                    $range = $('<div class="selectable-range" data-id="' + that.id + '"></div>')
                        .css($.extend({
                            zIndex: 1060,
                            position: 'absolute',
                            top: startX,
                            left: startY,
                            pointerEvents: 'none',
                        }, that.options.rangeStyle))
                        .appendTo($('body'));
                }
            }
            $range.css(range);
            clearTimeout(checkRangeCall);
            checkRangeCall = setTimeout(checkRange, 10);
            isIgnoreMove = false;
        };

        var mouseup = function(e) {
            $(document).off(eventNamespace);
            clearTimeout(mouseDownBackEventCall);
            if(!isMouseDown) return;
            isMouseDown = false;
            if($range) $range.remove();
            if(!isIgnoreMove)
            {
                if(range) {
                    clearTimeout(checkRangeCall);
                    checkRange();
                    range = null;
                }
            }
            that.callEvent('finish', {selections: that.selections, selected: that.getSelectedArray()});<commit_msg>* selectable: optimize move performance.<commit_after>/* ========================================================================
 * ZUI: selectable.js [1.5.0+]
 * http://openzui.com
 * ========================================================================
 * Copyright (c) 2016 <EMAIL>; Licensed MIT
 * ======================================================================== */


(function($) {
    'use strict';

    var name = 'zui.selectable'; // module name

    // The selectable modal class
    var Selectable = function(element, options) {
        this.name = name;
        this.$ = $(element);
        this.id = $.zui.uuid();
        this.selectOrder = 1;
        this.selections = {};

        this.getOptions(options);
        this._init();
    };

    var isPointInner = function(x, y, a) {
        return x >= a.left && x <= (a.left + a.width) && y >= a.top && y <= (a.top + a.height);
    };

    var isIntersectArea = function(a, b) {
        var x1 = Math.max(a.left, b.left),
            y1 = Math.max(a.top, b.top),
            x2 = Math.min(a.left + a.width, b.left + b.width),
            y2 = Math.min(a.top + a.height, b.top + b.height);

        return isPointInner(x1, y1, a) && isPointInner(x2, y2, a) && isPointInner(x1, y1, b) && isPointInner(x2, y2, b);
    };

    // default options
    Selectable.DEFAULTS = {
        selector: 'li,tr,div',
        trigger: '',
        selectClass: 'active',
        rangeStyle: {
            border: '1px solid ' + ($.zui.colorset ? $.zui.colorset.primary : '#3280fc'),
            backgroundColor: $.zui.colorset ? (new $.zui.Color($.zui.colorset.primary).fade(20).toCssStr()) : 'rgba(50, 128, 252, 0.2)'
        },
        clickBehavior: 'toggle',
        ignoreVal: 3,
        listenClick: true
        // mouseButton: -1 // 0, 1, 2, -1, all, left,  right, middle
    };

    // Get and init options
    Selectable.prototype.getOptions = function(options) {
        this.options = $.extend({}, Selectable.DEFAULTS, this.$.data(), options);
    };

    Selectable.prototype.select = function(elementOrid) {
        this.toggle(elementOrid, true);
    };

    Selectable.prototype.unselect = function(elementOrid) {
        this.toggle(elementOrid, false);
    };

    Selectable.prototype.toggle = function(elementOrid, isSelect, handle) {
        var $element, id, selector = this.options.selector, that = this;
        if(elementOrid === undefined) {
            this.$.find(selector).each(function() {
                that.toggle(this, isSelect);
            });
            return;
        } else if(typeof elementOrid === 'object') {
            $element = $(elementOrid).closest(selector);
            id = $element.data('id');
        } else {
            id = elementOrid;
            $element = that.$.find('.selectable-item[data-id="' + id + '"]');
        }
        if($element && $element.length) {
            if(!id) {
                id = $.zui.uuid();
                $element.attr('data-id', id);
            }
            if(isSelect === undefined || isSelect === null) {
                isSelect = !that.selections[id];
            }
            if(!!isSelect !== !!that.selections[id]) {
                var handleResult;
                if(typeof handle === 'function') {
                    handleResult = handle(isSelect);
                }
                if(handleResult !== true) {
                    that.selections[id] = isSelect ? that.selectOrder++ : false;
                    that.callEvent(isSelect ? 'select' : 'unselect', {id: id, selections: that.selections, target: $element, selected: that.getSelectedArray()}, that);
                }
            }
            if (that.options.selectClass) {
                $element.toggleClass(that.options.selectClass, isSelect);
            }
        }
    };

    Selectable.prototype.getSelectedArray = function() {
        var selected = [];
        $.each(this.selections, function(thisId, thisIsSelected) {
            if(thisIsSelected) selected.push(thisId);
        });
        return selected;
    };

    Selectable.prototype.syncSelectionsFromClass = function() {
        var that = this;
        var $children = that.$children = that.$.find(that.options.selector);
        that.selections = {};
        $children.each(function() {
            var $item = $(this);
            that.selections[$item.data('id')] = $item.hasClass(that.options.selectClass);
        });
    };

    Selectable.prototype._init = function() {
        var options = this.options, that = this;
        var ignoreVal = options.ignoreVal;
        var isIgnoreMove = true;
        var eventNamespace = '.' + this.name + '.' + this.id;
        var startX, startY, $range, range, x, y, checkRangeCall;
        var checkFunc = typeof options.checkFunc === 'function' ? options.checkFunc : null;
        var rangeFunc = typeof options.rangeFunc === 'function' ? options.rangeFunc : null;
        var isMouseDown    = false;
        var mouseDownBackEventCall = null;
        var mouseDownEventName = 'mousedown' + eventNamespace;

        var checkRange = function() {
            if(!range) return;
            that.$children.each(function() {
                var $item = $(this);
                var offset = $item.offset();
                offset.width = $item.outerWidth();
                offset.height = $item.outerHeight();
                var isIntersect = rangeFunc ? rangeFunc.call(this, range, offset) : isIntersectArea(range, offset);
                if(checkFunc) {
                    var result = checkFunc.call(that, {
                        intersect: isIntersect,
                        target: $item,
                        range: range,
                        targetRange: offset
                    });
                    if(result === true) {
                        that.select($item);
                    } else if(result === false) {
                        that.unselect($item);
                    }
                } else {
                    if(isIntersect) {
                        that.select($item);
                    } else if(!that.multiKey) {
                        that.unselect($item);
                    }
                }
            });
        };

        var mouseMoveHandler = function(e) {
            if(!isMouseDown) return;
            x = e.pageX;
            y = e.pageY;
            range = {
                width: Math.abs(x - startX),
                height: Math.abs(y - startY),
                left: x > startX ? startX : x,
                top: y > startY ? startY : y
            };

            if(isIgnoreMove && range.width < ignoreVal && range.height < ignoreVal) return;
            if(!$range) {
                $range = $('.selectable-range[data-id="' + that.id + '"]');
                if(!$range.length) {
                    $range = $('<div class="selectable-range" data-id="' + that.id + '"></div>')
                        .css($.extend({
                            zIndex: 1060,
                            position: 'absolute',
                            top: startX,
                            left: startY,
                            pointerEvents: 'none',
                        }, that.options.rangeStyle))
                        .appendTo($('body'));
                }
            }
            $range.css(range);
            clearTimeout(checkRangeCall);
            checkRangeCall = setTimeout(checkRange, 10);
            isIgnoreMove = false;
        };

        var mouseMoveTimer = 0;
        var mousemove = function(event) {
            if (mouseMoveTimer) {
                ($.zui.clearAsap || clearTimeout)(mouseMoveTimer);
            }
            mouseMoveTimer = ($.zui.asap || setTimeout)(function() {
                mouseMoveTimer = 0;
                mouseMoveHandler(event);
            }, 0);
        };

        var mouseup = function(e) {
            $(document).off(eventNamespace);
            clearTimeout(mouseDownBackEventCall);
            if(!isMouseDown) return;
            isMouseDown = false;
            if($range) $range.remove();
            if(!isIgnoreMove)
            {
                if(range) {
                    clearTimeout(checkRangeCall);
                    checkRange();
                    range = null;
                }
            }
            that.callEvent('finish', {selections: that.selections, selected: that.getSelectedArray()});
{'fraction_non_alphanumeric': 0.1600535540408958, 'fraction_numerical': 0.006146543330087634, 'mean_word_length': 1.5724796493425173, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1961132', 'n_tokens_mistral': 4595, 'n_tokens_neox': 4353, 'n_words': 882}