Marionette JS Client

API Docs for: 1.7.1
Show:

File: lib/marionette/actions.js

(function(module, ns) {

  /**
   * Actions is used to denote a set of actions that
   * have to be executed in particular order.
   *
   * @class Marionette.Actions
   * @param {Marionette.Client} context of a client.
   */
  function Actions(client) {
    this.client = client;
    this.actionChain = [];
    this.currentId = null;
  }

  Actions.prototype = {

    /**
     * Send a 'touchstart' event to this element. If no coordinates are given,
     * it will be targeted at the center of the element.
     * If given, it will be targeted at the (x,y) coordinates
     * relative to the top-left corner of the element.
     *
     * @method press
     * @param {Object} element {{#crossLink "Marionette.Element"}}{{/crossLink}}
     *                         to press on.
     * @param {Number} x optional, x-coordinate to tap,
     *                   relative to the top-left corner of the element.
     * @param {Number} y optional, y-coordinate to tap,
     *                   relative to the top-left corner of the element.
     * @return {Object} self.
     */
    press: function press(element, x, y) {
      this.actionChain.push(['press', element.id, x, y]);
      return this;
    },

    /**
     * release() can only be called
     * if press() has already be called on this element.
     * Send 'touchend' event to whenever the finger is.
     *
     * @method release
     *
     * @return {Object} self.
     */
    release: function release() {
      this.actionChain.push(['release']);
      return this;
    },

    /**
     * move() can only be called
     * if press() has already be called on this element.
     * move() send 'touchmove' event which moves the finger to target element.
     *
     * @method move
     * @param {Object} element {{#crossLink "Marionette.Element"}}{{/crossLink}}
     *                         of the move gesture.
     *
     * @return {Object} self.
     */
    move: function move(element) {
      this.actionChain.push(['move', element.id]);
      return this;
    },

    /**
     * moveByOffset() can only be called
     * if press() has already be called on this element.
     * moveByOffset() send 'touchmove' event.
     *
     * @method moveByOffset
     *
     * @param {Number} x x-coordinate relative to the top-left corner of
     *                   the target element of the last touch.
     *
     * @param {Number} y y-coordinate relative to the top-left corner of
     *                   the target element of the last touch.
     *
     * @return {Object} self.
     */
    moveByOffset: function moveByOffset(x, y) {
      this.actionChain.push(['moveByOffset', x, y]);
      return this;
    },

    /**
     * wait() waits for specified time period.
     *
     * @method wait
     * @param {Number} time wait for "time" seconds.
     *
     * @return {Object} self.
     */
    wait: function wait(time) {
      this.actionChain.push(['wait', time]);
      return this;
    },

    /**
     * cancel() can only be called
     * if press() has already be called on this element.
     * cancel() send 'touchcancel' event to whenever the finger is.
     *
     * @method cancel
     *
     * @return {Object} self.
     */
    cancel: function cancel() {
      this.actionChain.push(['cancel']);
      return this;
    },

    /**
     * tap() performs a quick tap on the target.
     * action.tap() is essentially action.press().release().
     *
     * @method tap
     * @param {Object} element {{#crossLink "Marionette.Element"}}{{/crossLink}}
     *                         to press/release on.
     *
     * @param {Number} x optional, x-coordinate relative to the top-left corner
     *                   of the element of the last touch.
     *
     * @param {Number} y optional, y-coordinate relative to the top-left corner
     *                   of the element of the last touch.
     *
     * @return {Object} self.
     */
    tap: function tap(element, x, y) {
      this.actionChain.push(['press', element.id, x, y]);
      this.actionChain.push(['release']);
      return this;
    },

    /**
     * doubleTap() performs a double
     * {{#crossLink "Marionette.Actions/tap"}}{{/crossLink}} on the element.
     *
     * @method doubleTap
     * @param {Object} element {{#crossLink "Marionette.Element"}}{{/crossLink}}
     *                         to double tap on.
     *
     * @param {Number} x optional, x-coordinate relative to
     * the top-left corner of the element of the last touch.
     *
     * @param {Number} y optional, y-coordinate relative to
     * the top-left corner of the element of the last touch.
     *
     * @return {Object} self.
     */
    doubleTap: function doubleTap(element, x, y) {
      this.actionChain.push(['press', element.id, x, y]);
      this.actionChain.push(['release']);
      this.actionChain.push(['press', element.id, x, y]);
      this.actionChain.push(['release']);
      return this;
    },

    /**
     * flick() sends a sequence of touch events:
     * touchstart, touchmove, touchend.
     * It scrolls the page in any direction
     * within period of time provided(duration).
     *
     * @method flick
     * @param {Object} element {{#crossLink "Marionette.Element"}}{{/crossLink}}
     *                         to double tap on.
     *
     * @param {Number} x1 starting x-coordinates of
     *                    the finger relative to the element.
     *
     * @param {Number} y1 starting y-coordinates of
     *                    the finger relative to the element.
     *
     * @param {Number} x2 ending x-coordinates of
     *                    the finger relative to the element.
     *
     * @param {Number} y2 ending y-coordinates of
     *                    the finger relative to the element.
     *
     * @param {Number} duration optional,
     *                          time needed for the flick gesture for complete.
     *
     * @return {Object} self.
     */
    flick: function flick(element, x1, y1, x2, y2, duration) {
      var time = 0;
      var timeIncrement = 10.0;
      if (duration === undefined) {
        duration = 200;
      }
      if (timeIncrement >= duration) {
        timeIncrement = duration;
      }
      var moveX = timeIncrement / duration * (x2 - x1);
      var moveY = timeIncrement / duration * (y2 - y1);

      this.actionChain.push(['press', element.id, x1, y1]);
      while (time < duration) {
        time += timeIncrement;
        this.actionChain.push(['moveByOffset', moveX, moveY]);
        this.actionChain.push(['wait', timeIncrement / 1000]);
      }
      this.actionChain.push(['release']);

      return this;
    },

    /**
     * Sends 'touchstart',
     * then wait for 'time' seconds, and send 'touchend' eventually.
     * longPress() cannot follow any active touch,
     * i.e. the finger must leave the screen before longPress() gets called.
     *
     * @method longPress
     * @param {Object} element {{#crossLink "Marionette.Element"}}{{/crossLink}}
     *                         of the long press.
     *
     * @param {Number} time the waiting time between touchstart and touchend.
     *
     * @return {Object} self.
     */
    longPress: function longPress(element, time) {
      this.actionChain.push(['press', element.id]);
      this.actionChain.push(['wait', time]);
      this.actionChain.push(['release']);
      return this;
    },

    /**
     * perform() will send the whole action chain built
     * so far to the server side for execution.
     *
     * @method perform
     * @param {Function} callback callback when the perform completes.
     *
     * @return {Object} self.
     */
    perform: function perform(callback) {
      var cmd = {
        name: 'actionChain',
        parameters: {
          chain: this.actionChain,
          nextId: this.currentId
        }
      };
      this.currentId = this.client._sendCommand(cmd, 'value', callback);
      this.actionChain = [];
      return this;
    }
  };

  module.exports = Actions;

}.apply(
  this,
  (this.Marionette) ?
    [Marionette('actions'), Marionette] :
    [module, require('../../lib/marionette/marionette')]
));