/node_modules/bower/node_modules/inquirer/lib/objects/choices.js
https://gitlab.com/jorgegoes/jointswp-child · JavaScript · 173 lines · 84 code · 39 blank · 50 comment · 7 complexity · 8b5b96ec744cd45a7c480bfafa36bbd2 MD5 · raw file
- /**
- * Choices object
- * Collection of multiple `choice` object
- */
- var _ = require("lodash");
- var clc = require("cli-color");
- var Separator = require("./separator");
- var Choice = require("./choice");
- /**
- * Module exports
- */
- module.exports = Choices;
- /**
- * Choices collection
- * @constructor
- * @param {Array} choices All `choice` to keep in the collection
- */
- function Choices( choices ) {
- this.choices = _.map( choices, function( val ) {
- if ( val instanceof Separator ) {
- return val;
- }
- return new Choice( val );
- });
- this.realChoices = this.choices.filter(Separator.exclude);
- Object.defineProperty( this, "length", {
- get: function() {
- return this.choices.length;
- },
- set: function( val ) {
- this.choices.length = val;
- }
- });
- Object.defineProperty( this, "realLength", {
- get: function() {
- return this.realChoices.length;
- },
- set: function() {
- throw new Error("Cannot set `realLength` of a Choices collection");
- }
- });
- // Set pagination state
- this.pointer = 0;
- this.lastIndex = 0;
- }
- /**
- * Get a valid choice from the collection
- * @param {Number} selector The selected choice index
- * @return {Choice|Undefined} Return the matched choice or undefined
- */
- Choices.prototype.getChoice = function( selector ) {
- if ( _.isNumber(selector) ) {
- return this.realChoices[ selector ];
- }
- return undefined;
- };
- /**
- * Get a raw element from the collection
- * @param {Number} selector The selected index value
- * @return {Choice|Undefined} Return the matched choice or undefined
- */
- Choices.prototype.get = function( selector ) {
- if ( _.isNumber(selector) ) {
- return this.choices[ selector ];
- }
- return undefined;
- };
- /**
- * Match the valid choices against a where clause
- * @param {Object} whereClause Lodash `where` clause
- * @return {Array} Matching choices or empty array
- */
- Choices.prototype.where = function( whereClause ) {
- return _.where( this.realChoices, whereClause );
- };
- /**
- * Pluck a particular key from the choices
- * @param {String} propertyName Property name to select
- * @return {Array} Selected properties
- */
- Choices.prototype.pluck = function( propertyName ) {
- return _.pluck( this.realChoices, propertyName );
- };
- // Propagate usual Array methods
- Choices.prototype.forEach = function() {
- return this.choices.forEach.apply( this.choices, arguments );
- };
- Choices.prototype.filter = function() {
- return this.choices.filter.apply( this.choices, arguments );
- };
- Choices.prototype.push = function() {
- var objs = _.map( arguments, function( val ) { return new Choice( val ); });
- this.choices.push.apply( this.choices, objs );
- this.realChoices = this.choices.filter(Separator.exclude);
- return this.choices;
- };
- /**
- * Render the choices as formatted string
- * @return {String} formatted content
- */
- Choices.prototype.render = function() {
- return this.renderingMethod.apply( this, arguments );
- };
- /**
- * Set the rendering method
- * @param {Function} render Function to be use when rendering
- */
- Choices.prototype.setRender = function( render ) {
- this.renderingMethod = (this.choices.length > 9) ? this.paginateOutput(render) : render;
- };
- /**
- * Paginate the output of a render function
- * @param {Function} render Render function whose content must be paginated
- * @return {Function} Wrapped render function
- */
- Choices.prototype.paginateOutput = function( render ) {
- var pageSize = 7;
- return function( active ) {
- var output = render.apply( this, arguments );
- var lines = output.split("\n");
- // Make sure there's enough line to paginate
- if ( lines.length <= pageSize ) return output;
- // Move the pointer only when the user go down and limit it to 3
- if ( this.pointer < 3 && this.lastIndex < active && active - this.lastIndex < 9 ) {
- this.pointer = Math.min( 3, this.pointer + active - this.lastIndex);
- }
- this.lastIndex = active;
- // Duplicate the lines so it give an infinite list look
- var infinite = _.flatten([ lines, lines, lines ]);
- var topIndex = Math.max( 0, active + lines.length - this.pointer );
- var section = infinite.splice( topIndex, pageSize ).join("\n");
- return section + "\n" + clc.blackBright("(Move up and down to reveal more choices)");
- }.bind(this);
- };