<commit_before>/**
 * Split into declaration and initialization for better startup performance.
 */

var Projects = require('../models/Projects')

module.exports = {
  /**
   * GET /projects
   * List of Project examples.
   */
  getProjects: function (req, res) {
    Projects.find({brigade: res.locals.brigade.slug}, function (err, foundProjects) {
      if (err) console.error(err)
      var allKeywords = []
      foundProjects.forEach(function (project) {
        project.keywords.forEach(function (keyword) {
          if (allKeywords.indexOf(keyword) < 0) {
            allKeywords.push(keyword)
          }
        })
      })
      res.render(res.locals.brigade.theme.slug + '/views/projects/index', {
        view: 'project-list',
        title: 'Projects',
        brigade: res.locals.brigade,
        projects: foundProjects,
        keywords: allKeywords.sort()
      })
    })
  },
  /**
   * GET /projects/manage
   * Manage Projects.
   */
  getProjectsManage: function (req, res) {
    Projects.find({brigade: res.locals.brigade.slug}, function (err, foundProjects) {
      if (err) console.error(err)
      console.log(foundProjects)
      res.render(res.locals.brigade.theme.slug + '/views/projects/manage', {
        view: 'project-list-manage',
        title: 'Manage Projects',
        brigade: res.locals.brigade,
        projects: foundProjects
      })
    })
  },
  /**
   * POST /projects/manage
   * Update all Projects.
   */
  postProjectsManage: function (req, res) {
    res.redirect('projects/manage')
  },
  /**
   * GET /projects/new
   * New Projects.
   */
  getProjectsNew: function (req, res) {
    res.render(res.locals.brigade.theme.slug + '/views/projects/new', {
      view: 'project-new',
      title: 'New Projects',
      brigade: res.locals.brigade
    })
  },
  /**
   * POST /projects/new
   * Submit New Projects.
   */
  postProjectsNew: function (req, res) {
    res.redirect('projects/new')
  },

  /**
   * GET /projects/:projectID
   * Display Project by ID.
   */
  getProjectsID: function (req, res) {
    Projects.findOne({
      brigade: res.locals.brigade.slug,
      id: req.params.projectId
    }, function (err, foundProject) {
      if (err) console.error(err)
      Projects.fetchGitHubUsers(foundProject.contact, function (result) {
        res.render(res.locals.brigade.theme.slug + '/views/projects/project', {
          view: 'project',
          projectId: req.params.projectId,
          title: foundProject.name,
          brigade: res.locals.brigade,
          project: foundProject,
          contacts: result
        })
      })
    })
  },
  /**
   * GET /projects/:projectID/settings
   * IDSettings Projects.
   */
  getProjectsIDSettings: function (req, res) {
    Projects.find({'id': req.params.projectId}, function (err, foundProject) {
      if (err) console.log(err)
      res.render(res.locals.brigade.theme.slug + '/views/projects/settings', {
        view: 'project-settings',
        project: foundProject[0],
        title: 'IDSettings Projects',
        brigade: res.locals.brigade
      })
    })
  },
  /**
   * POST /projects/:projectID/settings
   * Submit IDSettings Projects.
   */
  postProjectsIDSettings: function (req, res) {
    Projects.find({'id': req.params.projectId}, function (err, foundProject) {
      if (err) console.log(err)
      var thisProject = foundProject[0]
      thisProject.categories = []
      thisProject.needs = []
      thisProject.contact = []
      thisProject.name = req.body.title || ''
      thisProject.status = req.body.status || ''
      thisProject.type = req.body.type || ''
      thisProject.homepage = req.body.homepage || ''
      thisProject.repository = req.body.repository || ''
      thisProject.description = req.body.description || ''
      if (req.body.categories) {
        req.body.categories.split(',').forEach(function (category) {
          thisProject.categories.push(category)
        })
      }
      if (req.body.contacts) {
        req.body.contacts.replace(/\s/g, '').split(',').forEach(function (contact) {
          thisProject.contact.push(contact)
        })
      }
      if (req.body.needs) {
        req.body.needs.split(',').forEach(function (need) {
          thisProject.needs.push(need)
        })
      }

      thisProject.save(function (err) {
        if (err) console.log(err)
      })
    })
    console.log(req.body)
    res.redirect('/projects/' + req.params.projectId + '/settings')
  },
  /**
   * POST /projects/sync
   * Sync Projects.
   */
  postProjectsSync: function (req, res) {
    Projects.fetchGithubRepos(res.locals.brigade, req.user, function (results) {
      req.flash('success', { msg: 'Success! You have successfully synced projects from Github.' })
      res.redirect('/projects/manage')
    })
  },
  /**
   * POST /projects/:projectID/settings
   * Submit IDSettings Projects.
   */
  postProjectsIDSync: function (req, res) {
    res.redirect('projects/:projectID/settings')
  }
}
<commit_msg>re-add controller work lost in merge conflict.<commit_after>/**
 * Split into declaration and initialization for better startup performance.
 */

var Projects = require('../models/Projects')

module.exports = {
  /**
   * GET /projects
   * List of Project examples.
   */
  getProjects: function (req, res) {
    Projects.find({brigade: res.locals.brigade.slug}, function (err, foundProjects) {
      if (err) console.error(err)
      var allKeywords = []
      foundProjects.forEach(function (project) {
        project.keywords.forEach(function (keyword) {
          if (allKeywords.indexOf(keyword) < 0) {
            allKeywords.push(keyword)
          }
        })
      })
      res.render(res.locals.brigade.theme.slug + '/views/projects/index', {
        view: 'project-list',
        title: 'Projects',
        brigade: res.locals.brigade,
        projects: foundProjects,
        keywords: allKeywords.sort()
      })
    })
  },
  /**
   * GET /projects/manage
   * Manage Projects.
   */
  getProjectsManage: function (req, res) {
    Projects.find({brigade: res.locals.brigade.slug}, function (err, foundProjects) {
      if (err) console.error(err)
      console.log(foundProjects)
      res.render(res.locals.brigade.theme.slug + '/views/projects/manage', {
        view: 'project-list-manage',
        title: 'Manage Projects',
        brigade: res.locals.brigade,
        projects: foundProjects
      })
    })
  },
  /**
   * POST /projects/manage
   * Update all Projects.
   */
  postProjectsManage: function (req, res) {
    res.redirect('projects/manage')
  },
  /**
   * GET /projects/new
   * New Projects.
   */
  getProjectsNew: function (req, res) {
    res.render(res.locals.brigade.theme.slug + '/views/projects/new', {
      view: 'project-new',
      title: 'New Projects',
      brigade: res.locals.brigade
    })
  },
  /**
   * POST /projects/new
   * Submit New Projects.
   */
  postProjectsNew: function (req, res) {
    res.redirect('projects/new')
  },

  /**
   * GET /projects/:projectID
   * Display Project by ID.
   */
  getProjectsID: function (req, res) {
    Projects.findOne({
      brigade: res.locals.brigade.slug,
      id: req.params.projectId
    }, function (err, foundProject) {
      if (err) console.error(err)
      Projects.fetchGitHubUsers(foundProject.contact, function (contactList) {
        res.render(res.locals.brigade.theme.slug + '/views/projects/project', {
          view: 'project',
          projectId: req.params.projectId,
          title: foundProject.name,
          brigade: res.locals.brigade,
          project: foundProject,
          contacts: contactList
        })
      })
    })
  },
  /**
   * GET /projects/:projectID/settings
   * IDSettings Projects.
   */
  getProjectsIDSettings: function (req, res) {
    Projects.find({'id': req.params.projectId}, function (err, foundProject) {
      if (err) console.log(err)
      res.render(res.locals.brigade.theme.slug + '/views/projects/settings', {
        view: 'project-settings',
        project: foundProject[0],
        title: 'IDSettings Projects',
        brigade: res.locals.brigade
      })
    })
  },
  /**
   * POST /projects/:projectID/settings
   * Submit IDSettings Projects.
   */
  postProjectsIDSettings: function (req, res) {
    Projects.find({'id': req.params.projectId}, function (err, foundProject) {
      if (err) console.log(err)
      var thisProject = foundProject[0]
      thisProject.categories = []
      thisProject.needs = []
      thisProject.contact = []
      thisProject.data = []
      thisProject.keywords = []
      thisProject.name = req.body.title || ''
      thisProject.status = req.body.status || ''
      thisProject.type = req.body.type || ''
      thisProject.politicalEntity = req.body.politicalEntity || ''
      thisProject.geography = req.body.geography || ''
      thisProject.homepage = req.body.homepage || ''
      thisProject.repository = req.body.repository || ''
      thisProject.description = req.body.description || ''
      if (req.body.categories) {
        req.body.categories.replace(/\s/g, '').split(',').forEach(function (category) {
          thisProject.categories.push(category)
        })
      }
      if (req.body.contacts) {
        req.body.contacts.replace(/\s/g, '').split(',').forEach(function (contact) {
          thisProject.contact.push(contact)
        })
      }
      if (req.body.needs) {
        req.body.needs.replace(/\s/g, '').split(',').forEach(function (need) {
          thisProject.needs.push(need)
        })
      }
      if (req.body.keywords) {
        req.body.keywords.replace(/\s/g, '').split(',').forEach(function (keyword) {
          thisProject.keywords.push(keyword)
        })
      }
      if (req.body.data) {
        req.body.data.replace(/\s/g, '').split(',').forEach(function (datum) {
          thisProject.data.push(datum)
        })
      }
      thisProject.save(function (err) {
        if (err) console.log(err)
      })
    })
    console.log(req.body)
    res.redirect('/projects/' + req.params.projectId + '/settings')
  },
  /**
   * POST /projects/sync
   * Sync Projects.
   */
  postProjectsSync: function (req, res) {
    Projects.fetchGithubRepos(res.locals.brigade, req.user, function (results) {
      req.flash('success', { msg: 'Success! You have successfully synced projects from Github.' })
      res.redirect('/projects/manage')
    })
  },
  /**
   * POST /projects/:projectID/settings
   * Submit IDSettings Projects.
   */
  postProjectsIDSync: function (req, res) {
    res.redirect('projects/:projectID/settings')
  }
}
<|endoftext|>


<commit_before>/**
 * jQuery AutoComplete Component.
 */

(function($) {

  'use strict';

  var identity = function(param) {
    return param;
  };

  var noop = function() {
  };

  /**
   * Plugin name in jQuery cache data.
   * @type {string}
   * @const
   * @private
   */
  var PLUGIN_NAME = 'jqAutoComplete';

  /**
   * Enter Key Code.
   * @type {number}
   * @const
   * @private
   */
  var ENTER_KEY = 13;

  /**
   * Key associated to arrow down on keyboard.
   * @type {number}
   * @const
   * @private
   */
  var ARROW_DOWN = 40;

  /**
   * Key associated to arrow up on keyboard.
   * @type {number}
   * @const
   * @private
   */
  var ARROW_UP = 38;

  /**
   * Key associated to tab on keyboard.
   * @type {number}
   * @const
   * @private
   */
  var TAB = 9;

  /**
   * Css class use on list items.
   * @type {string}
   * @const
   * @private
   */
  var ITEM_CLASS = 'jq-autocomplete-item';

  /**
   * Css class use on active items.
   * @type {string}
   * @const
   * @private
   */
  var ACTIVE_CLASS = 'jq-autocomplete-item-active';

  /**
   * Css class use on result list.
   * @type {string}
   * @const
   * @private
   */
  var RESULT_CLASS = 'jq-autocomplete-results';

  /**
   * Get attribute value of object.
   * @param {object} obj Object to look for.
   * @param {string} key Name of attribute.
   * @returns {*} Value associated to key in object.
   * @private
   */
  var attr = function(obj, key) {
    if (!obj || !key) {
      return obj;
    }

    var subKeys = key.split('.');
    var current = obj;
    var ln = subKeys.length;
    for (var i = 0; i < (ln - 1); ++i) {
      current = current[subKeys[i]];
      if (current === null || current === undefined) {
        return '';
      }
    }

    return current[subKeys[ln - 1]];
  };

  var data = function($obj, data) {
    var value = $obj.attr('data-' + data);
    if (value === '') {
      value = undefined;
    }
    return value;
  };

  var AutoComplete = function(options, input) {
    this.$input = $(input);

    // Override options with data attributes
    this.opts = $.extend({}, options, this.readDatas());

    this.caches = {};
    this.filter = '';
    this.results = [];
    this.idx = -1;

    this.top = -1;
    this.left = -1;
    this.width = -1;

    this.timer = null;
    this.xhr = null;
  };

  AutoComplete.prototype = {
    /**
     * Initialize autocomplete.
     * @public
     */
    init: function() {
      this.$ul = $('

').addClass(RESULT_CLASS);

      var relativeTo = this.opts.relativeTo;
      var position = 'fixed';
      var isFixed = !!(relativeTo === 'fixed');

      if (!isFixed) {
        var $relativeTo = relativeTo ? $(relativeTo) : this.$input.parent();
        $relativeTo.css('position', 'relative');
        position = 'absolute';
      }

      this.position = position;
      this.fixed = isFixed;
      this.positionResult();

      this.$input.after(this.$ul);

      // Bind User-Events
      this.bind();
    },

    /**
     * Read data attributes used to initialize autocomplete.
     * @return {object} Initialization object initialized with data attributes.
     * @public
     */
    readDatas: function() {
      var datas = {};
      var $input = this.$input;
      datas.minSize = data($input, 'min-size');
      datas.limit = data($input, 'limit');
      datas.url = data($input, 'url');
      datas.method = data($input, 'method');
      datas.limitName = data($input, 'limit-name');
      datas.filterName = data($input, 'filter-name');
      datas.label = data($input, 'label');
      datas.cache = data($input, 'cache') || false;
      datas.relativeTo = data($input, 'relative-to');

      if (datas.minSize !== undefined) {
        datas.minSize = parseInt(datas.minSize, 10);
      }
      if (datas.limit !== undefined) {
        datas.limit = parseInt(datas.limit, 10);
      }
      if (typeof datas.cache === 'string') {
        datas.cache = !!(datas.cache === 'true');
      }

      return datas;
    },

    /**
     * Position result list in fixed position below input field.
     * @public
     */
    positionResult: function() {
      // Get Input Position
      var $input = this.$input;

      var position = this.fixed ? $input.offset() : $input.position();
      var width = $input.outerWidth();
      var height = $input.outerHeight();

      var left = position.left;
      var top = position.top + height;

      if (this.left !== left || this.top !== top || this.width !== width) {
        this.left = left;
        this.top = top;
        this.width = width;

        this.$ul.css({
          'position': this.position,
          'left': left,
          'top': top,
          'width': width
        });
      }
    },

    /**
     * Bind User-Events on autocomplete.
     * @public
     */
    bind: function() {
      var that = this;

      this.$input.on('keyup.jqauto', function(e) {
        var keyCode = e.keyCode;
        if (keyCode === ENTER_KEY) {
          // Enter key
          that.select(that.idx);
          $(this).focus();
        }
        else if (keyCode !== ARROW_DOWN && keyCode !== ARROW_UP) {
          var filter = $.trim($(this).val());
          if (filter.length >= that.opts.minSize) {
            that.fetch(filter);
          }
          else {
            that.filter = filter;
            that.$hide();
            that.clear();
          }
        }
      });

      this.$input.on('keydown.jqauto', function(e) {
        var keyCode = e.keyCode;
        if (keyCode === ARROW_DOWN) {
          e.preventDefault();
          e.stopPropagation();
          that.highlight(that.idx + 1);
        }
        else if (keyCode === ARROW_UP) {
          e.preventDefault();
          e.stopPropagation();
          that.highlight(that.idx - 1);
        }
        else if (keyCode === TAB) {
          that.select(that.idx);
        }
      });

      this.$input.on('focusout.jqauto', function() {
        that.focus = false;
        var $this = $(this);
        setTimeout(function() {
          if (!that.focus && that.$ul) {
            that.$hide();
            if (!that.item) {
              that.autoSelect($.trim($this.val()));
            }
          }
        }, 200);
      });

      this.$input.on('focusin.jqauto', function() {
        that.focus = true;
        if ((!that.item) && (that.results.length > 0)) {
          that.$show();
        }
      });

      this.$ul.on('mouseenter.jqauto', function() {
        $(this).find('li').removeClass(ACTIVE_CLASS);
      });

      this.$ul.on('click.jqauto', 'li', function() {
        that.select(parseInt($(this).attr('data-idx'), 10));
        that.$input.focus();
      });
    },

    /**
     * Check if item is set.
     * @returns {boolean} True if item is set, false otherwise.
     * @public
     */
    itemIsEmpty: function() {
      return this.item === undefined || this.item === null;
    },

    /**
     * Fetch results with given filter.
     * @param {string} filter Filter to fetch.
     * @public
     */
    fetch: function(filter) {
      if (this.filter === filter) {
        // If filter do not change, don't do anything
        if (this.itemIsEmpty()) {
          this.$show();
        }
        return;
      }

      if (!this.itemIsEmpty()) {
        this.opts.unSelect.call(this);
      }

      // Filter changed, unset item
      this.item = null;

      // Update filter
      this.filter = filter;

      // Abort current request if a request is pending
      if (this.xhr) {
        this.xhr.abort();
        this.xhr = null;
      }

      // Abort current timer
      if (this.timer) {
        clearTimeout(this.timer);
        this.timer = null;
      }

      var that = this;

      // Use a case-insensitive cache
      var key = filter.toLowerCase();

      if (this.opts.cache && this.caches[key]) {
        // Get from cache
        this.show(this.caches[key]);
      }
      else {
        var request = function() {
          // Build default parameters
          var params = {};

          params[that.opts.filterName] = that.filter;
          if (that.opts.limit > 0) {
            params[that.opts.limitName] = that.opts.limit;
          }

          // Append custom datas to parameters
          if (that.opts.datas) {
            if (typeof that.opts.datas === 'object') {
              params = $.extend(params, that.opts.datas);
            }
            else if (typeof that.opts.datas === 'function') {
              params = $.extend(params, that.opts.datas.apply(this));
            }
          }

          // Launch request
          that.xhr = $.ajax({
            url: that.opts.url,
            type: that.opts.method,
            dataType: 'json',
            data: params
          });

          that.xhr.done(function(datas) {
            that.timer = null;
            that.xhr = null;

            if (that.opts.cache) {
              // Store in cache
              that.caches[key] = datas;
            }

            that.show(datas);
          });
        };

        // Launch request in 200ms
        // If user type something else in the meantime, request will be aborted
        this.timer = setTimeout(request, 200);
      }
    },

    /**
     * Clear cache.
     * @public
     */
    clearCache: function() {
      this.caches = {};
    },

    /**
     * Show current datas in results list.
     * @param {Array<object>} datas New results to display.
     * @public
     */
    show: function(datas) {
      this.results = datas;

      if (datas.length === 0) {
        this.clear();
        return;
      }

      this.$hide().empty();

      for (var i = 0, ln = datas.length; i < ln; ++i) {
        var label = this.renderItem(datas[i]);
        $('
')
          .addClass(ITEM_CLASS)
          .attr('data-idx', i)
          .attr('title', label)
          .html(label)
          .appendTo(this.$ul);
      }

      this.$show();
    },

    /**
     * Show result list.
     * @returns {jQuery} Result list object.
     * @public
     */
    $show: function() {
      this.positionResult();
      return this.$ul.show();
    },

    /**
     * Hide result list.
     * @returns {jQuery} Result list object.
     * @public
     */
    $hide: function() {
      return this.$ul.hide();
    },

    /**
     * Set item as selected value.
     * @param {*} obj Object to select.
     * @public
     */
    setItem: function(obj) {
      this.item = obj;
      this.filter = this.renderItem(obj);
      this.$input.val(this.filter);
      this.$hide();
      this.idx = -1;
      this.opts.select.call(this, obj);
    },

    /**
     * Render an item.
     * @param {object|string|number} obj Object to render.
     * @returns {*} Result of render function.
     * @public
     */
    renderItem: function(obj) {
      var label = this.opts.label;
      var txt = $.isFunction(label) ? label.call(null, obj) : attr(obj, label);
      if (txt === undefined || txt === null) {
        txt = '';
      }
      return txt;
    },

    /**
     * Select item at given index (into results list).
     * @param {number} idx Index.
     * @public
     */
    select: function(idx) {
      if (idx >= 0 && idx < this.results.length) {
        this.setItem(this.results[idx]);
      }
    },

    /**
     * Auto Select a result in the list of results.

     * We search for the same filter (case insensitive) in the list of results.
     * @param {string} filter Current filter to search.
     * @public
     */
    autoSelect: function(filter) {
      var results = this.results;
      var f = filter.toLowerCase();

      for (var i = 0, ln = results.length; i < ln; ++i) {
        var label = this.renderItem(results[i]).toLowerCase();
        if (label === f) {
          this.select(i);
          return;
        }
      }
    },

    /**
     * Highlight item at given index.
     * @param {number} idx Index.
     * @public
     */
    highlight: function(idx) {
      var ln = this.results.length;
      if (!ln) {
        return;
      }

      if (idx < 0) {
        idx = ln - 1;
      }
      else if (idx >= ln) {
        idx = 0;
      }

      this.$ul.find('li')
        .removeClass(ACTIVE_CLASS)
        .eq(idx).addClass(ACTIVE_CLASS);

      this.idx = idx;
    },

    /**
     * Clear autocomplete :
     * - Clear and hide results.
     * - Reset variable storing results and current selected item.
     * @public
     */
    clear: function() {
      if (this.item !== undefined && this.item !== null) {
        this.opts.unSelect.call(this);
      }

      this.$ul.empty().hide();
      this.results = [];
      this.idx = -1;
      this.item = null;
    },

    /**
     * Clear autocomplete and set input to an empty string.
     * @public
     */
    empty: function() {
      this.clear();
      this.$input.val('');
    },

    /**
     * Unbind user events handlers.
     * @public
     */
    unbind: function() {
      this.$input.off('.jqauto');
      this.$ul.off('.jqauto');
    },

    /**
     * Destroy autocomplete component.
     * @public
     */
    destroy: function() {
      this.unbind();
      this.$ul.remove();

      if (this.timer) {
        clearTimeout(this.timer);
      }
      if (this.xhr) {
        this.xhr.abort();
      }

      for (var i in this) {
        if (this.hasOwnProperty(i)) {
          this[i] = null;
        }
      }
    }
  };

  $.fn.jqAutoComplete = function(options) {
    var that = this;

    this.destroy = function() {
      $(this).data(PLUGIN_NAME).destroy();
      return that;
    };

    this.clear = function() {
      $(this).data(PLUGIN_NAME).clear();
      return that;
    };

    this.empty = function() {
      $(this).data(PLUGIN_NAME).empty();
      return that;
    };

    this.item = function(obj) {
      var autocomplete = $(this).data(PLUGIN_NAME);
      if (obj) {
        autocomplete.setItem(obj);
        return that;
      }
      return autocomplete.item;
    };

    this.clearCache = function() {
      $(this).data(PLUGIN_NAME).clearCache();
      return that;
    };

    return this.each(function() {
      var autocomplete = $(this).data(PLUGIN_NAME);
      if (!autocomplete) {
        var opts = $.extend({}, $.fn.jqAutoComplete.options);
        if (typeof options === 'object') {
          opts = $.extend(opts, options);
        }
        autocomplete = new AutoComplete(opts, this);
        autocomplete.init();
      }
      $(this).data(PLUGIN_NAME, autocomplete);
    });
  };

  $.fn.jqAutoComplete.options = {
    url: '',
    label: identity,
    minSize: 3,
    method: 'GET',
    filterName: 'filter',
    limitName: 'limit',
    limit: 10,
    datas: null,
    cache: false,
    select: noop,
    unSelect: noop
  };

})(jQuery);
<commit_msg>build: ignore jshint warning<commit_after>/**
 * jQuery AutoComplete Component.
 */

(function($) {

  'use strict';
  /*jshint -W018 */

  var identity = function(param) {
    return param;
  };

  var noop = function() {
  };

  /**
   * Plugin name in jQuery cache data.
   * @type {string}
   * @const
   * @private
   */
  var PLUGIN_NAME = 'jqAutoComplete';

  /**
   * Enter Key Code.
   * @type {number}
   * @const
   * @private
   */
  var ENTER_KEY = 13;

  /**
   * Key associated to arrow down on keyboard.
   * @type {number}
   * @const
   * @private
   */
  var ARROW_DOWN = 40;

  /**
   * Key associated to arrow up on keyboard.
   * @type {number}
   * @const
   * @private
   */
  var ARROW_UP = 38;

  /**
   * Key associated to tab on keyboard.
   * @type {number}
   * @const
   * @private
   */
  var TAB = 9;

  /**
   * Css class use on list items.
   * @type {string}
   * @const
   * @private
   */
  var ITEM_CLASS = 'jq-autocomplete-item';

  /**
   * Css class use on active items.
   * @type {string}
   * @const
   * @private
   */
  var ACTIVE_CLASS = 'jq-autocomplete-item-active';

  /**
   * Css class use on result list.
   * @type {string}
   * @const
   * @private
   */
  var RESULT_CLASS = 'jq-autocomplete-results';

  /**
   * Get attribute value of object.
   * @param {object} obj Object to look for.
   * @param {string} key Name of attribute.
   * @returns {*} Value associated to key in object.
   * @private
   */
  var attr = function(obj, key) {
    if (!obj || !key) {
      return obj;
    }

    var subKeys = key.split('.');
    var current = obj;
    var ln = subKeys.length;
    for (var i = 0; i < (ln - 1); ++i) {
      current = current[subKeys[i]];
      if (current === null || current === undefined) {
        return '';
      }
    }

    return current[subKeys[ln - 1]];
  };

  var data = function($obj, data) {
    var value = $obj.attr('data-' + data);
    if (value === '') {
      value = undefined;
    }
    return value;
  };

  var AutoComplete = function(options, input) {
    this.$input = $(input);

    // Override options with data attributes
    this.opts = $.extend({}, options, this.readDatas());

    this.caches = {};
    this.filter = '';
    this.results = [];
    this.idx = -1;

    this.top = -1;
    this.left = -1;
    this.width = -1;

    this.timer = null;
    this.xhr = null;
  };

  AutoComplete.prototype = {
    /**
     * Initialize autocomplete.
     * @public
     */
    init: function() {
      this.$ul = $('

').addClass(RESULT_CLASS);

      var relativeTo = this.opts.relativeTo;
      var position = 'fixed';
      var isFixed = !!(relativeTo === 'fixed');

      if (!isFixed) {
        var $relativeTo = relativeTo ? $(relativeTo) : this.$input.parent();
        $relativeTo.css('position', 'relative');
        position = 'absolute';
      }

      this.position = position;
      this.fixed = isFixed;
      this.positionResult();

      this.$input.after(this.$ul);

      // Bind User-Events
      this.bind();
    },

    /**
     * Read data attributes used to initialize autocomplete.
     * @return {object} Initialization object initialized with data attributes.
     * @public
     */
    readDatas: function() {
      var datas = {};
      var $input = this.$input;
      datas.minSize = data($input, 'min-size');
      datas.limit = data($input, 'limit');
      datas.url = data($input, 'url');
      datas.method = data($input, 'method');
      datas.limitName = data($input, 'limit-name');
      datas.filterName = data($input, 'filter-name');
      datas.label = data($input, 'label');
      datas.cache = data($input, 'cache') || false;
      datas.relativeTo = data($input, 'relative-to');

      if (datas.minSize !== undefined) {
        datas.minSize = parseInt(datas.minSize, 10);
      }
      if (datas.limit !== undefined) {
        datas.limit = parseInt(datas.limit, 10);
      }
      if (typeof datas.cache === 'string') {
        datas.cache = !!(datas.cache === 'true');
      }

      return datas;
    },

    /**
     * Position result list in fixed position below input field.
     * @public
     */
    positionResult: function() {
      // Get Input Position
      var $input = this.$input;

      var position = this.fixed ? $input.offset() : $input.position();
      var width = $input.outerWidth();
      var height = $input.outerHeight();

      var left = position.left;
      var top = position.top + height;

      if (this.left !== left || this.top !== top || this.width !== width) {
        this.left = left;
        this.top = top;
        this.width = width;

        this.$ul.css({
          'position': this.position,
          'left': left,
          'top': top,
          'width': width
        });
      }
    },

    /**
     * Bind User-Events on autocomplete.
     * @public
     */
    bind: function() {
      var that = this;

      this.$input.on('keyup.jqauto', function(e) {
        var keyCode = e.keyCode;
        if (keyCode === ENTER_KEY) {
          // Enter key
          that.select(that.idx);
          $(this).focus();
        }
        else if (keyCode !== ARROW_DOWN && keyCode !== ARROW_UP) {
          var filter = $.trim($(this).val());
          if (filter.length >= that.opts.minSize) {
            that.fetch(filter);
          }
          else {
            that.filter = filter;
            that.$hide();
            that.clear();
          }
        }
      });

      this.$input.on('keydown.jqauto', function(e) {
        var keyCode = e.keyCode;
        if (keyCode === ARROW_DOWN) {
          e.preventDefault();
          e.stopPropagation();
          that.highlight(that.idx + 1);
        }
        else if (keyCode === ARROW_UP) {
          e.preventDefault();
          e.stopPropagation();
          that.highlight(that.idx - 1);
        }
        else if (keyCode === TAB) {
          that.select(that.idx);
        }
      });

      this.$input.on('focusout.jqauto', function() {
        that.focus = false;
        var $this = $(this);
        setTimeout(function() {
          if (!that.focus && that.$ul) {
            that.$hide();
            if (!that.item) {
              that.autoSelect($.trim($this.val()));
            }
          }
        }, 200);
      });

      this.$input.on('focusin.jqauto', function() {
        that.focus = true;
        if ((!that.item) && (that.results.length > 0)) {
          that.$show();
        }
      });

      this.$ul.on('mouseenter.jqauto', function() {
        $(this).find('li').removeClass(ACTIVE_CLASS);
      });

      this.$ul.on('click.jqauto', 'li', function() {
        that.select(parseInt($(this).attr('data-idx'), 10));
        that.$input.focus();
      });
    },

    /**
     * Check if item is set.
     * @returns {boolean} True if item is set, false otherwise.
     * @public
     */
    itemIsEmpty: function() {
      return this.item === undefined || this.item === null;
    },

    /**
     * Fetch results with given filter.
     * @param {string} filter Filter to fetch.
     * @public
     */
    fetch: function(filter) {
      if (this.filter === filter) {
        // If filter do not change, don't do anything
        if (this.itemIsEmpty()) {
          this.$show();
        }
        return;
      }

      if (!this.itemIsEmpty()) {
        this.opts.unSelect.call(this);
      }

      // Filter changed, unset item
      this.item = null;

      // Update filter
      this.filter = filter;

      // Abort current request if a request is pending
      if (this.xhr) {
        this.xhr.abort();
        this.xhr = null;
      }

      // Abort current timer
      if (this.timer) {
        clearTimeout(this.timer);
        this.timer = null;
      }

      var that = this;

      // Use a case-insensitive cache
      var key = filter.toLowerCase();

      if (this.opts.cache && this.caches[key]) {
        // Get from cache
        this.show(this.caches[key]);
      }
      else {
        var request = function() {
          // Build default parameters
          var params = {};

          params[that.opts.filterName] = that.filter;
          if (that.opts.limit > 0) {
            params[that.opts.limitName] = that.opts.limit;
          }

          // Append custom datas to parameters
          if (that.opts.datas) {
            if (typeof that.opts.datas === 'object') {
              params = $.extend(params, that.opts.datas);
            }
            else if (typeof that.opts.datas === 'function') {
              params = $.extend(params, that.opts.datas.apply(this));
            }
          }

          // Launch request
          that.xhr = $.ajax({
            url: that.opts.url,
            type: that.opts.method,
            dataType: 'json',
            data: params
          });

          that.xhr.done(function(datas) {
            that.timer = null;
            that.xhr = null;

            if (that.opts.cache) {
              // Store in cache
              that.caches[key] = datas;
            }

            that.show(datas);
          });
        };

        // Launch request in 200ms
        // If user type something else in the meantime, request will be aborted
        this.timer = setTimeout(request, 200);
      }
    },

    /**
     * Clear cache.
     * @public
     */
    clearCache: function() {
      this.caches = {};
    },

    /**
     * Show current datas in results list.
     * @param {Array<object>} datas New results to display.
     * @public
     */
    show: function(datas) {
      this.results = datas;

      if (datas.length === 0) {
        this.clear();
        return;
      }

      this.$hide().empty();

      for (var i = 0, ln = datas.length; i < ln; ++i) {
        var label = this.renderItem(datas[i]);
        $('
')
          .addClass(ITEM_CLASS)
          .attr('data-idx', i)
          .attr('title', label)
          .html(label)
          .appendTo(this.$ul);
      }

      this.$show();
    },

    /**
     * Show result list.
     * @returns {jQuery} Result list object.
     * @public
     */
    $show: function() {
      this.positionResult();
      return this.$ul.show();
    },

    /**
     * Hide result list.
     * @returns {jQuery} Result list object.
     * @public
     */
    $hide: function() {
      return this.$ul.hide();
    },

    /**
     * Set item as selected value.
     * @param {*} obj Object to select.
     * @public
     */
    setItem: function(obj) {
      this.item = obj;
      this.filter = this.renderItem(obj);
      this.$input.val(this.filter);
      this.$hide();
      this.idx = -1;
      this.opts.select.call(this, obj);
    },

    /**
     * Render an item.
     * @param {object|string|number} obj Object to render.
     * @returns {*} Result of render function.
     * @public
     */
    renderItem: function(obj) {
      var label = this.opts.label;
      var txt = $.isFunction(label) ? label.call(null, obj) : attr(obj, label);
      if (txt === undefined || txt === null) {
        txt = '';
      }
      return txt;
    },

    /**
     * Select item at given index (into results list).
     * @param {number} idx Index.
     * @public
     */
    select: function(idx) {
      if (idx >= 0 && idx < this.results.length) {
        this.setItem(this.results[idx]);
      }
    },

    /**
     * Auto Select a result in the list of results.

     * We search for the same filter (case insensitive) in the list of results.
     * @param {string} filter Current filter to search.
     * @public
     */
    autoSelect: function(filter) {
      var results = this.results;
      var f = filter.toLowerCase();

      for (var i = 0, ln = results.length; i < ln; ++i) {
        var label = this.renderItem(results[i]).toLowerCase();
        if (label === f) {
          this.select(i);
          return;
        }
      }
    },

    /**
     * Highlight item at given index.
     * @param {number} idx Index.
     * @public
     */
    highlight: function(idx) {
      var ln = this.results.length;
      if (!ln) {
        return;
      }

      if (idx < 0) {
        idx = ln - 1;
      }
      else if (idx >= ln) {
        idx = 0;
      }

      this.$ul.find('li')
        .removeClass(ACTIVE_CLASS)
        .eq(idx).addClass(ACTIVE_CLASS);

      this.idx = idx;
    },

    /**
     * Clear autocomplete :
     * - Clear and hide results.
     * - Reset variable storing results and current selected item.
     * @public
     */
    clear: function() {
      if (this.item !== undefined && this.item !== null) {
        this.opts.unSelect.call(this);
      }

      this.$ul.empty().hide();
      this.results = [];
      this.idx = -1;
      this.item = null;
    },

    /**
     * Clear autocomplete and set input to an empty string.
     * @public
     */
    empty: function() {
      this.clear();
      this.$input.val('');
    },

    /**
     * Unbind user events handlers.
     * @public
     */
    unbind: function() {
      this.$input.off('.jqauto');
      this.$ul.off('.jqauto');
    },

    /**
     * Destroy autocomplete component.
     * @public
     */
    destroy: function() {
      this.unbind();
      this.$ul.remove();

      if (this.timer) {
        clearTimeout(this.timer);
      }
      if (this.xhr) {
        this.xhr.abort();
      }

      for (var i in this) {
        if (this.hasOwnProperty(i)) {
          this[i] = null;
        }
      }
    }
  };

  $.fn.jqAutoComplete = function(options) {
    var that = this;

    this.destroy = function() {
      $(this).data(PLUGIN_NAME).destroy();
      return that;
    };

    this.clear = function() {
      $(this).data(PLUGIN_NAME).clear();
      return that;
    };

    this.empty = function() {
      $(this).data(PLUGIN_NAME).empty();
      return that;
    };

    this.item = function(obj) {
      var autocomplete = $(this).data(PLUGIN_NAME);
      if (obj) {
        autocomplete.setItem(obj);
        return that;
      }
      return autocomplete.item;
    };

    this.clearCache = function() {
      $(this).data(PLUGIN_NAME).clearCache();
      return that;
    };

    return this.each(function() {
      var autocomplete = $(this).data(PLUGIN_NAME);
      if (!autocomplete) {
        var opts = $.extend({}, $.fn.jqAutoComplete.options);
        if (typeof options === 'object') {
          opts = $.extend(opts, options);
        }
        autocomplete = new AutoComplete(opts, this);
        autocomplete.init();
      }
      $(this).data(PLUGIN_NAME, autocomplete);
    });
  };

  $.fn.jqAutoComplete.options = {
    url: '',
    label: identity,
    minSize: 3,
    method: 'GET',
    filterName: 'filter',
    limitName: 'limit',
    limit: 10,
    datas: null,
    cache: false,
    select: noop,
    unSelect: noop
  };

})(jQuery);
<|endoftext|>


<commit_before>wp.customize.controlConstructor['kirki-code'] = wp.customize.kirkiDynamicControl.extend({

	initKirkiControl: function() {

		var control  = this;

		// Early exit if wp.customize.CodeEditorControl is not available.
		if ( _.isUndefined( wp.customize.CodeEditorControl ) ) {
			return;
		}

		// Hide the textarea.
		jQuery( control.container.find( 'textarea.kirki-codemirror-editor' ) ).hide();

		// Add the control.
		wp.customize.control.add( new wp.customize.CodeEditorControl( control.id, {
			section: control.params.section,
			priority: control.params.priority,
			label: control.params.label,
			editor_settings: {
				codemirror: {
					mode: control.params.choices.language
				}
			},
			settings: { 'default': control.id }
		} ) );
	}
});
<commit_msg>fixes #1622<commit_after>wp.customize.controlConstructor['kirki-code'] = wp.customize.kirkiDynamicControl.extend({

	ready: function() {

		var control  = this;

		// Early exit if wp.customize.CodeEditorControl is not available.
		if ( _.isUndefined( wp.customize.CodeEditorControl ) ) {
			return;
		}

		// Hide the textarea.
		jQuery( control.container.find( 'textarea.kirki-codemirror-editor' ) ).hide();

		// Add the control.
		wp.customize.control.add( new wp.customize.CodeEditorControl( control.id, {
			section: control.params.section,
			priority: control.params.priority,
			label: control.params.label,
			editor_settings: {
				codemirror: {
					mode: control.params.choices.language
				}
			},
			settings: { 'default': control.id }
		} ) );
	}
});
<|endoftext|>


<commit_before>/*

            _/    _/_/    _/_/_/_/_/                              _/
               _/    _/      _/      _/_/    _/    _/    _/_/_/  _/_/_/
          _/  _/  _/_/      _/    _/    _/  _/    _/  _/        _/    _/
         _/  _/    _/      _/    _/    _/  _/    _/  _/        _/    _/
        _/    _/_/  _/    _/      _/_/      _/_/_/    _/_/_/  _/    _/
       _/
    _/

    Created by David Kaneda <http://www.davidkaneda.com>
    Maintained by Thomas Yip <http://beedesk.com/>
    Sponsored by Sencha Labs <http://www.sencha.com/>
    Special thanks to Jonathan Stark <http://www.jonathanstark.com/>

    Documentation and issue tracking on GitHub <http://github.com/senchalabs/jQTouch/>

    (c) 2009-2011 Sencha Labs
    jQTouch may be freely distributed under the MIT license.

*/

(function($){
  var touch = {}, touchTimeout;
  var jQT;
  var touchSelector = 'a, .touch';

  function parentIfText(node){
    return 'tagName' in node ? node : node.parentNode;
  }

  function swipeDirection(x1, x2, y1, y2){
    var xDelta = Math.abs(x1 - x2), yDelta = Math.abs(y1 - y2);
    if (xDelta >= yDelta) {
      return (x1 - x2 > 0 ? 'Left' : 'Right');
    } else {
      return (y1 - y2 > 0 ? 'Up' : 'Down');
    }
  }

  var longTapDelay = 750;
  function longTap(){
    if (touch.last && (Date.now() - touch.last >= longTapDelay)) {
      touch.el.trigger('longTap');
      touch = {};
    }
  }

  if ($.jQTouch) {
    $.jQTouch.addExtension(function GetInstance(jqt) {
      jQT = jqt;
      touchSelector = jQT.settings.touchSelector;
    });
  } else {
    console.warn('Error: jQTouch not found.');
  }

  $(document).ready(function(){
    var SUPPORT_TOUCH = (typeof Touch != "undefined");
    var START_EVENT = SUPPORT_TOUCH? 'touchstart' : 'mousedown';
    var MOVE_EVENT = SUPPORT_TOUCH? 'touchmove' : 'mousemove';
    var END_EVENT = SUPPORT_TOUCH? 'touchend' : 'mouseup';
    var CANCEL_EVENT = SUPPORT_TOUCH? 'touchcancel' : 'mouseout'; // mouseout on document

    function isRightClick(e) {
      var rightclick = false;

      if (!SUPPORT_TOUCH) {
        // http://www.quirksmode.org/js/events_properties.html
        if (!e) var e = window.event;
        if (e.which) rightclick = (e.which == 3);
        else if (e.button) rightclick = (e.button == 2);
      }
      return rightclick;
    }

    function touchstartHandler(e) {
      console.warn('touch started');
      try {
      var $oel, $el, $marked;
      var elX, elY;

      if (isRightClick(e)) {
        return;
      }

      $oel = $(e.target);
      $el = $oel;
      elStartY = $el.offset().top;
      elStartX = $el.offset().left;

      var hovertimeout = null;
      var presstimeout = null;
      var startX, startY, startTime;
      var deltaX, deltaY, deltaT;
      var endX, endY, endTime;
      var swipped = false, tapped = false, moved = false, inprogress = false, pressed = false;

      function bindEvents($el) {
          $el.bind(MOVE_EVENT, handlemove).bind(END_EVENT, handleend);
          if ($.support.touch) {
              $el.bind(CANCEL_EVENT, handlecancel);
          } else {
              $(document).bind('mouseout', handleend);
          }
      }

      function unbindEvents($el) {
          $el.unbind(MOVE_EVENT, handlemove).unbind(END_EVENT, handleend);
          if ($.support.touch) {
              $el.unbind(CANCEL_EVENT, handlecancel);
          } else {
              $(document).unbind('mouseout', handlecancel);
          }
      }

      function updateChanges(e) {
          var point = e.originalEvent;
          var first = $.support.touch? point.changedTouches[0]: point;
          deltaX = first.pageX - startX;
          deltaY = first.pageY - startY;
          deltaT = (new Date).getTime() - startTime;
          var absElOffset = $el.offset();
          elX = absElOffset.left - elStartX;
          elY = absElOffset.top - elStartY;
      }

      function handlestart(e) {
          var point;

          inprogress = true, swipped = false, tapped = false,
          moved = false, timed = false, pressed = false;
          point = e.originalEvent;
          startX = $.support.touch? point.changedTouches[0].pageX: point.pageX;
          startY = $.support.touch? point.changedTouches[0].pageY: point.pageY;
          startTime = (new Date).getTime();
          endX = null, endY = null, endTime = null;
          deltaX = 0;
          deltaY = 0;
          deltaT = 0;

          // Let's bind these after the fact, so we can keep some internal values
          bindEvents($el);

          setTimeout(function() {
              $marked = $el;
              var mySelectors = touchSelector;
              while ($marked.parent().is(mySelectors)) {
                $marked = $marked.parent();
              }

              handlehover();
          }, 50);

          setTimeout(function() {
              $el.trigger("touch");
          }, 50);

          setTimeout(function() {
            handlepress(e);
          }, 1000);
      };

      function handlemove(e) {
          updateChanges(e);

          if (!inprogress)
            return;

          var absX = Math.abs(deltaX);
          var absY = Math.abs(deltaY);

          if (absX > 1 || absY > 1) {
              moved = true;
          }
          if (absY <= 5 && elX === 0 && elY === 0) {
              if (absX > (3 * absY) && (absX > 10) && deltaT < 1000) {
                  inprogress = false;
                  if ($marked) $marked.removeClass('active');
                  unbindEvents($el);

                  swipped = true;
                  $el.trigger('swipe', {direction: (deltaX < 0) ? 'left' : 'right', deltaX: deltaX, deltaY: deltaY });
              } else if (absY > (3 * absX) && (absY > 10) && deltaT < 1000) {
                  inprogress = false;
                  if ($marked) $marked.removeClass('active');
                  unbindEvents($el);

                  swipped = true;
                  $el.trigger('swipe', {direction: (deltaY < 0) ? 'up' : 'down', deltaX: deltaX, deltaY: deltaY });
              }
          } else {
              // moved too much, can't swipe anymore
              inprogress = false;
              if ($marked) $marked.removeClass('active');
              unbindEvents($el);
          }
      };

      function handleend(e) {
          updateChanges(e);
          var absX = Math.abs(deltaX);
          var absY = Math.abs(deltaY);

          inprogress = false;
          unbindEvents($el);
          if (!tapped && (absX <= 1 && absY <= 1) && (elX === 0 && elY === 0)) {
              tapped = true;
              $oel.trigger('tap');
              setTimeout(function() {
                if ($marked) $marked.removeClass('active');
            }, 1000);
          } else {
              if ($marked) $marked.removeClass('active');
              //e.preventDefault();
          }
      };

      function handlecancel(e) {
          inprogress = false;
          if ($marked) $marked.removeClass('active');
          unbindEvents();
      };

      function handlehover() {
          timed = true;
          if (tapped) {
              // flash the selection
              $marked.addClass('active');
              hovertimeout = setTimeout(function() {
                  $marked.removeClass('active');
              }, 1000);
          } else if (inprogress && !moved) {
              $marked.addClass('active');
          }
      };

      function handlepress(e) {
        if (inprogress && !tapped && !moved) {
          pressed = true;
          tapped = true;
          $el.trigger('press');
        }
      }

      handlestart(e);
      } catch (e) {
        console.error('tap error: ' + e);
      }

    }; // End touch handler

    $(document.body).bind('touchstart', touchstartHandler);
  });

  ['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(m){
    $.fn[m] = function(callback){ return this.bind(m, callback) }
  });
})($);
<commit_msg>Don't recycle vars<commit_after>/*

            _/    _/_/    _/_/_/_/_/                              _/
               _/    _/      _/      _/_/    _/    _/    _/_/_/  _/_/_/
          _/  _/  _/_/      _/    _/    _/  _/    _/  _/        _/    _/
         _/  _/    _/      _/    _/    _/  _/    _/  _/        _/    _/
        _/    _/_/  _/    _/      _/_/      _/_/_/    _/_/_/  _/    _/
       _/
    _/

    Created by David Kaneda <http://www.davidkaneda.com>
    Maintained by Thomas Yip <http://beedesk.com/>
    Sponsored by Sencha Labs <http://www.sencha.com/>
    Special thanks to Jonathan Stark <http://www.jonathanstark.com/>

    Documentation and issue tracking on GitHub <http://github.com/senchalabs/jQTouch/>

    (c) 2009-2011 Sencha Labs
    jQTouch may be freely distributed under the MIT license.

*/

(function($){
  var touch = {}, touchTimeout;
  var jQT;
  var touchSelector = 'a, .touch';

  function parentIfText(node){
    return 'tagName' in node ? node : node.parentNode;
  }

  function swipeDirection(x1, x2, y1, y2){
    var xDelta = Math.abs(x1 - x2), yDelta = Math.abs(y1 - y2);
    if (xDelta >= yDelta) {
      return (x1 - x2 > 0 ? 'Left' : 'Right');
    } else {
      return (y1 - y2 > 0 ? 'Up' : 'Down');
    }
  }

  var longTapDelay = 750;
  function longTap(){
    if (touch.last && (Date.now() - touch.last >= longTapDelay)) {
      touch.el.trigger('longTap');
      touch = {};
    }
  }

  if ($.jQTouch) {
    $.jQTouch.addExtension(function GetInstance(jqt) {
      jQT = jqt;
      touchSelector = jQT.settings.touchSelector;
    });
  } else {
    console.warn('Error: jQTouch not found.');
  }

  $(document).ready(function(){
    var SUPPORT_TOUCH = (typeof Touch != "undefined");
    var START_EVENT = SUPPORT_TOUCH? 'touchstart' : 'mousedown';
    var MOVE_EVENT = SUPPORT_TOUCH? 'touchmove' : 'mousemove';
    var END_EVENT = SUPPORT_TOUCH? 'touchend' : 'mouseup';
    var CANCEL_EVENT = SUPPORT_TOUCH? 'touchcancel' : 'mouseout'; // mouseout on document

    function isRightClick(e) {
      var rightclick = false;

      if (!SUPPORT_TOUCH) {
        // http://www.quirksmode.org/js/events_properties.html
        if (!e) var e = window.event;
        if (e.which) rightclick = (e.which == 3);
        else if (e.button) rightclick = (e.button == 2);
      }
      return rightclick;
    }

    function touchstartHandler(e) {
      console.warn('touch started');
      try {
      var $oel, $el, $marked;
      var elX, elY;

      if (isRightClick(e)) {
        return;
      }

      $oel = $(e.target);
      $el = $oel;
      elStartY = $el.offset().top;
      elStartX = $el.offset().left;

      var hovertimeout = null;
      var presstimeout = null;
      var startX, startY, startTime;
      var deltaX, deltaY, deltaT;
      var endX, endY, endTime;
      var swipped = false, tapped = false, moved = false, inprogress = false, pressed = false;

      function bindEvents($el) {
          $el.bind(MOVE_EVENT, handlemove).bind(END_EVENT, handleend);
          if ($.support.touch) {
              $el.bind(CANCEL_EVENT, handlecancel);
          } else {
              $(document).bind('mouseout', handleend);
          }
      }

      function unbindEvents($el) {
          $el.unbind(MOVE_EVENT, handlemove).unbind(END_EVENT, handleend);
          if ($.support.touch) {
              $el.unbind(CANCEL_EVENT, handlecancel);
          } else {
              $(document).unbind('mouseout', handlecancel);
          }
      }

      function updateChanges(e) {
          var point = e.originalEvent;
          var first = $.support.touch? point.changedTouches[0]: point;
          deltaX = first.pageX - startX;
          deltaY = first.pageY - startY;
          deltaT = (new Date).getTime() - startTime;
          var absElOffset = $el.offset();
          elX = absElOffset.left - elStartX;
          elY = absElOffset.top - elStartY;
      }

      function handlestart(e) {
          var point;

          inprogress = true, swipped = false, tapped = false,
          moved = false, timed = false, pressed = false;
          point = e.originalEvent;
          startX = $.support.touch? point.changedTouches[0].pageX: point.pageX;
          startY = $.support.touch? point.changedTouches[0].pageY: point.pageY;
          startTime = (new Date).getTime();
          endX = null, endY = null, endTime = null;
          deltaX = 0;
          deltaY = 0;
          deltaT = 0;

          // Let's bind these after the fact, so we can keep some internal values
          bindEvents($el);

          setTimeout(function() {
              $marked = $el;
              var mySelectors = touchSelector;
              while ($marked.parent().is(mySelectors)) {
                $marked = $marked.parent();
              }

              handlehover();
          }, 50);

          setTimeout(function() {
              $el.trigger("touch");
          }, 50);

          setTimeout(function() {
            handlepress(e);
          }, 1000);
      };

      function handlemove(e) {
          updateChanges(e);

          if (!inprogress)
            return;

          var absX = Math.abs(deltaX);
          var absY = Math.abs(deltaY);

          if (absX > 1 || absY > 1) {
              moved = true;
          }
          if (absY <= 5 && elX === 0 && elY === 0) {
              if (absX > (3 * absY) && (absX > 10) && deltaT < 1000) {
                  inprogress = false;
                  if ($marked) $marked.removeClass('active');
                  unbindEvents($el);

                  swipped = true;
                  $el.trigger('swipe', {direction: (deltaX < 0) ? 'left' : 'right', deltaX: deltaX, deltaY: deltaY });
              } else if (absY > (3 * absX) && (absY > 10) && deltaT < 1000) {
                  inprogress = false;
                  if ($marked) $marked.removeClass('active');
                  unbindEvents($el);

                  swipped = true;
                  $el.trigger('swipe', {direction: (deltaY < 0) ? 'up' : 'down', deltaX: deltaX, deltaY: deltaY });
              }
          } else {
              // moved too much, can't swipe anymore
              inprogress = false;
              if ($marked) $marked.removeClass('active');
              unbindEvents($el);
          }
      };

      function handleend(e) {
          updateChanges(e);
          var absX = Math.abs(deltaX);
          var absY = Math.abs(deltaY);

          inprogress = false;
          unbindEvents($el);
          if (!tapped && (absX <= 1 && absY <= 1) && (elX === 0 && elY === 0)) {
              tapped = true;
              $oel.trigger('tap');
              setTimeout(function() {
                if ($marked) $marked.removeClass('active');
            }, 1000);
          } else {
              if ($marked) $marked.removeClass('active');
              //e.preventDefault();
          }
      };

      function handlecancel(e) {
          inprogress = false;
          if ($marked) $marked.removeClass('active');
          unbindEvents();
      };

      function handlehover() {
          timed = true;
          if (tapped) {
              // flash the selection
              $marked.addClass('active');
              hovertimeout = setTimeout(function() {
                  $marked.removeClass('active');
              }, 1000);
          } else if (inprogress && !moved) {
              $marked.addClass('active');
          }
      };

      function handlepress(e) {
        if (inprogress && !tapped && !moved) {
          pressed = true;
          tapped = true;
          $el.trigger('press');
        }
      }

      handlestart(e);
      } catch (err) {
        console.error('tap error: ' + err);
      }

    } // End touch handler

    $(document.body).bind('touchstart', touchstartHandler);
  });

  ['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(m){
    $.fn[m] = function(callback){ return this.bind(m, callback) }
  });
})($);
<|endoftext|>


<commit_before>wp.customize.controlConstructor['kirki-code'] = wp.customize.kirkiDynamicControl.extend({

	ready: function() {

		var control  = this;

		// Early exit if wp.customize.CodeEditorControl is not available.
		if ( _.isUndefined( wp.customize.CodeEditorControl ) ) {
			return;
		}

		// Hide the textarea.
		jQuery( control.container.find( 'textarea.kirki-codemirror-editor' ) ).hide();

		// Add the control.
		wp.customize.control.add( new wp.customize.CodeEditorControl( control.id, {
			section: control.params.section,
			priority: control.params.priority,
			label: control.params.label,
			editor_settings: {
				codemirror: {
					mode: control.params.choices.language
				}
			},
			settings: { 'default': control.id }
		} ) );
	}
});
<commit_msg>Revert "fixes #1622"<commit_after>wp.customize.controlConstructor['kirki-code'] = wp.customize.kirkiDynamicControl.extend({

	initKirkiControl: function() {

		var control  = this;

		// Early exit if wp.customize.CodeEditorControl is not available.
		if ( _.isUndefined( wp.customize.CodeEditorControl ) ) {
			return;
		}

		// Hide the textarea.
		jQuery( control.container.find( 'textarea.kirki-codemirror-editor' ) ).hide();

		// Add the control.
		wp.customize.control.add( new wp.customize.CodeEditorControl( control.id, {
			section: control.params.section,
			priority: control.params.priority,
			label: control.params.label,
			editor_settings: {
				codemirror: {
					mode: control.params.choices.language
				}
			},
			settings: { 'default': control.id }
		} ) );
	}
});
<|endoftext|>


<commit_before>if (typeof process === 'object') {
  // Initialize node environment
  global.chai = require('chai');
  global.expect = require('chai').expect;
  require('mocha-jsdom')();
} else {
  window.expect = window.chai.expect
  window.require = function () { /* noop */ }
}
<commit_msg>semicolons are my friend<commit_after>if (typeof process === 'object') {
  // Initialize node environment
  global.chai = require('chai');
  global.expect = require('chai').expect;
  require('mocha-jsdom')();
} else {
  window.expect = window.chai.expect;
  window.require = function () { /* noop */ };
}
<|endoftext|>


<commit_before>/*
 *  jQuery HelyeNav plugin
 *  ======================
 *
 *  @desc HelyeNav is a simple on level Accordion vertical menu.
 *        It's fully accessible, non obstrusive, and uses a cookie to
 *        remember the current opened menu through pages.
 *
 *
 *  @require jQuery 1.3.x
 *  @require [jQuery Cookie Plugin](http://dev.jquery.com/browser/trunk/plugins/cookie/)
 *
 *  -- License --
 *  Copyright (c) 2009 Fabrice Luraine
 *  Published under [MIT license](http://www.opensource.org/licenses/mit-license.php)
 *  --
 *
 */

(function($) {
    // PLUGIN DEFINITION
    $.fn.helyenav = function(options) {
        // init plugin and build options before elemnts iteration
        var opts = $.extend({}, $.fn.helyenav.defaults, options);
        $.helyenav.opts = opts;
        $.helyenav.current = opts.current;

        return this.each(function() {
            // execute plugin on each elt
            $.helyenav.init(this, opts);
            $(this).click(onClick);
        });

        // private
        function onClick() {
            return $.cookie(opts.cookieName, $.helyenav.current(), { path: opts.cookiePath});
        }
    };

    $.helyenav = {
        init: function(container, opts) {
            var current = $.helyenav.current();
            this.container = container;
            var subnavs = $(container).find(opts.childBlockElt);
            var subnavsNames = $.map(subnavs, function(el) {
                return $(el).parent().attr('class');
            });
            $(subnavs).hide();
            if($.cookie(opts.cookieName) == current){
                subnav(current).show();
            } else {
              $.each(subnavsNames, function(i, name){
                 if($.cookie(opts.cookieName)==name){
                       subnav(name).show();
                       subnav(name).slideUp(opts.speed);
                    }
                    if(current==name){
                       subnav(name).slideDown(opts.speed);
                    }
              });
           }

           // private
           function subnav(name){
               return $(this.container).find("." + name + ' > ' + $.helyenav.opts.childBlockElt);
           }
        }
    };

    // PLUGIN DEFAULTS
    $.fn.helyenav.defaults = {
        current: function(){ return $('body').attr('class'); },
        speed: 'slow',
        cookieName: 'last',
        cookiePath: '/',
        childBlockElt: 'ul'
    };

})(jQuery);<commit_msg>Little fix for Firefox 2.x<commit_after>/*
 *  jQuery HelyeNav plugin
 *  ======================
 *
 *  @desc HelyeNav is a simple on level Accordion vertical menu.
 *        It's fully accessible, non obstrusive, and uses a cookie to
 *        remember the current opened menu through pages.
 *
 *
 *  @require jQuery 1.3.x
 *  @require [jQuery Cookie Plugin](http://dev.jquery.com/browser/trunk/plugins/cookie/)
 *
 *  -- License --
 *  Copyright (c) 2009 Fabrice Luraine
 *  Published under [MIT license](http://www.opensource.org/licenses/mit-license.php)
 *  --
 *
 */

(function($) {
    // PLUGIN DEFINITION
    $.fn.helyenav = function(options) {
        // init plugin and build options before elemnts iteration
        var opts = $.extend({}, $.fn.helyenav.defaults, options);
        $.helyenav.opts = opts;
        $.helyenav.current = opts.current;

        return this.each(function() {
            // execute plugin on each elt
            $.helyenav.init(this, opts);
            $(this).click(onClick);
        });

        // private
        function onClick() {
            return $.cookie(opts.cookieName, $.helyenav.current(), { path: opts.cookiePath});
        }
    };

    $.helyenav = {
        init: function(container, opts) {
            var current = $.helyenav.current();
            this.container = container;
            var subnavs = $(container).find(opts.childBlockElt);
            var subnavsNames = $.map(subnavs, function(el) {
                return $(el).parent().attr('class');
            });
            $(subnavs).hide();
            if($.cookie(opts.cookieName) == current){
                subnav(current).show();
            } else {
              $.each(subnavsNames, function(i, name){
                 if($.cookie(opts.cookieName)==name){
                       subnav(name).show();
                       subnav(name).css('display', 'block'); /* for FF2, in case it's inline */
                       subnav(name).slideUp(opts.speed);
                    }
                    if(current==name){
                       subnav(name).slideDown(opts.speed);
                    }
              });
           }

           // private
           function subnav(name){
               return $(this.container).find("." + name + ' > ' + $.helyenav.opts.childBlockElt);
           }
        }
    };

    // PLUGIN DEFAULTS
    $.fn.helyenav.defaults = {
        current: function(){ return $('body').attr('class'); },
        speed: 'slow',
        cookieName: 'last',
        cookiePath: '/',
        childBlockElt: 'ul'
    };

})(jQuery);<|endoftext|>


<commit_before>(function($) {
    $.fn.seSlider = function(options) {
        var defaults = {
            nextBtn: '.sliderNextBtn',
            prevBtn: '.sliderPrevBtn',
            playPauseBtn: '.sliderPlayBtn',
            resetBtn: '.sliderResetBtn',
            preventReversedCycle: false,
            progressBar: null,
            changeCallback: null,
            afterChangeCallback: null,
            playCallback: null,
            pauseCallback: null,
            endCallback: null,
            resetCallback: null,
            autoPlay: false,
            slideshowSoundTrack: null,
            slideshowSteps: null,
            slideshowIntervalTime: 1000,
            transitionSpeed: 200
        };
        var params = $.extend(defaults, options),
            changeCallbacks = $.Callbacks(),
            afterChangeCallbacks = $.Callbacks();

        if(typeof params.changeCallback === 'function')
            changeCallbacks.add(params.changeCallback);

        if(typeof params.afterChangeCallback === 'function')
            afterChangeCallbacks.add(params.afterChangeCallback);

        function moveLeft(slider, slideshow) {
            if(params.preventReversedCycle === true && slideshow.currStep <= 0)
                return;

            changeCallbacks.fire(slideshow.currStep, slideshow.currStep - 1, 'left');

            slider.animate({
                left: + slider.children('li').width()
            }, params.transitionSpeed, function() {
                slideshow.currStep--;
                slider.find('li').last().prependTo(slider);
                slider.css('left', '');

                if(slideshow.currStep < 0)
                {
                    if(slideshow.interval !== false)
                        stopSlideShow(slider, slideshow, true, false);

                    slideshow.currStep = slideshow.maxStep;
                }

                afterChangeCallbacks.fire(slideshow.currStep);
                updateElapsedTime(slideshow);
                updateProgressBar(slideshow.elapsedTime / slideshow.maxTime * 100);
                updateSoundTrackTime(slideshow.elapsedTime / 1000);
            });
        }

        function moveRight(slider, slideshow, updateComponents) {
            changeCallbacks.fire(slideshow.currStep, slideshow.currStep + 1, 'right');

            slider.animate({
                left: - slider.children('li').width()
            }, params.transitionSpeed, function() {
                slideshow.currStep++;
                slider.find('li').first().appendTo(slider);
                slider.css('left', '');

                if(slideshow.currStep > slideshow.maxStep)
                {
                    slideshow.currStep = 0;
                    if(slideshow.interval !== false)
                    {
                        stopSlideShow(slider, slideshow, true, false);
                        updateComponents = false;
                    }
                }

                afterChangeCallbacks.fire(slideshow.currStep);
                if(updateComponents === true)
                {
                    updateElapsedTime(slideshow);
                    updateProgressBar(slideshow.elapsedTime / slideshow.maxTime * 100);
                    updateSoundTrackTime(slideshow.elapsedTime / 1000);
                }
            });
        }

        function playSlideShow(slider, slideshow)
        {
            slideshow.interval = setInterval(function() {
                slideshow.elapsedTime += params.slideshowIntervalTime;
                updateProgressBar(slideshow.elapsedTime / slideshow.maxTime * 100);

                if(params.slideshowSteps === null || params.slideshowSteps[slideshow.currStep] <= slideshow.elapsedTime)
                    moveRight(slider, slideshow, false);
            }, params.slideshowIntervalTime);

            if(params.slideshowSoundTrack !== null)
                $(params.slideshowSoundTrack).get(0).play();

            if(typeof params.playCallback === 'function')
                params.playCallback();
        }

        function stopSlideShow(slider, slideshow, endReached, reset)
        {
            if(slideshow.interval !== false)
            {
                clearInterval(slideshow.interval);
                slideshow.interval = false;

                if(params.slideshowSoundTrack !== null)
                    $(params.slideshowSoundTrack).get(0).pause();
            }

            if(endReached === true || reset === true)
            {
                slider.finish();
                if(reset === true && slideshow.currStep !== 0)
                    slider.find('li').slice((slideshow.maxStep + 1) - slideshow.currStep).prependTo(slider);

                slideshow.currStep = 0;
                slideshow.elapsedTime = 0;
                updateProgressBar(0);
                updateSoundTrackTime(0);

                if(endReached === true && typeof params.endCallback === 'function')
                    params.endCallback();
                else if(reset === true && typeof params.resetCallback === 'function')
                    params.resetCallback();
            }
            else if(typeof params.pauseCallback === 'function')
                params.pauseCallback();
        }

        function updateElapsedTime(slideshow)
        {
            if(params.slideshowSteps === null)
                slideshow.elapsedTime = params.slideshowIntervalTime * slideshow.currStep;
            else
                slideshow.elapsedTime = params.slideshowSteps[slideshow.currStep - 1] || 0;
        }

        function updateProgressBar(size)
        {
            if(params.progressBar !== null)
                $(params.progressBar).children('div').css('width', size + '%');
        }

        function updateSoundTrackTime(time)
        {
            if(params.slideshowSoundTrack !== null)
                $(params.slideshowSoundTrack).get(0).currentTime = time;
        }

        return this.each(function() {
            var obj = $(this).children('ul');
            var slideWidth = obj.children('li').width(),
                slideshow = {
                interval: false,
                maxStep: obj.children('li').length - 1,
                currStep: 0,
                elapsedTime: 0
            };

            if(params.slideshowSteps !== null && params.slideshowSteps.length != slideshow.maxStep + 1)
                throw new TypeError('The slideshowSteps parameter must have a length equal to the number of li tags in the slider.');

            slideshow.maxTime = params.slideshowSteps === null ? params.slideshowIntervalTime * (slideshow.maxStep + 1) : params.slideshowSteps[slideshow.maxStep];

            if(obj.children('li').length === 1)
                return true;

            obj.children('li').last().prependTo(obj);
            if(obj.children('li').length === 2)
            {
                var first = obj.children('li').first().clone(),
                    last = obj.children('li').last().clone();
                obj.append(first).append(last);
            }

            obj.css({width: slideWidth * (slideshow.maxStep + 1), marginLeft: - slideWidth});

            if(params.autoPlay === true)
                playSlideShow(obj, slideshow);

            //Next button
            $(params.nextBtn).on('touchstart click', function(e) {
                e.preventDefault();
                if(obj.css('left') !== 'auto')
                    return;

                moveRight(obj, slideshow, true);
            });

            //Prev button
            $(params.prevBtn).on('touchstart click', function(e) {
                e.preventDefault();
                if(obj.css('left') !== 'auto')
                    return;

                moveLeft(obj, slideshow);
            });

            //Reset button
            $(params.resetBtn).on('touchstart click', function(e) {
                e.preventDefault();
                stopSlideShow(obj, slideshow, false, true);
            });

            //SlideShow play
            $(params.playPauseBtn).on('touchstart click', function(e) {
                e.preventDefault();
                if(slideshow.interval === false)
                    playSlideShow(obj, slideshow);
                else
                    stopSlideShow(obj, slideshow, false, false);
            });
        });
    };
})(jQuery);
<commit_msg>Optimize code<commit_after>(function($) {
    $.fn.seSlider = function(options) {
        var defaults = {
            nextBtn: '.sliderNextBtn',
            prevBtn: '.sliderPrevBtn',
            playPauseBtn: '.sliderPlayBtn',
            resetBtn: '.sliderResetBtn',
            preventReversedCycle: false,
            progressBar: null,
            changeCallback: null,
            afterChangeCallback: null,
            playCallback: null,
            pauseCallback: null,
            endCallback: null,
            resetCallback: null,
            autoPlay: false,
            slideshowSoundTrack: null,
            slideshowSteps: null,
            slideshowIntervalTime: 1000,
            transitionSpeed: 200
        };
        var params = $.extend(defaults, options),
            changeCallbacks = $.Callbacks(),
            afterChangeCallbacks = $.Callbacks();

        if(typeof params.changeCallback === 'function')
            changeCallbacks.add(params.changeCallback);

        if(typeof params.afterChangeCallback === 'function')
            afterChangeCallbacks.add(params.afterChangeCallback);

        function moveLeft(slider, slideshow) {
            if(params.preventReversedCycle === true && slideshow.currStep <= 0)
                return;

            changeCallbacks.fire(slideshow.currStep, slideshow.currStep - 1, 'left');

            slider.animate({
                left: + slider.children('li').width()
            }, params.transitionSpeed, function() {
                slideshow.currStep--;
                slider.find('li').last().prependTo(slider);
                slider.css('left', '');

                if(slideshow.currStep < 0)
                {
                    if(slideshow.interval !== false)
                        stopSlideShow(slider, slideshow, true, false);

                    slideshow.currStep = slideshow.maxStep;
                }

                afterChangeCallbacks.fire(slideshow.currStep);
                updateElapsedTime(slideshow);
                updateProgressBar(slideshow.elapsedTime / slideshow.maxTime * 100);
                updateSoundTrackTime(slideshow.elapsedTime / 1000);
            });
        }

        function moveRight(slider, slideshow, updateComponents) {
            changeCallbacks.fire(slideshow.currStep, slideshow.currStep + 1, 'right');

            slider.animate({
                left: - slider.children('li').width()
            }, params.transitionSpeed, function() {
                slideshow.currStep++;
                slider.find('li').first().appendTo(slider);
                slider.css('left', '');

                if(slideshow.currStep > slideshow.maxStep)
                {
                    slideshow.currStep = 0;
                    if(slideshow.interval !== false)
                    {
                        stopSlideShow(slider, slideshow, true, false);
                        updateComponents = false;
                    }
                }

                afterChangeCallbacks.fire(slideshow.currStep);
                if(updateComponents === true)
                {
                    updateElapsedTime(slideshow);
                    updateProgressBar(slideshow.elapsedTime / slideshow.maxTime * 100);
                    updateSoundTrackTime(slideshow.elapsedTime / 1000);
                }
            });
        }

        function playSlideShow(slider, slideshow)
        {
            slideshow.interval = setInterval(function() {
                slideshow.elapsedTime += params.slideshowIntervalTime;
                updateProgressBar(slideshow.elapsedTime / slideshow.maxTime * 100);

                if(params.slideshowSteps === null || params.slideshowSteps[slideshow.currStep] <= slideshow.elapsedTime)
                    moveRight(slider, slideshow, false);
            }, params.slideshowIntervalTime);

            if(params.slideshowSoundTrack !== null)
                $(params.slideshowSoundTrack).get(0).play();

            if(typeof params.playCallback === 'function')
                params.playCallback();
        }

        function stopSlideShow(slider, slideshow, endReached, reset)
        {
            if(slideshow.interval !== false)
            {
                clearInterval(slideshow.interval);
                slideshow.interval = false;

                if(params.slideshowSoundTrack !== null)
                    $(params.slideshowSoundTrack).get(0).pause();
            }

            if(endReached === true || reset === true)
            {
                slider.finish();
                if(reset === true && slideshow.currStep !== 0)
                    slider.find('li').slice((slideshow.maxStep + 1) - slideshow.currStep).prependTo(slider);

                slideshow.currStep = 0;
                slideshow.elapsedTime = 0;
                updateProgressBar(0);
                updateSoundTrackTime(0);

                if(endReached === true && typeof params.endCallback === 'function')
                    params.endCallback();
                else if(reset === true && typeof params.resetCallback === 'function')
                    params.resetCallback();
            }
            else if(typeof params.pauseCallback === 'function')
                params.pauseCallback();
        }

        function updateElapsedTime(slideshow)
        {
            if(params.slideshowSteps === null)
                slideshow.elapsedTime = params.slideshowIntervalTime * slideshow.currStep;
            else
                slideshow.elapsedTime = params.slideshowSteps[slideshow.currStep - 1] || 0;
        }

        function updateProgressBar(size)
        {
            if(params.progressBar !== null)
                $(params.progressBar).children('div').css('width', size + '%');
        }

        function updateSoundTrackTime(time)
        {
            if(params.slideshowSoundTrack !== null)
                $(params.slideshowSoundTrack).get(0).currentTime = time;
        }

        return this.each(function() {
            var obj = $(this).children('ul');
            var slideWidth = obj.children('li').width(),
                slideshow = {
                interval: false,
                maxStep: obj.children('li').length - 1,
                currStep: 0,
                elapsedTime: 0
            };

            if(slideshow.maxStep < 1)
                return true;

            if(params.slideshowSteps !== null && params.slideshowSteps.length != slideshow.maxStep + 1)
                throw new TypeError('The slideshowSteps parameter must have a length equal to the number of li tags in the slider.');

            slideshow.maxTime = params.slideshowSteps === null ? params.slideshowIntervalTime * (slideshow.maxStep + 1) : params.slideshowSteps[slideshow.maxStep];

            obj.children('li').last().prependTo(obj);
            if(obj.children('li').length === 2)
            {
                var first = obj.children('li').first().clone(),
                    last = obj.children('li').last().clone();
                obj.append(first).append(last);
            }

            obj.css({width: slideWidth * (slideshow.maxStep + 1), marginLeft: - slideWidth});

            if(params.autoPlay === true)
                playSlideShow(obj, slideshow);

            //Next button
            $(params.nextBtn).on('touchstart click', function(e) {
                e.preventDefault();
                if(obj.css('left') !== 'auto')
                    return;

                moveRight(obj, slideshow, true);
            });

            //Prev button
            $(params.prevBtn).on('touchstart click', function(e) {
                e.preventDefault();
                if(obj.css('left') !== 'auto')
                    return;

                moveLeft(obj, slideshow);
            });

            //Reset button
            $(params.resetBtn).on('touchstart click', function(e) {
                e.preventDefault();
                stopSlideShow(obj, slideshow, false, true);
            });

            //SlideShow play
            $(params.playPauseBtn).on('touchstart click', function(e) {
                e.preventDefault();
                if(slideshow.interval === false)
                    playSlideShow(obj, slideshow);
                else
                    stopSlideShow(obj, slideshow, false, false);
            });
        });
    };
})(jQuery);
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 Adobe Systems Incorporated. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

define(function (require, exports) {
    "use strict";

    var os = require("adapter/os");

    /**
     * Native menu command IDs for Photoshop edit commands.
     *
     * @const
     * @private
     * @type {number}
     */
    var CUT_NATIVE_MENU_COMMMAND_ID = 103,
        COPY_NATIVE_MENU_COMMMAND_ID = 104,
        PASTE_NATIVE_MENU_COMMMAND_ID = 105;

    /**
     * Determines whether the given element is an HTML input element.
     *
     * @private
     * @param {HTMLElement} el
     * @return boolean
     */
    var _isInput = function (el) {
        return el instanceof window.HTMLInputElement;
    };

    /**
     * Determines whether the given input element is a textual element.
     *
     * @private
     * @param {HTMLInputElement} el
     * @return boolean
     */
    var _isTextInput = function (el) {
        switch (el.type) {
            case "text":
            case "search":
            case "url":
            case "tel":
            case "password":
                return true;
            default:
                return false;
        }
    };

    /**
     * Execute either a cut or copy operation, depending on the value of the parameter.
     *
     * @private
     * @param {boolean} cut If true, perform a cut operation; otherwise, a copy.
     * @return {Promise}
     */
    var _cutOrCopyCommand = function (cut) {
        return os.hasKeyboardFocus()
            .bind(this)
            .then(function (cefHasFocus) {
                var el = document.activeElement;
                if (cefHasFocus && _isInput(el)) {
                    var data;
                    if (_isTextInput(el)) {
                        data = el.value.substring(el.selectionStart, el.selectionEnd);
                        if (cut) {
                            el.setRangeText("");
                        }
                    } else {
                        data = el.value;
                    }

                    var cutCopyEvent = new Event(cut ? "cut" : "copy", {bubbles: true});
                    el.dispatchEvent(cutCopyEvent);

                    return os.clipboardWrite(data);
                } else {
                    var commandID = cut ?
                        CUT_NATIVE_MENU_COMMMAND_ID :
                        COPY_NATIVE_MENU_COMMMAND_ID;

                    this.flux.actions.menu.nativeModal({
                        commandID: commandID
                    });
                }
            });
    };

    /**
     * Execute a cut operation on the currently active HTML element.
     *
     * @private
     * @return {Promise}
     */
    var cutCommand = function () {
        return _cutOrCopyCommand.call(this, true);
    };

    /**
     * Execute a copy operation on the currently active HTML element.
     *
     * @private
     * @return {Promise}
     */
    var copyCommand = function () {
        return _cutOrCopyCommand.call(this, false);
    };

    /**
     * Execute a paste operation on the currently active HTML element.
     *
     * @private
     * @return {Promise}
     */
    var pasteCommand = function () {
        return os.hasKeyboardFocus()
            .bind(this)
            .then(function (cefHasFocus) {
                var el = document.activeElement;
                if (cefHasFocus && _isInput(el)) {
                    return os.clipboardRead()
                        .then(function (result) {
                            var data = result.data,
                                format = result.format;

                            if (format !== "string") {
                                return;
                            }

                            if (_isTextInput(el)) {
                                var selectionStart = el.selectionStart;
                                el.setRangeText(data);
                                el.setSelectionRange(selectionStart + data.length, selectionStart + data.length);
                            } else {
                                el.value = data;
                            }

                            var pasteEvent = new Event("paste", {bubbles: true});
                            el.dispatchEvent(pasteEvent);
                        });
                } else {
                    this.flux.actions.menu.nativeModal({
                        commandID: PASTE_NATIVE_MENU_COMMMAND_ID
                    });
                }
            });
    };

    /**
     * Execute a select operation on the currently active HTML element.
     *
     * @private
     * @return {Promise}
     */
    var selectAllCommand = function () {
        return os.hasKeyboardFocus()
            .bind(this)
            .then(function (cefHasFocus) {
                var el = document.activeElement;
                if (cefHasFocus && _isInput(el)) {
                    if (_isTextInput(el)) {
                        el.setSelectionRange(0, el.value.length);
                    }
                } else {
                    this.flux.actions.layers.selectAll();
                }
            });
    };

    /**
     * @type {Action}
     */
    var cut = {
        command: cutCommand,
        modal: true,
        reads: [],
        writes: []
    };

    /**
     * @type {Action}
     */
    var copy = {
        command: copyCommand,
        modal: true,
        reads: [],
        writes: []
    };

    /**
     * @type {Action}
     */
    var paste = {
        command: pasteCommand,
        modal: true,
        reads: [],
        writes: []
    };

    /**
     * @type {Action}
     */
    var selectAll = {
        command: selectAllCommand,
        modal: true,
        reads: [],
        writes: []
    };

    exports.cut = cut;
    exports.copy = copy;
    exports.paste = paste;
    exports.selectAll = selectAll;
});
<commit_msg>Enable Select All in text layers<commit_after>/*
 * Copyright (c) 2014 Adobe Systems Incorporated. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

define(function (require, exports) {
    "use strict";

    var os = require("adapter/os");

    /**
     * Native menu command IDs for Photoshop edit commands.
     *
     * @const
     * @private
     * @type {number}
     */
    var CUT_NATIVE_MENU_COMMMAND_ID = 103,
        COPY_NATIVE_MENU_COMMMAND_ID = 104,
        PASTE_NATIVE_MENU_COMMMAND_ID = 105,
        SELECT_ALL_NATIVE_MENU_COMMMAND_ID = 1017;

    /**
     * Determines whether the given element is an HTML input element.
     *
     * @private
     * @param {HTMLElement} el
     * @return boolean
     */
    var _isInput = function (el) {
        return el instanceof window.HTMLInputElement;
    };

    /**
     * Determines whether the given input element is a textual element.
     *
     * @private
     * @param {HTMLInputElement} el
     * @return boolean
     */
    var _isTextInput = function (el) {
        switch (el.type) {
            case "text":
            case "search":
            case "url":
            case "tel":
            case "password":
                return true;
            default:
                return false;
        }
    };

    /**
     * Execute either a cut or copy operation, depending on the value of the parameter.
     *
     * @private
     * @param {boolean} cut If true, perform a cut operation; otherwise, a copy.
     * @return {Promise}
     */
    var _cutOrCopyCommand = function (cut) {
        return os.hasKeyboardFocus()
            .bind(this)
            .then(function (cefHasFocus) {
                var el = document.activeElement;
                if (cefHasFocus && _isInput(el)) {
                    var data;
                    if (_isTextInput(el)) {
                        data = el.value.substring(el.selectionStart, el.selectionEnd);
                        if (cut) {
                            el.setRangeText("");
                        }
                    } else {
                        data = el.value;
                    }

                    var cutCopyEvent = new Event(cut ? "cut" : "copy", {bubbles: true});
                    el.dispatchEvent(cutCopyEvent);

                    return os.clipboardWrite(data);
                } else {
                    var commandID = cut ?
                        CUT_NATIVE_MENU_COMMMAND_ID :
                        COPY_NATIVE_MENU_COMMMAND_ID;

                    this.flux.actions.menu.nativeModal({
                        commandID: commandID
                    });
                }
            });
    };

    /**
     * Execute a cut operation on the currently active HTML element.
     *
     * @private
     * @return {Promise}
     */
    var cutCommand = function () {
        return _cutOrCopyCommand.call(this, true);
    };

    /**
     * Execute a copy operation on the currently active HTML element.
     *
     * @private
     * @return {Promise}
     */
    var copyCommand = function () {
        return _cutOrCopyCommand.call(this, false);
    };

    /**
     * Execute a paste operation on the currently active HTML element.
     *
     * @private
     * @return {Promise}
     */
    var pasteCommand = function () {
        return os.hasKeyboardFocus()
            .bind(this)
            .then(function (cefHasFocus) {
                var el = document.activeElement;
                if (cefHasFocus && _isInput(el)) {
                    return os.clipboardRead()
                        .then(function (result) {
                            var data = result.data,
                                format = result.format;

                            if (format !== "string") {
                                return;
                            }

                            if (_isTextInput(el)) {
                                var selectionStart = el.selectionStart;
                                el.setRangeText(data);
                                el.setSelectionRange(selectionStart + data.length, selectionStart + data.length);
                            } else {
                                el.value = data;
                            }

                            var pasteEvent = new Event("paste", {bubbles: true});
                            el.dispatchEvent(pasteEvent);
                        });
                } else {
                    this.flux.actions.menu.nativeModal({
                        commandID: PASTE_NATIVE_MENU_COMMMAND_ID
                    });
                }
            });
    };

    /**
     * Execute a select operation on the currently active HTML element.
     *
     * @private
     * @return {Promise}
     */
    var selectAllCommand = function () {
        return os.hasKeyboardFocus()
            .bind(this)
            .then(function (cefHasFocus) {
                var el = document.activeElement;
                if (cefHasFocus && _isInput(el)) {
                    if (_isTextInput(el)) {
                        el.setSelectionRange(0, el.value.length);
                    }
                } else {
                    var toolStore = this.flux.store("tool");
                    if (toolStore.getModalToolState()) {
                        this.flux.actions.menu.nativeModal({
                            commandID: SELECT_ALL_NATIVE_MENU_COMMMAND_ID
                        });
                    } else {
                        this.flux.actions.layers.selectAll();
                    }

                }
            });
    };

    /**
     * @type {Action}
     */
    var cut = {
        command: cutCommand,
        modal: true,
        reads: [],
        writes: []
    };

    /**
     * @type {Action}
     */
    var copy = {
        command: copyCommand,
        modal: true,
        reads: [],
        writes: []
    };

    /**
     * @type {Action}
     */
    var paste = {
        command: pasteCommand,
        modal: true,
        reads: [],
        writes: []
    };

    /**
     * @type {Action}
     */
    var selectAll = {
        command: selectAllCommand,
        modal: true,
        reads: [],
        writes: []
    };

    exports.cut = cut;
    exports.copy = copy;
    exports.paste = paste;
    exports.selectAll = selectAll;
});
<|endoftext|>