Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

exports.getEventNodeFromPoint = getEventNodeFromPoint;
exports.isEvent = isEvent;
exports.objectsCollide = objectsCollide;
exports.getBoundsForNode = getBoundsForNode;

var _contains = require('dom-helpers/query/contains');

var _contains2 = _interopRequireDefault(_contains);

var _closest = require('dom-helpers/query/closest');

var _closest2 = _interopRequireDefault(_closest);

var _events = require('dom-helpers/events');

var _events2 = _interopRequireDefault(_events);

var _constants = require('./utils/constants');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function addEventListener(type, handler) {
  var target = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : document;

  // events.on(target, type, handler, { passive: false });
  target.addEventListener(type, handler, false);
  return {
    remove: function remove() {
      _events2.default.off(target, type, handler);
    }
  };
}

function isOverContainer(container, x, y) {
  return !container || (0, _contains2.default)(container, document.elementFromPoint(x, y));
}

function getEventNodeFromPoint(node, _ref) {
  var clientX = _ref.clientX,
      clientY = _ref.clientY;

  var target = document.elementFromPoint(clientX, clientY);
  return (0, _closest2.default)(target, '.rbc-event', node);
}

function isEvent(node, bounds) {
  return !!getEventNodeFromPoint(node, bounds);
}

function getEventCoordinates(e) {
  var target = e;

  if (e.touches && e.touches.length) {
    target = e.touches[0];
  } else if (e.changedTouches && e.changedTouches.length) {
    target = e.changedTouches[0];
  }

  return {
    clientX: target.clientX,
    clientY: target.clientY,
    pageX: target.pageX,
    pageY: target.pageY
  };
}

var clickTolerance = 10;
var clickInterval = 250;

var Selection = function () {
  function Selection(node) {
    var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
        _ref2$global = _ref2.global,
        global = _ref2$global === undefined ? false : _ref2$global,
        _ref2$longPressThresh = _ref2.longPressThreshold,
        longPressThreshold = _ref2$longPressThresh === undefined ? 250 : _ref2$longPressThresh;

    _classCallCheck(this, Selection);

    this.container = node;
    this.globalMouse = !node || global;
    this.longPressThreshold = longPressThreshold;

    this._listeners = Object.create(null);

    this._handleInitialEvent = this._handleInitialEvent.bind(this);
    this._handleMoveEvent = this._handleMoveEvent.bind(this);
    this._handleTouchMoveEvent = this._handleTouchMoveEvent.bind(this);
    this._handleTerminatingEvent = this._handleTerminatingEvent.bind(this);
    this._keyListener = this._keyListener.bind(this);

    // Fixes an iOS 10 bug where scrolling could not be prevented on the window.
    // https://github.com/metafizzy/flickity/issues/457#issuecomment-254501356
    this._onTouchMoveWindowListener = addEventListener('touchmove', function () {}, window);
    this._onKeyDownListener = addEventListener('keydown', this._keyListener);
    this._onKeyUpListener = addEventListener('keyup', this._keyListener);
    this._addInitialEventListener();
  }

  _createClass(Selection, [{
    key: 'on',
    value: function on(type, handler) {
      var handlers = this._listeners[type] || (this._listeners[type] = []);

      handlers.push(handler);

      return {
        remove: function remove() {
          var idx = handlers.indexOf(handler);
          if (idx !== -1) handlers.splice(idx, 1);
        }
      };
    }
  }, {
    key: 'emit',
    value: function emit(type) {
      for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
        args[_key - 1] = arguments[_key];
      }

      var result = void 0;
      var handlers = this._listeners[type] || [];
      handlers.forEach(function (fn) {
        if (result === undefined) result = fn.apply(undefined, args);
      });
      return result;
    }
  }, {
    key: 'teardown',
    value: function teardown() {
      this.listeners = Object.create(null);
      this._onTouchMoveWindowListener && this._onTouchMoveWindowListener.remove();
      this._onInitialEventListener && this._onInitialEventListener.remove();
      this._onEndListener && this._onEndListener.remove();
      this._onMoveListener && this._onMoveListener.remove();
      this._onKeyUpListener && this._onKeyUpListener.remove();
      this._onKeyDownListener && this._onKeyDownListener.remove();
    }
  }, {
    key: 'isSelected',
    value: function isSelected(node) {
      var box = this._selectRect;

      if (!box || !this.selecting) return false;

      return objectsCollide(box, getBoundsForNode(node));
    }
  }, {
    key: 'filter',
    value: function filter(items) {
      var box = this._selectRect;

      // not selecting
      if (!box || !this.selecting) return [];

      return items.filter(this.isSelected, this);
    }

    // Adds a listener that will call the handler only after the user has pressed on the screen
    // without moving their finger for 250ms.

  }, {
    key: '_addLongPressListener',
    value: function _addLongPressListener(handler, initialEvent) {
      var _this = this;

      var timer = null;
      var touchMoveListener = null;
      var touchEndListener = null;
      var handleTouchStart = function handleTouchStart(initialEvent) {
        timer = setTimeout(function () {
          cleanup();
          handler(initialEvent);
        }, _this.longPressThreshold);
        touchMoveListener = addEventListener('touchmove', function () {
          return cleanup();
        });
        touchEndListener = addEventListener('touchend', function () {
          return cleanup();
        });
      };
      var touchStartListener = addEventListener('touchstart', handleTouchStart);
      var cleanup = function cleanup() {
        if (timer) {
          clearTimeout(timer);
        }
        if (touchMoveListener) {
          touchMoveListener.remove();
        }
        if (touchEndListener) {
          touchEndListener.remove();
        }

        timer = null;
        touchMoveListener = null;
        touchEndListener = null;
      };

      if (initialEvent) {
        handleTouchStart(initialEvent);
      }

      return {
        remove: function remove() {
          cleanup();
          touchStartListener.remove();
        }
      };
    }

    // Listen for mousedown and touchstart events. When one is received, disable the other and setup
    // future event handling based on the type of event.

  }, {
    key: '_addInitialEventListener',
    value: function _addInitialEventListener() {
      var _this2 = this;

      var mouseDownListener = addEventListener('mousedown', function (e) {
        _this2._onInitialEventListener.remove();
        _this2._handleInitialEvent(e);
        _this2._onInitialEventListener = addEventListener('mousedown', _this2._handleInitialEvent);
      });
      var touchStartListener = addEventListener('touchstart', function (e) {
        _this2._onInitialEventListener.remove();
        _this2._handleInitialEvent(e);
        _this2._onInitialEventListener = addEventListener('touchstart', _this2._handleInitialEvent);
      });

      this._onInitialEventListener = {
        remove: function remove() {
          mouseDownListener.remove();
          touchStartListener.remove();
        }
      };
    }
  }, {
    key: '_handleInitialEvent',
    value: function _handleInitialEvent(e) {
      var _getEventCoordinates = getEventCoordinates(e),
          clientX = _getEventCoordinates.clientX,
          clientY = _getEventCoordinates.clientY,
          pageX = _getEventCoordinates.pageX,
          pageY = _getEventCoordinates.pageY;
      // due to the fact that the IE does not appropriately delete eventlisteners
      // should use this check


      if (_constants.isIE || _constants.isEdge) {
        if (!document.querySelector('.calendar')) return;
      }
      var node = this.container();

      var collides = void 0;

      var offsetData = void 0;

      // Right clicks
      if (e.which === 3 || e.button === 2 || !isOverContainer(node, clientX, clientY)) return;

      if (!this.globalMouse && node && !(0, _contains2.default)(node, e.target)) {
        var _normalizeDistance = normalizeDistance(0),
            top = _normalizeDistance.top,
            left = _normalizeDistance.left,
            bottom = _normalizeDistance.bottom,
            right = _normalizeDistance.right;

        offsetData = getBoundsForNode(node);

        collides = objectsCollide({
          top: offsetData.top - top,
          left: offsetData.left - left,
          bottom: offsetData.bottom + bottom,
          right: offsetData.right + right
        }, { top: pageY, left: pageX });

        if (!collides) return;
      }

      var result = this.emit('beforeSelect', this._initialEventData = {
        isTouch: /^touch/.test(e.type),
        x: pageX,
        y: pageY,
        clientX: clientX,
        clientY: clientY
      });

      if (result === false) return;

      switch (e.type) {
        case 'mousedown':
          this._onEndListener = addEventListener('mouseup', this._handleTerminatingEvent);
          this._onMoveListener = addEventListener('mousemove', this._handleMoveEvent);
          break;
        case 'touchstart':
          this.hoverSlotEnabled = false;
          this._onEndListener = addEventListener('touchend', this._handleTerminatingEvent);
          this._onMoveListener = addEventListener('touchmove', this._handleTouchMoveEvent);
          break;
        default:
          break;
      }
    }
  }, {
    key: '_handleTerminatingEvent',
    value: function _handleTerminatingEvent(e) {
      var _getEventCoordinates2 = getEventCoordinates(e),
          pageX = _getEventCoordinates2.pageX,
          pageY = _getEventCoordinates2.pageY;

      this.selecting = false;

      this._onEndListener && this._onEndListener.remove();
      this._onMoveListener && this._onMoveListener.remove();

      if (!this._initialEventData) return;

      var inRoot = !this.container || (0, _contains2.default)(this.container(), e.target);
      var bounds = this._selectRect;
      var click = this.isClick(pageX, pageY);

      this._initialEventData = null;

      if (click && !inRoot) {
        return this.emit('reset');
      }

      if (click && inRoot) {
        this.selecting = false;
        return this._handleClickEvent(e);
      }

      // User drag-clicked in the Selectable area
      if (!click) return this.emit('select', bounds);
    }
  }, {
    key: '_handleClickEvent',
    value: function _handleClickEvent(e) {
      var _getEventCoordinates3 = getEventCoordinates(e),
          pageX = _getEventCoordinates3.pageX,
          pageY = _getEventCoordinates3.pageY,
          clientX = _getEventCoordinates3.clientX,
          clientY = _getEventCoordinates3.clientY;

      var now = new Date().getTime();

      var slotHoverCoords = getBoundsForNode(document.querySelector('#rbc-timeslot-hover'));

      var clickY = this.hoverSlotEnabled && slotHoverCoords ? slotHoverCoords.top : pageY;
      var clickClientY = this.hoverSlotEnabled && slotHoverCoords && slotHoverCoords.y ? slotHoverCoords.y : clientY;

      this.hoverSlotEnabled = true;

      if (this._lastClickData && now - this._lastClickData.timestamp < clickInterval) {
        // Double click event
        this._lastClickData = null;
        return this.emit('doubleClick', {
          event: e,
          isTouch: /^touch/.test(e.type),
          x: pageX,
          y: clickY,
          clientX: clientX,
          clientY: clickClientY
        });
      }

      // Click event
      this._lastClickData = {
        timestamp: now
      };

      return this.emit('click', {
        event: e,
        isTouch: /^touch/.test(e.type),
        x: pageX,
        y: clickY,
        clientX: clientX,
        clientY: clickClientY
      });
    }
  }, {
    key: '_handleMoveEvent',
    value: function _handleMoveEvent(e) {
      if (this._initialEventData === null) {
        return;
      }

      var _initialEventData = this._initialEventData,
          x = _initialEventData.x,
          y = _initialEventData.y,
          isTouch = _initialEventData.isTouch;

      var _getEventCoordinates4 = getEventCoordinates(e),
          pageX = _getEventCoordinates4.pageX,
          pageY = _getEventCoordinates4.pageY;

      var w = Math.abs(x - pageX);
      var h = Math.abs(y - pageY);

      var left = Math.min(pageX, x);

      var top = Math.min(pageY, y);

      var old = this.selecting;

      // Prevent emitting selectStart event until mouse is moved.
      // in Chrome on Windows, mouseMove event may be fired just after mouseDown event.
      if (!old && !(w || h)) {
        return;
      }

      this.selecting = true;
      this._selectRect = {
        top: top,
        left: left,
        isTouch: isTouch,
        x: pageX,
        y: pageY,
        right: left + w,
        bottom: top + h,
        event: e
      };

      if (!old) {
        this.emit('selectStart', this._initialEventData);
      }

      if (!this.isClick(pageX, pageY)) this.emit('selecting', this._selectRect);

      if (e.cancelable) e.preventDefault();
    }
  }, {
    key: '_handleTouchMoveEvent',
    value: function _handleTouchMoveEvent(e) {
      if (!this._initialEventData) {
        return;
      }

      var _initialEventData2 = this._initialEventData,
          x = _initialEventData2.x,
          y = _initialEventData2.y,
          isTouch = _initialEventData2.isTouch;

      var _getEventCoordinates5 = getEventCoordinates(e),
          pageX = _getEventCoordinates5.pageX,
          pageY = _getEventCoordinates5.pageY;

      var w = Math.abs(x - pageX);
      var h = Math.abs(y - pageY);

      var left = Math.min(pageX, x);

      var top = Math.min(pageY, y);

      var old = this.selecting;

      // Prevent emitting selectStart event until mouse is moved.
      // in Chrome on Windows, mouseMove event may be fired just after mouseDown event.
      if (!old && !(w || h)) {
        return;
      }

      this.selecting = true;
      this._selectRect = {
        top: top,
        left: left,
        isTouch: isTouch,
        x: pageX,
        y: pageY,
        right: left + w,
        bottom: top + h,
        event: e
      };

      if (!old) {
        this.emit('selectStart', this._initialEventData);
      }
      this.emit('selecting', this._selectRect);
    }
  }, {
    key: '_keyListener',
    value: function _keyListener(e) {
      this.ctrl = e.metaKey || e.ctrlKey;
    }
  }, {
    key: 'isClick',
    value: function isClick(pageX, pageY) {
      var _initialEventData3 = this._initialEventData,
          x = _initialEventData3.x,
          y = _initialEventData3.y;

      return Math.abs(pageX - x) <= clickTolerance && Math.abs(pageY - y) <= clickTolerance;
    }
  }]);

  return Selection;
}();

/**
 * Resolve the disance prop from either an Int or an Object
 * @return {Object}
 */


function normalizeDistance() {
  var distance = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;

  if ((typeof distance === 'undefined' ? 'undefined' : _typeof(distance)) !== 'object') distance = {
    top: distance,
    left: distance,
    right: distance,
    bottom: distance
  };

  return distance;
}

/**
 * Given two objects containing "top", "left", "offsetWidth" and "offsetHeight"
 * properties, determine if they collide.
 * @param  {Object|HTMLElement} nodeA
 * @param  {Object|HTMLElement} nodeB
 * @param  {number} tolerance
 * @return {bool}
 */
function objectsCollide(nodeA, nodeB) {
  var tolerance = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;

  var _getBoundsForNode = getBoundsForNode(nodeA),
      aTop = _getBoundsForNode.top,
      aLeft = _getBoundsForNode.left,
      _getBoundsForNode$rig = _getBoundsForNode.right,
      aRight = _getBoundsForNode$rig === undefined ? aLeft : _getBoundsForNode$rig,
      _getBoundsForNode$bot = _getBoundsForNode.bottom,
      aBottom = _getBoundsForNode$bot === undefined ? aTop : _getBoundsForNode$bot;

  var _getBoundsForNode2 = getBoundsForNode(nodeB),
      bTop = _getBoundsForNode2.top,
      bLeft = _getBoundsForNode2.left,
      _getBoundsForNode2$ri = _getBoundsForNode2.right,
      bRight = _getBoundsForNode2$ri === undefined ? bLeft : _getBoundsForNode2$ri,
      _getBoundsForNode2$bo = _getBoundsForNode2.bottom,
      bBottom = _getBoundsForNode2$bo === undefined ? bTop : _getBoundsForNode2$bo;

  return !( // 'a' bottom doesn't touch 'b' top
  aBottom - tolerance < bTop ||
  // 'a' top doesn't touch 'b' bottom
  aTop + tolerance > bBottom ||
  // 'a' right doesn't touch 'b' left
  aRight - tolerance < bLeft ||
  // 'a' left doesn't touch 'b' right
  aLeft + tolerance > bRight);
}

/**
 * Given a node, get everything needed to calculate its boundaries
 * @param  {HTMLElement} node
 * @return {Object}
 */
function getBoundsForNode(node) {
  if (!node || !node.getBoundingClientRect) return node;

  var rect = node.getBoundingClientRect();

  var left = rect.left + pageOffset('left');

  var top = rect.top + pageOffset('top');

  return {
    x: rect.x,
    y: rect.y,
    top: top,
    left: left,
    right: (node.offsetWidth || 0) + left,
    bottom: (node.offsetHeight || 0) + top
  };
}

function pageOffset(dir) {
  if (dir === 'left') return window.pageXOffset || document.body.scrollLeft || 0;
  if (dir === 'top') return window.pageYOffset || document.body.scrollTop || 0;
}
exports.default = Selection;