WordPress/WordPress

View on GitHub
wp-includes/js/jquery/ui/selectable.js

Summary

Maintainability
D
1 day
Test Coverage
/*!
 * jQuery UI Selectable 1.13.3
 * https://jqueryui.com
 *
 * Copyright OpenJS Foundation and other contributors
 * Released under the MIT license.
 * https://jquery.org/license
 */

//>>label: Selectable
//>>group: Interactions
//>>description: Allows groups of elements to be selected with the mouse.
//>>docs: https://api.jqueryui.com/selectable/
//>>demos: https://jqueryui.com/selectable/
//>>css.structure: ../../themes/base/selectable.css

( function( factory ) {
    "use strict";

    if ( typeof define === "function" && define.amd ) {

        // AMD. Register as an anonymous module.
        define( [
            "jquery",
            "./mouse",
            "../version",
            "../widget"
        ], factory );
    } else {

        // Browser globals
        factory( jQuery );
    }
} )( function( $ ) {
"use strict";

return $.widget( "ui.selectable", $.ui.mouse, {
    version: "1.13.3",
    options: {
        appendTo: "body",
        autoRefresh: true,
        distance: 0,
        filter: "*",
        tolerance: "touch",

        // Callbacks
        selected: null,
        selecting: null,
        start: null,
        stop: null,
        unselected: null,
        unselecting: null
    },
    _create: function() {
        var that = this;

        this._addClass( "ui-selectable" );

        this.dragged = false;

        // Cache selectee children based on filter
        this.refresh = function() {
            that.elementPos = $( that.element[ 0 ] ).offset();
            that.selectees = $( that.options.filter, that.element[ 0 ] );
            that._addClass( that.selectees, "ui-selectee" );
            that.selectees.each( function() {
                var $this = $( this ),
                    selecteeOffset = $this.offset(),
                    pos = {
                        left: selecteeOffset.left - that.elementPos.left,
                        top: selecteeOffset.top - that.elementPos.top
                    };
                $.data( this, "selectable-item", {
                    element: this,
                    $element: $this,
                    left: pos.left,
                    top: pos.top,
                    right: pos.left + $this.outerWidth(),
                    bottom: pos.top + $this.outerHeight(),
                    startselected: false,
                    selected: $this.hasClass( "ui-selected" ),
                    selecting: $this.hasClass( "ui-selecting" ),
                    unselecting: $this.hasClass( "ui-unselecting" )
                } );
            } );
        };
        this.refresh();

        this._mouseInit();

        this.helper = $( "<div>" );
        this._addClass( this.helper, "ui-selectable-helper" );
    },

    _destroy: function() {
        this.selectees.removeData( "selectable-item" );
        this._mouseDestroy();
    },

    _mouseStart: function( event ) {
        var that = this,
            options = this.options;

        this.opos = [ event.pageX, event.pageY ];
        this.elementPos = $( this.element[ 0 ] ).offset();

        if ( this.options.disabled ) {
            return;
        }

        this.selectees = $( options.filter, this.element[ 0 ] );

        this._trigger( "start", event );

        $( options.appendTo ).append( this.helper );

        // position helper (lasso)
        this.helper.css( {
            "left": event.pageX,
            "top": event.pageY,
            "width": 0,
            "height": 0
        } );

        if ( options.autoRefresh ) {
            this.refresh();
        }

        this.selectees.filter( ".ui-selected" ).each( function() {
            var selectee = $.data( this, "selectable-item" );
            selectee.startselected = true;
            if ( !event.metaKey && !event.ctrlKey ) {
                that._removeClass( selectee.$element, "ui-selected" );
                selectee.selected = false;
                that._addClass( selectee.$element, "ui-unselecting" );
                selectee.unselecting = true;

                // selectable UNSELECTING callback
                that._trigger( "unselecting", event, {
                    unselecting: selectee.element
                } );
            }
        } );

        $( event.target ).parents().addBack().each( function() {
            var doSelect,
                selectee = $.data( this, "selectable-item" );
            if ( selectee ) {
                doSelect = ( !event.metaKey && !event.ctrlKey ) ||
                    !selectee.$element.hasClass( "ui-selected" );
                that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
                    ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
                selectee.unselecting = !doSelect;
                selectee.selecting = doSelect;
                selectee.selected = doSelect;

                // selectable (UN)SELECTING callback
                if ( doSelect ) {
                    that._trigger( "selecting", event, {
                        selecting: selectee.element
                    } );
                } else {
                    that._trigger( "unselecting", event, {
                        unselecting: selectee.element
                    } );
                }
                return false;
            }
        } );

    },

    _mouseDrag: function( event ) {

        this.dragged = true;

        if ( this.options.disabled ) {
            return;
        }

        var tmp,
            that = this,
            options = this.options,
            x1 = this.opos[ 0 ],
            y1 = this.opos[ 1 ],
            x2 = event.pageX,
            y2 = event.pageY;

        if ( x1 > x2 ) {
            tmp = x2; x2 = x1; x1 = tmp;
        }
        if ( y1 > y2 ) {
            tmp = y2; y2 = y1; y1 = tmp;
        }
        this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );

        this.selectees.each( function() {
            var selectee = $.data( this, "selectable-item" ),
                hit = false,
                offset = {};

            //prevent helper from being selected if appendTo: selectable
            if ( !selectee || selectee.element === that.element[ 0 ] ) {
                return;
            }

            offset.left   = selectee.left   + that.elementPos.left;
            offset.right  = selectee.right  + that.elementPos.left;
            offset.top    = selectee.top    + that.elementPos.top;
            offset.bottom = selectee.bottom + that.elementPos.top;

            if ( options.tolerance === "touch" ) {
                hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
                    offset.bottom < y1 ) );
            } else if ( options.tolerance === "fit" ) {
                hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
                    offset.bottom < y2 );
            }

            if ( hit ) {

                // SELECT
                if ( selectee.selected ) {
                    that._removeClass( selectee.$element, "ui-selected" );
                    selectee.selected = false;
                }
                if ( selectee.unselecting ) {
                    that._removeClass( selectee.$element, "ui-unselecting" );
                    selectee.unselecting = false;
                }
                if ( !selectee.selecting ) {
                    that._addClass( selectee.$element, "ui-selecting" );
                    selectee.selecting = true;

                    // selectable SELECTING callback
                    that._trigger( "selecting", event, {
                        selecting: selectee.element
                    } );
                }
            } else {

                // UNSELECT
                if ( selectee.selecting ) {
                    if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
                        that._removeClass( selectee.$element, "ui-selecting" );
                        selectee.selecting = false;
                        that._addClass( selectee.$element, "ui-selected" );
                        selectee.selected = true;
                    } else {
                        that._removeClass( selectee.$element, "ui-selecting" );
                        selectee.selecting = false;
                        if ( selectee.startselected ) {
                            that._addClass( selectee.$element, "ui-unselecting" );
                            selectee.unselecting = true;
                        }

                        // selectable UNSELECTING callback
                        that._trigger( "unselecting", event, {
                            unselecting: selectee.element
                        } );
                    }
                }
                if ( selectee.selected ) {
                    if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
                        that._removeClass( selectee.$element, "ui-selected" );
                        selectee.selected = false;

                        that._addClass( selectee.$element, "ui-unselecting" );
                        selectee.unselecting = true;

                        // selectable UNSELECTING callback
                        that._trigger( "unselecting", event, {
                            unselecting: selectee.element
                        } );
                    }
                }
            }
        } );

        return false;
    },

    _mouseStop: function( event ) {
        var that = this;

        this.dragged = false;

        $( ".ui-unselecting", this.element[ 0 ] ).each( function() {
            var selectee = $.data( this, "selectable-item" );
            that._removeClass( selectee.$element, "ui-unselecting" );
            selectee.unselecting = false;
            selectee.startselected = false;
            that._trigger( "unselected", event, {
                unselected: selectee.element
            } );
        } );
        $( ".ui-selecting", this.element[ 0 ] ).each( function() {
            var selectee = $.data( this, "selectable-item" );
            that._removeClass( selectee.$element, "ui-selecting" )
                ._addClass( selectee.$element, "ui-selected" );
            selectee.selecting = false;
            selectee.selected = true;
            selectee.startselected = true;
            that._trigger( "selected", event, {
                selected: selectee.element
            } );
        } );
        this._trigger( "stop", event );

        this.helper.remove();

        return false;
    }

} );

} );