The source code

    /**
     * @ignore
     *  droppable for kissy
     * @author yiminghe@gmail.com
     */
    KISSY.add('dd/droppable/base', function (S, Node, RichBase, DD) {

            var DDM = DD.DDM,
                PREFIX_CLS = DDM.PREFIX_CLS;

            function validDrop(dropGroups, dragGroups) {
                if (dropGroups === true) {
                    return 1;
                }
                for (var d in dropGroups) {
                    if (dragGroups[d]) {
                        return 1;
                    }
                }
                return 0;
            }

            /**
             * @class KISSY.DD.Droppable
             * @extends KISSY.RichBase
             * Make a node droppable.
             */
            return RichBase.extend({

                initializer: function () {
                    var self = this;
                    self.addTarget(DDM);

                    /**
                     * fired after a draggable leaves a droppable
                     * @event dropexit
                     * @member KISSY.DD.DDM
                     * @param e
                     * @param e.drag current draggable object
                     * @param e.drop current droppable object
                     */

                    /**
                     *
                     * fired after a draggable leaves a droppable
                     * @event dropexit
                     * @member KISSY.DD.Droppable
                     * @param e
                     * @param e.drag current draggable object
                     * @param e.drop current droppable object
                     */

                    /**
                     * fired after a draggable object mouseenter a droppable object
                     * @event dropenter
                     * @member KISSY.DD.DDM
                     * @param e
                     * @param e.drag current draggable object
                     * @param e.drop current droppable object
                     */

                    /**
                     * fired after a draggable object mouseenter a droppable object
                     * @event dropenter
                     * @member KISSY.DD.Droppable
                     * @param e
                     * @param e.drag current draggable object
                     * @param e.drop current droppable object
                     */

                    /**
                     *
                     * fired after a draggable object mouseover a droppable object
                     * @event dropover
                     * @member KISSY.DD.DDM
                     * @param e
                     * @param e.drag current draggable object
                     * @param e.drop current droppable object
                     */

                    /**
                     *
                     * fired after a draggable object mouseover a droppable object
                     * @event dropover
                     * @member KISSY.DD.Droppable
                     * @param e
                     * @param e.drag current draggable object
                     * @param e.drop current droppable object
                     */

                    /**
                     *
                     * fired after drop a draggable onto a droppable object
                     * @event drophit
                     * @member KISSY.DD.DDM
                     * @param e
                     * @param e.drag current draggable object
                     * @param e.drop current droppable object
                     */

                    /**
                     *
                     * fired after drop a draggable onto a droppable object
                     * @event drophit
                     * @member KISSY.DD.Droppable
                     * @param e
                     * @param e.drag current draggable object
                     * @param e.drop current droppable object
                     */

                    DDM._regDrop(this);
                },
                /**
                 * Get drop node from target
                 * @protected
                 */
                getNodeFromTarget: function (ev, dragNode, proxyNode) {
                    var node = this.get('node'),
                        domNode = node[0];
                    // 排除当前拖放和代理节点
                    return domNode == dragNode ||
                        domNode == proxyNode
                        ? null : node;
                },

                _active: function () {
                    var self = this,
                        drag = DDM.get('activeDrag'),
                        node = self.get('node'),
                        dropGroups = self.get('groups'),
                        dragGroups = drag.get('groups');
                    if (validDrop(dropGroups, dragGroups)) {
                        DDM._addValidDrop(self);
                        // 委托时取不到节点
                        if (node) {
                            node.addClass(PREFIX_CLS + 'drop-active-valid');
                            DDM.cacheWH(node);
                        }
                    } else if (node) {
                        node.addClass(PREFIX_CLS + 'drop-active-invalid');
                    }
                },

                _deActive: function () {
                    var node = this.get('node');
                    if (node) {
                        node.removeClass(PREFIX_CLS + 'drop-active-valid')
                            .removeClass(PREFIX_CLS + 'drop-active-invalid');
                    }
                },

                __getCustomEvt: function (ev) {
                    return S.mix({
                        drag: DDM.get('activeDrag'),
                        drop: this
                    }, ev);
                },

                _handleOut: function () {
                    var self = this,
                        ret = self.__getCustomEvt();
                    self.get('node').removeClass(PREFIX_CLS + 'drop-over');

                    // html5 => dragleave
                    self.fire('dropexit', ret);
                },

                _handleEnter: function (ev) {
                    var self = this,
                        e = self.__getCustomEvt(ev);
                    e.drag._handleEnter(e);
                    self.get('node').addClass(PREFIX_CLS + 'drop-over');
                    self.fire('dropenter', e);
                },

                _handleOver: function (ev) {
                    var self = this,
                        e = self.__getCustomEvt(ev);
                    e.drag._handleOver(e);
                    self.fire('dropover', e);
                },

                _end: function () {
                    var self = this,
                        ret = self.__getCustomEvt();
                    self.get('node').removeClass(PREFIX_CLS + 'drop-over');
                    self.fire('drophit', ret);
                },

                /**
                 * make this droppable' element undroppable
                 * @private
                 */
                destructor: function () {
                    DDM._unRegDrop(this);
                }
            }, {
                ATTRS: {
                    /**
                     * droppable element
                     * @cfg {String|HTMLElement|KISSY.NodeList} node
                     * @member KISSY.DD.Droppable
                     */
                    /**
                     * droppable element
                     * @type {KISSY.NodeList}
                     * @property node
                     * @member KISSY.DD.Droppable
                     */
                    /**
                     * @ignore
                     */
                    node: {
                        setter: function (v) {
                            if (v) {
                                return Node.one(v);
                            }
                        }
                    },

                    /**
                     * groups this droppable object belongs to. true to match any group.
                     * default  true
                     * @cfg {Object|Boolean} groups
                     * @member KISSY.DD.Droppable
                     */
                    /**
                     * @ignore
                     */
                    groups: {
                        value: true
                    }

                }
            });

        },
        { requires: ['node', 'rich-base', 'dd/base'] });