| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 | (function() {  "use strict";  function buildDraggable(Sortable) {    function removeNode (node) {      node.parentElement.removeChild(node)    }    function insertNodeAt (fatherNode, node, position) {      if (position < fatherNode.children.length) {        fatherNode.insertBefore(node, fatherNode.children[position])      } else {        fatherNode.appendChild(node)      }    }    function computeVmIndex (vnodes, element) {      return vnodes.map(elt => elt.elm).indexOf(element)    }    function computeIndexes (slots, children) {      return (!slots)? [] : Array.prototype.map.call(children, elt => computeVmIndex(slots, elt))    }    function emit (evtName, evtData) {      this.$emit( evtName.toLowerCase(), evtData)    }    function delegateAndEmit (evtName) {      return (evtData) => {        if (this.list!==null) {          this['onDrag' + evtName](evtData)        }        emit.call(this, evtName, evtData)      }    }    const eventsListened = ['Start', 'Add', 'Remove', 'Update', 'End']    const eventsToEmit = ['Choose', 'Sort', 'Filter', 'Clone']    const readonlyProperties = ['Move', ...eventsListened, ...eventsToEmit].map(evt => 'on'+evt)    var draggingElement = null      const props = {      options: Object,      list: {         type: Array,        required: false,        default: null      },      clone: {        type: Function,        default : (original) => { return original;}      },      element: {        type: String,        default: 'div'      },      move: {        type: Function,        default: null      }    }    const draggableComponent = {      props,      data() {        return {          transitionMode: false        }      },      render (h) {        if (this.$slots.default && this.$slots.default.length===1) {          const child = this.$slots.default[0]          if (child.componentOptions && child.componentOptions.tag==="transition-group") {             this.transitionMode = true          }        }        return h(this.element, null, this.$slots.default);      },      mounted () {        var optionsAdded = {};        eventsListened.forEach( elt => {          optionsAdded['on' + elt] = delegateAndEmit.call(this, elt)        });        eventsToEmit.forEach( elt => {          optionsAdded['on' + elt] = emit.bind(this, elt)        });        const options = Object.assign({}, this.options, optionsAdded, { onMove: evt => {return this.onDragMove(evt);} })        this._sortable = new Sortable(this.rootContainer, options)        this.computeIndexes()      },      beforeDestroy () {        this._sortable.destroy()      },      computed : {        rootContainer () {          return this.transitionMode? this.$el.children[0] : this.$el;        }      },      watch: {        options (newOptionValue){          for(var property in newOptionValue) {            if (readonlyProperties.indexOf(property)==-1) {              this._sortable.option(property, newOptionValue[property] );            }                  }                 },        list(){          this.computeIndexes()        }      },      methods: {        getChildrenNodes () {          const rawNodes = this.$slots.default          return this.transitionMode? rawNodes[0].child.$slots.default : rawNodes        },        computeIndexes () {          this.$nextTick( () => {             this.visibleIndexes = computeIndexes(this.getChildrenNodes(), this.rootContainer.children)          })        },        getUnderlyingVm (htmlElt) {          const index = computeVmIndex(this.getChildrenNodes(), htmlElt)          const element = this.list[index]          return {index, element}        },        getUnderlyingPotencialDraggableComponent ({__vue__}) {          if (!__vue__ || !__vue__.$options || __vue__.$options._componentTag!=="transition-group"){            return __vue__          }          return __vue__.$parent        },        emitChanges (evt) {          this.$nextTick( ()=>{            this.$emit('change', evt)          });               },        spliceList () {          this.list.splice(...arguments)        },        updatePosition (oldIndex, newIndex) {          this.list.splice(newIndex, 0, this.list.splice(oldIndex, 1)[0])        },        getRelatedContextFromMoveEvent({to, related}) {          const component = this.getUnderlyingPotencialDraggableComponent(to)          if (!component) {            return {component}          }          const list = component.list          const context = {list, component}          if (to !== related && list && component.getUnderlyingVm) {            const destination = component.getUnderlyingVm(related)            return Object.assign(destination, context)          }          return context        },        getVmIndex (domIndex) {          const indexes = this.visibleIndexes          const numberIndexes = indexes.length          return (domIndex > numberIndexes - 1) ? numberIndexes : indexes[domIndex]        },        onDragStart (evt) {          this.context = this.getUnderlyingVm(evt.item)          evt.item._underlying_vm_ = this.clone(this.context.element)          draggingElement = evt.item        },        onDragAdd (evt) {          const element = evt.item._underlying_vm_          if (element === undefined) {            return          }          removeNode(evt.item)          const newIndex = this.getVmIndex(evt.newIndex)          this.spliceList(newIndex, 0, element)          this.computeIndexes()          const added = {element, newIndex}          this.emitChanges({added})        },        onDragRemove (evt) {          insertNodeAt(this.rootContainer, evt.item, evt.oldIndex)          const isCloning = !!evt.clone          if (isCloning) {            removeNode(evt.clone)            return          }          const oldIndex = this.context.index          this.spliceList(oldIndex, 1)          const removed = {element: this.context.element, oldIndex}          this.emitChanges({removed})        },        onDragUpdate (evt) {          removeNode(evt.item)          insertNodeAt(evt.from, evt.item, evt.oldIndex)          const oldIndex = this.context.index          const newIndex = this.getVmIndex(evt.newIndex)          this.updatePosition(oldIndex, newIndex)          const moved = {element: this.context.element, oldIndex, newIndex}          this.emitChanges({moved})        },        computeFutureIndex (relatedContext, evt) {          if (!relatedContext.element){            return 0          }          const domChildren = [...evt.to.children]          const currentDOMIndex = domChildren.indexOf(evt.related)          const currentIndex = relatedContext.component.getVmIndex(currentDOMIndex)          const draggedInList = domChildren.indexOf(draggingElement) != -1          return draggedInList? currentIndex : currentIndex+1        },        onDragMove (evt) {          const onMove = this.move          if (!onMove || !this.list) {            return true          }          const relatedContext = this.getRelatedContextFromMoveEvent(evt)          const draggedContext = this.context          const futureIndex = this.computeFutureIndex(relatedContext, evt)          Object.assign(draggedContext, { futureIndex })          Object.assign(evt, {relatedContext, draggedContext})          return onMove(evt)        },        onDragEnd (evt) {          this.computeIndexes()          draggingElement = null        }      }    }        return draggableComponent  }		 	  if (typeof exports == "object") {    var Sortable =  require("sortablejs")    module.exports = buildDraggable(Sortable)  } else if (typeof define == "function" && define.amd) {    define(['sortablejs'], function(Sortable) {return buildDraggable(Sortable);});  } else if ( window && (window.Vue) && (window.Sortable)) {    var draggable = buildDraggable(window.Sortable)    Vue.component('draggable', draggable)  }  })();
 |