<commit_before>/*!
 * jQuery QueryBuilder Sortable
 * Copyright 2014-2015 Damien "Mistic" Sorel (http://www.strangeplanet.fr)
 * Licensed under MIT (http://opensource.org/licenses/MIT)
 */

(function($){
    "use strict";

    $.fn.queryBuilder.defaults.set({
        default_rule_flags: {
            no_sortable: false
        },
        icons: {
            sort: 'glyphicon glyphicon-sort'
        }
    });

    $.fn.queryBuilder.define('sortable', function(options) {
        /**
         * Init HTML5 drag and drop
         */
        this.on('afterInit', function() {
            // configure jQuery to use dataTransfer
            $.event.props.push('dataTransfer');

            var placeholder, src, isHandle = false;

            // only init drag from drag handle
            this.$el.on('mousedown', '.drag-handle', function(e) {
                isHandle = true;
            });
            this.$el.on('mouseup', '.drag-handle', function(e) {
                isHandle = false;
            });

            // dragstart: create placeholder and hide current element
            this.$el.on('dragstart', '[draggable]', function(e) {
                e.stopPropagation();

                if (isHandle) {
                    isHandle = false;

                    // notify drag and drop (only dummy text)
                    e.dataTransfer.setData('text', 'drag');

                    src = $(e.target);

                    placeholder = $('<div class="rule-placeholder">&nbsp;</div>');
                    placeholder.css('min-height', src.height());
                    placeholder.insertAfter(src);

                    // Chrome glitch (helper invisible if hidden immediately)
                    setTimeout(function() {
                        src.hide();
                    }, 0);
                }
                else {
                    e.preventDefault();
                }
            });

            // dragenter: move the placeholder
            this.$el.on('dragenter', '[draggable]', function(e) {
                e.preventDefault();
                e.stopPropagation();

                var target = $(e.target), parent;

                // on rule
                parent = target.closest('.rule-container');
                if (parent.length) {
                    placeholder.detach().insertAfter(parent);
                    return;
                }

                // on group header
                parent = target.closest('.rules-group-header');
                if (parent.length) {
                    parent = target.closest('.rules-group-container');
                    placeholder.detach().prependTo(parent.find('.rules-list').eq(0));
                    return;
                }

                // on group
                parent = target.closest('.rules-group-container');
                if (parent.length) {
                    placeholder.detach().appendTo(parent.find('.rules-list').eq(0));
                    return;
                }
            });

            // dragover: prevent glitches
            this.$el.on('dragover', '[draggable]', function(e) {
                e.preventDefault();
                e.stopPropagation();
            });

            // drop: move current element
            this.$el.on('drop', function(e) {
                e.preventDefault();
                e.stopPropagation();

                var target = $(e.target), parent;

                // on rule
                parent = target.closest('.rule-container');
                if (parent.length) {
                    src.detach().insertAfter(parent);
                    return;
                }

                // on group header
                parent = target.closest('.rules-group-header');
                if (parent.length) {
                    parent = target.closest('.rules-group-container');
                    src.detach().prependTo(parent.find('.rules-list').eq(0));
                    return;
                }

                // on group
                parent = target.closest('.rules-group-container');
                if (parent.length) {
                    src.detach().appendTo(parent.find('.rules-list').eq(0));
                    return;
                }
            });

            // dragend: show current element and delete placeholder
            this.$el.on('dragend', '[draggable]', function(e) {
                e.preventDefault();
                e.stopPropagation();

                src.show();
                placeholder.remove();
            });
        });

        /**
         * Remove drag handle from non-sortable rules
         */
        this.on('afterApplyRuleFlags', function($rule, rule, flags) {
            if (flags.no_sortable) {
                $rule.removeAttr('draggable').find('.drag-handle').remove();
            }
        });

        /**
         * Modify templates
         */
        this.on('getGroupTemplate', function(h, level) {
            if (level>1) {
                var $h = $(h);

                $h.attr('draggable', 'true')
                  .find('.group-conditions').after('<div class="drag-handle"><i class="' + this.icons.sort + '"></i></div>');

                h = $h.prop('outerHTML');
            }

            return h;
        });

        this.on('getRuleTemplate', function(h) {
            var $h = $(h);

            $h.attr('draggable', 'true')
              .find('.rule-header').after('<div class="drag-handle"><i class="' + this.icons.sort + '"></i></div>');

            return $h.prop('outerHTML');
        });
    });
<commit_msg>fixes #75 only add "draggable" attribute on drag handle mouse over to prevent unselectable text in Firefox<commit_after>/*!
 * jQuery QueryBuilder Sortable
 * Copyright 2014-2015 Damien "Mistic" Sorel (http://www.strangeplanet.fr)
 * Licensed under MIT (http://opensource.org/licenses/MIT)
 */

(function($){
    "use strict";

    $.fn.queryBuilder.defaults.set({
        default_rule_flags: {
            no_sortable: false
        },
        icons: {
            sort: 'glyphicon glyphicon-sort'
        }
    });

    $.fn.queryBuilder.define('sortable', function(options) {
        /**
         * Init HTML5 drag and drop
         */
        this.on('afterInit', function() {
            // configure jQuery to use dataTransfer
            $.event.props.push('dataTransfer');

            var placeholder, src,
                that = this;

            // only add "draggable" attribute when hovering drag handle
            // preventing text select bug in Firefox
            this.$el.on('mouseover', '.drag-handle', function() {
                that.$el.find('.rule-container, .rules-group-container').attr('draggable', true);
            });
            this.$el.on('mouseout', '.drag-handle', function() {
                that.$el.find('.rule-container, .rules-group-container').removeAttr('draggable');
            });

            // dragstart: create placeholder and hide current element
            this.$el.on('dragstart', '[draggable]', function(e) {
                e.stopPropagation();

                // notify drag and drop (only dummy text)
                e.dataTransfer.setData('text', 'drag');

                src = $(e.target);

                placeholder = $('<div class="rule-placeholder">&nbsp;</div>');
                placeholder.css('min-height', src.height());
                placeholder.insertAfter(src);

                // Chrome glitch (helper invisible if hidden immediately)
                setTimeout(function() {
                    src.hide();
                }, 0);
            });

            // dragenter: move the placeholder
            this.$el.on('dragenter', '[draggable]', function(e) {
                e.preventDefault();
                e.stopPropagation();

                moveSortableToTarget(placeholder, $(e.target));
            });

            // dragover: prevent glitches
            this.$el.on('dragover', '[draggable]', function(e) {
                e.preventDefault();
                e.stopPropagation();
            });

            // drop: move current element
            this.$el.on('drop', function(e) {
                e.preventDefault();
                e.stopPropagation();

                moveSortableToTarget(src, $(e.target));
            });

            // dragend: show current element and delete placeholder
            this.$el.on('dragend', '[draggable]', function(e) {
                e.preventDefault();
                e.stopPropagation();

                src.show();
                placeholder.remove();

                src = placeholder = null;

                that.$el.find('.rule-container, .rules-group-container').removeAttr('draggable');
            });
        });

        /**
         * Remove drag handle from non-sortable rules
         */
        this.on('afterApplyRuleFlags', function($rule, rule, flags) {
            if (flags.no_sortable) {
                $rule.find('.drag-handle').remove();
            }
        });

        /**
         * Modify templates
         */
        this.on('getGroupTemplate', function(h, level) {
            if (level>1) {
                var $h = $(h);
                $h.find('.group-conditions').after('<div class="drag-handle"><i class="' + this.icons.sort + '"></i></div>');
                h = $h.prop('outerHTML');
            }

            return h;
        });

        this.on('getRuleTemplate', function(h) {
            var $h = $(h);
            $h.find('.rule-header').after('<div class="drag-handle"><i class="' + this.icons.sort + '"></i></div>');
            return $h.prop('outerHTML');
        });
    });

    /**
     * Move an element (placeholder or actual object) depending on active target
     */
    function moveSortableToTarget(element, target) {
        var parent;

        // on rule
        parent = target.closest('.rule-container');
        if (parent.length) {
            element.detach().insertAfter(parent);
            return;
        }

        // on group header
        parent = target.closest('.rules-group-header');
        if (parent.length) {
            parent = target.closest('.rules-group-container');
            element.detach().prependTo(parent.find('.rules-list').eq(0));
            return;
        }

        // on group
        parent = target.closest('.rules-group-container');
        if (parent.length) {
            element.detach().appendTo(parent.find('.rules-list').eq(0));
            return;
        }
    }

{'fraction_non_alphanumeric': 0.1448019801980198, 'fraction_numerical': 0.0028560548362528563, 'mean_word_length': 1.3989495318565883, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '7522647', 'n_tokens_mistral': 2776, 'n_tokens_neox': 2602, 'n_words': 513}