vknplayer
Version:
console audio player for listen music from vk.com and on-line radio
365 lines (280 loc) • 6.5 kB
JavaScript
var util = require('util');
var events = require('events');
/**
* @param {Array.<!ItemType>=} items
* @constructor
* @extends {EventEmitter}
* @template ItemType
*/
var DataList = function (items) {
this._items = [];
this._currentIndex = NaN;
this._autoSelect = true;
if (items) {
this.setItems(items);
}
};
goog.inherits(DataList, events.EventEmitter);
/**
* @param {boolean} value
*/
DataList.prototype.setAutoSelect = function(value) {
this._autoSelect = value;
};
/**
* Empty data
*/
DataList.prototype.clear = function () {
this.selectAt(NaN);
this._items.splice(0, this._items.length);
this.emit(this.EVENT_CLEAR);
};
/**
* @return {number}
*/
DataList.prototype.size = function () {
return this._items.length;
};
/**
* @param {Array.<!ItemType>} items
*/
DataList.prototype.addItems = function (items) {
for (var i = 0; i < items.length; i++) {
this.add(items[i]);
}
this.emit(this.EVENT_ITEMS_ADDED, items);
};
/**
* @param {Array.<!ItemType>} items
* @param {number} index
*/
DataList.prototype.addItemsAt = function (items, index) {
for (var i = 0; i < items.length; i++) {
this.addAt(items[i], index + i);
}
this.emit(this.EVENT_ITEMS_ADDED, items);
};
/**
* @param {Array.<!ItemType>} items
*/
DataList.prototype.removeItems = function (items) {
var reallyRemovedItems = [];
for (var i = 0; i < items.length; i++) {
if (this.remove(items[i])) {
reallyRemovedItems.push(items[i]);
}
}
this.emit(this.EVENT_ITEMS_REMOVED, reallyRemovedItems);
};
/**
* @param {Array.<!ItemType>} items
*/
DataList.prototype.setItems = function (items) {
this.clear();
this.addItems(items);
};
/**
* @param {!ItemType} item
*/
DataList.prototype.add = function (item) {
this.addAt(item, this.size());
};
/**
* @param {!ItemType} item
* @param {number} index
*/
DataList.prototype.addAt = function (item, index) {
var currentIndex = this.currentIndex();
var changedIndex = null;
var fireSelectAt = false;
this._items.splice(index, 0, item);
if (this._autoSelect && isNaN(currentIndex)) {
fireSelectAt = true;
changedIndex = 0;
} else if (!isNaN(currentIndex) && currentIndex >= index) {
if (currentIndex === index) {
fireSelectAt = true;
}
changedIndex = currentIndex + 1;
}
this.emit(this.EVENT_ITEM_ADDED, item, index);
if (this.size() == 1) {
this.emit(this.EVENT_FIRST_ITEM_ADDED, item);
}
if (changedIndex !== null) {
if (fireSelectAt) {
this.selectAt(changedIndex);
} else {
this._currentIndex = changedIndex;
}
}
};
/**
* @param {!ItemType} item
* @return {boolean}
*/
DataList.prototype.remove = function (item) {
return this.removeAt(this.indexOf(item));
};
/**
* @param {number} index
* @return {boolean}
*/
DataList.prototype.removeAt = function (index) {
if (!this.isValidIndex(index)) {
return false;
}
var currentIndex = this.currentIndex();
var removedItem = this._items.splice(index, 1)[0];
var changedIndex = null;
var fireSelectAt = false;
if (!isNaN(currentIndex)) {
if (currentIndex === index) {
this._currentIndex = NaN;
changedIndex = NaN;
if (this.isValidIndex(index)) {
changedIndex = currentIndex;
} else if (this.isValidIndex(index - 1)) {
changedIndex = index - 1;
}
fireSelectAt = true;
} else if (currentIndex > index) {
changedIndex = currentIndex - 1;
}
}
this.emit(this.EVENT_ITEM_REMOVED, removedItem, index);
if (changedIndex !== null) {
if (fireSelectAt) {
this.selectAt(changedIndex);
} else {
this._currentIndex = changedIndex;
}
}
if (this.size() == 0) {
this.emit(this.EVENT_CLEAR);
}
return true;
};
/**
* @param {!ItemType} item
* @return {boolean}
*/
DataList.prototype.select = function (item) {
return this.selectAt(this.indexOf(item));
};
/**
* @param {number} index
* @return {boolean}
*/
DataList.prototype.selectAt = function (index) {
if (this.isValidIndex(index) || isNaN(index)) {
if (index !== this._currentIndex) {
var prevItem = this.current();
var prevIndex = this.currentIndex();
this._currentIndex = index;
this.emit(this.EVENT_ITEM_SELECTED, this.current(), this.currentIndex(), prevItem, prevIndex);
}
return true;
}
return false;
};
/**
* @param {!ItemType} item
* @return {number} -1 if not found
*/
DataList.prototype.indexOf = function (item) {
return this._items.indexOf(item);
};
/**
* @param {number} index
* @return {boolean}
*/
DataList.prototype.isValidIndex = function (index) {
return index >= 0 && index < this._items.length;
};
/**
* @return {?ItemType}
*/
DataList.prototype.current = function () {
return this.itemAt(this.currentIndex());
};
/**
* @return {number}
*/
DataList.prototype.currentIndex = function () {
return this._currentIndex;
};
/**
* @param {number} index
* @return {?ItemType}
*/
DataList.prototype.itemAt = function (index) {
if (!this.isValidIndex(index)) {
return null;
}
return this._items[index];
};
/**
* @param {number=} step Default 1.
* @return {boolean}
*/
DataList.prototype.selectNextItem = function (step) {
step = isNaN(step) ? 1 : (step < 1 ? 1 : step);
return this.selectAt(this.currentIndex() + step);
};
/**
* @param {number=} step Default 1.
* @return {boolean}
*/
DataList.prototype.selectPrevItem = function (step) {
step = isNaN(step) ? 1 : (step < 1 ? 1 : step);
return this.selectAt(this.currentIndex() - step);
};
/**
* @returns {Array.<ItemType>}
*/
DataList.prototype.toArray = function () {
return this._items;
};
/**
* @type {Array.<ItemType>}
* @protected
*/
DataList.prototype._items;
/**
* @type {number}
*/
DataList.prototype._currentIndex;
/**
* @type {boolean}
*/
DataList.prototype._autoSelect;
/**
* @const Fired with args: item, index, prevItem, prevIndex
*/
DataList.prototype.EVENT_ITEM_SELECTED = 'item-selected';
/**
* @const Fired without args.
*/
DataList.prototype.EVENT_CLEAR = 'clear';
/**
* @const Fired with args: item
*/
DataList.prototype.EVENT_FIRST_ITEM_ADDED = 'first-item-added';
/**
* @const Fired with args: item, index
*/
DataList.prototype.EVENT_ITEM_ADDED = 'item-added';
/**
* @const Fired with args: Array.<!ItemType>
*/
DataList.prototype.EVENT_ITEMS_ADDED = 'items-added';
/**
* @const Fired with args: item, index
*/
DataList.prototype.EVENT_ITEM_REMOVED = 'item-removed';
/**
* @const Fired with args: Array.<!ItemType>
*/
DataList.prototype.EVENT_ITEMS_REMOVED = 'items-removed';
module.exports = DataList;