toolshed-8.x-1.x-dev/assets/DragDrop.es6.js

assets/DragDrop.es6.js
(({ Toolshed }) => {
  /**
   * Object wrapping a DOM element to implement a droppable container for
   * accepting draggable instances.
   */
  class Droppable {
    /**
     * Create a new instance of a droppable for containing draggables.
     *
     * @param {Element} el
     *   DOM element to treat as the droppable.
     * @param {Object} opts
     *   Configuration options to control how this droppable behaves.
     */
    constructor(el, opts = {}) {
      this.el = el;
      this.opts = {
        ...opts,
      };

      this.id = el.dataset.containerId;
      this.items = [];
      this.children = [];
    }

    getId() {
      return this.id;
    }

    getItems() {
      return this.items;
    }

    getChildren() {
      return this.children;
    }

    attachItem(item, pos) {
      const el = item.getElement();

      if ((pos || pos === 0) && this.items.length > pos) {
        this.el.insertBefore(el, this.items[pos].getElement());
        this.items.splice(pos, 0, el);
      }
      else {
        this.el.appendChild(item.getElement());
        this.items.push(item);
        pos = this.items.length - 1;
      }

      item.attach(this, pos);
    }

    detachItem(item) {
      for (let i = 0; i < this.items.length; ++i) {
        if (this.items[i] === item) {
          this.items.splice(i, 1);
          break;
        }
      }

      this.el.removeChild(item.getElement());
      item.detach();
    }
  }

  /**
   * A element that is draggable and can get placed into {Droppable} objects.
   */
  class Draggable {
    /**
     * Get the active dragging object instance, if there is a dragging action
     * in progress. There will only be a single draggable actively being dragged
     * at any given time.
     *
     * @return {Draggable|null}
     *   Return the draggable instance if there is one, otherwise return {null}.
     */
    static get dragging() {
      return this._dragging;
    }

    /**
     * Get the currently active dragging tracking to this draggable object.
     * This property is global because there should only be 1 active dragging
     * activity for the entire application, even if it is accross multiple
     * drag and drop sets.
     *
     * @param {Draggable|null} draggable
     *   Set the {Draggable} element as actively being dragged. Passing {null}
     *   as the parameter here is the same as unsetting cancelling any current
     *   dragging activity and clearing this property.
     */
    static set dragging(draggable) {
      if (this._dragging) {
        const oldDrag = this._dragging;

        oldDrag.cancelDrag(false);
      }

      this._dragging = draggable;
    }

    /**
     * Construct a new draggable handler.
     *
     * @param {Element} el
     *   The element to attach the draggable behaviors to.
     * @param {Object} opts
     *   The options for the draggable behaviors.
     */
    constructor(el, opts = {}) {
      this.el = el;
      this.opts = {
        inputSelector: 'input.drag-parent',
        ...opts,
      };

      this.parent = null;
      this.pos = 0;
      this.input = this.el.querySelector(this.opts.inputSelector);
    }

    getElement() {
      return this.el;
    }

    attach(droppable, pos) {
      this.parent = droppable;
      this.pos = pos;
      this.input.value = `${droppable.getId()}:${pos}`;
    }

    detach() {
      this.parent = null;
      this.pos = 0;
      this.input.value = '';
    }

    /**
     * Cancel the dragging action if it's been dragged.
     */
    cancelDrag() {
      if (this.placeholder) {
        this.placeholder.parentNode.removeChild(this.placeholder);
      }
    }
  }

  // Export the drag and drop definitions to the Toolshed namespace.
  Toolshed.Droppable = Droppable;
  Toolshed.Draggable = Draggable;
})(Drupal);

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc