spiritjs
Version:
The animation toolkit for the web
476 lines (451 loc) • 14.3 kB
JavaScript
"use strict";
exports.__esModule = true;
exports["default"] = void 0;
var is = _interopRequireWildcard(require("../utils/is"));
var _events = require("../utils/events");
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _construct(t, e, r) { if (_isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments); var o = [null]; o.push.apply(o, e); var p = new (t.bind.apply(t, o))(); return r && _setPrototypeOf(p, r.prototype), p; }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _inheritsLoose(t, o) { t.prototype = Object.create(o.prototype), t.prototype.constructor = t, _setPrototypeOf(t, o); }
function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
/**
* List
*
* @fires List#add
* @fires List#remove
* @fires List#change:list
*/
var List = /*#__PURE__*/function (_Emitter) {
/**
* Create List
*
* @param {Array} items
* @param {*} model
* @param {Array|undefined} defaultModelArgs
*/
function List(items, model, defaultModelArgs) {
var _this;
if (items === void 0) {
items = [];
}
if (model === void 0) {
model = null;
}
if (defaultModelArgs === void 0) {
defaultModelArgs = undefined;
}
_this = _Emitter.call(this) || this;
_this._list = [];
_this._model = null;
_this._duplicates = true;
_this._sortOn = false;
_this._linkedList = false;
_this._model = model;
if (model) {
var testProto = defaultModelArgs !== undefined ? _construct(model, defaultModelArgs) // eslint-disable-line new-cap
: new model(); // eslint-disable-line new-cap
if (typeof testProto.toObject !== 'function') {
throw new Error('Invalid Model prototype. model.toObject does not exist.');
}
}
if (!Array.isArray(items)) {
throw new Error('Items should be an array');
}
// parse initial list
_this._list = items.reduce(function (list, item) {
if (_this._model) {
if (item instanceof _this._model) {
item._list = _this;
if (item.setupBubbleEvents && typeof item.setupBubbleEvents === 'function') {
item.setupBubbleEvents();
}
list.push(item);
} else {
if (is.isObject(item) && typeof model.fromObject === 'function') {
var itemFromModel = model.fromObject(item);
itemFromModel._list = _this;
if (itemFromModel.setupBubbleEvents && typeof itemFromModel.setupBubbleEvents === 'function') {
itemFromModel.setupBubbleEvents();
}
list.push(itemFromModel);
} else {
throw new Error('Could not parse item from model');
}
}
} else {
list.push(item);
}
return list;
}, []);
return _this;
}
/**
* Get list to allow duplicates
*
* @returns {boolean|object}
*/
_inheritsLoose(List, _Emitter);
var _proto = List.prototype;
/**
* Check current list on duplicates
*/
_proto.checkOnDuplicates = function checkOnDuplicates() {
var dup = this._duplicates;
var uniq = false;
var isProp = false;
// check based on boolean
if (typeof dup === 'boolean' && dup === false) {
uniq = this.list.map(function (item) {
return {
count: 1,
item: item
};
}).reduce(function (a, b) {
a[b.item] = (a[b.item] || 0) + b.count;
return a;
}, {});
}
// check based on object property
if (is.isObject(dup) && dup.hasOwnProperty('prop')) {
isProp = true;
uniq = this.list.map(function (item) {
return {
count: 1,
prop: item[dup.prop]
};
}).reduce(function (a, b) {
a[b.prop] = (a[b.prop] || 0) + b.count;
return a;
}, {});
}
if (uniq && Object.keys(uniq).filter(function (a) {
return uniq[a] > 1;
}).length > 0) {
var prop = Object.keys(uniq).find(function (p) {
return uniq[p] > 1;
});
var p = isProp ? dup.prop + ": " + prop : false;
var m = this._model ? this.constructor.name + " > " + this._model.name + " > { " + p + " }" : false;
throw new Error("List has duplicates. " + m);
}
}
/**
* Get the sort type of this list
*
* @returns {boolean|string}
*/;
/**
* Sort list based on sort type
*/
_proto.sort = function sort() {
var so = this._sortOn;
// sort on primitives
if (typeof so === 'boolean' && so === true) {
this._list = this._list.sort();
}
// sort on property
if (typeof so === 'string') {
this._list = this._list.sort(function (a, b) {
var valA = a[so];
var valB = b[so];
if (is.isNumeric(valA)) {
return valA - valB;
}
String(valA).localeCompare(String(valB));
});
}
// sort on function
if (typeof so === 'function') {
this._list = this._list.sort(so);
}
}
/**
* Is current list linked?
*
* @returns {boolean}
*/;
/**
* Link items to each other as a linked list based on sortOn
* if this list is setup as a linked list
*/
_proto.linkItems = function linkItems() {
if (this._linkedList) {
for (var i = 0; i < this._list.length; i++) {
if (is.isObject(this._list[i])) {
this._list[i]._prev = i > 0 ? this._list[i - 1] : null;
this._list[i]._next = i < this._list.length - 1 ? this._list[i + 1] : null;
} else {
throw new Error('Can not link primitives.');
}
}
}
}
/**
* Get the list
*
* @returns {Array}
*/;
/**
* Get the value at index
*
* @param {number} index
* @returns {*}
*/
_proto.at = function at(index) {
if (index >= this._list.length) {
throw new Error("Index exceeded. Requested " + index + ", have length of " + this.length);
}
return this._list[index];
}
/**
* Add item to list
*
* @param {*|Array} item
* @fires List#add
* @returns {*}
*/;
_proto.add = function add(item) {
var _this2 = this;
var result = null;
var addSingle = function addSingle(i) {
var newItem;
if (_this2._model) {
if (i instanceof _this2._model) {
newItem = i;
newItem._list = _this2;
if (newItem.setupBubbleEvents && typeof newItem.setupBubbleEvents === 'function') {
newItem.setupBubbleEvents();
}
} else if (is.isObject(i) && typeof _this2._model.fromObject === 'function') {
newItem = _this2._model.fromObject(i);
newItem._list = _this2;
if (newItem.setupBubbleEvents && typeof newItem.setupBubbleEvents === 'function') {
newItem.setupBubbleEvents();
}
} else {
throw new Error('Invalid item.');
}
} else {
newItem = i;
}
Array.isArray(result) ? result.push(newItem) : result = newItem;
_this2._list.push(newItem);
/**
* List event.
*
* @event List#add
* @type {*}
*/
_this2.emit('add', newItem);
};
if (Array.isArray(item)) {
result = [];
item.forEach(addSingle);
} else {
addSingle(item);
}
this.checkOnDuplicates();
this.sort();
this.linkItems();
return result;
}
/**
* Remove item from list
*
* @fires List#remove
* @param {*|Array} item
*/;
_proto.remove = function remove(item) {
var _this3 = this;
var result = null;
var removeSingle = function removeSingle(i) {
var doRemove = function doRemove(ins) {
var index = _this3._list.indexOf(ins);
if (index > -1) {
_this3._list.splice(index, 1);
if (is.isObject(ins)) {
if ('_prev' in ins) {
delete ins._prev;
}
if ('_next' in ins) {
delete ins._next;
}
}
/**
* List event.
*
* @event List#remove
* @type {*}
*/
_this3.emit('remove', ins);
if (ins._list && ins._list instanceof List) {
ins._list = null;
}
Array.isArray(result) ? result.push(ins) : result = ins;
}
};
if (_this3._model) {
if (i instanceof _this3._model) {
doRemove(i);
}
} else {
doRemove(i);
}
};
if (Array.isArray(item)) {
result = [];
item.forEach(removeSingle);
} else {
removeSingle(item);
}
this.sort();
this.linkItems();
return result;
}
/**
* Clear the list
*/;
_proto.clear = function clear() {
this.each(this.remove.bind(this));
}
/**
* Walk over each item
*
* @returns {*}
*/;
_proto.each = function each(cb) {
var list = [].concat(this.list);
var mapped = [];
var error = false;
for (var i = 0; i < list.length; i++) {
var item = list[i];
try {
mapped.push(cb(item, i));
} catch (err) {
error = err;
}
if (error) {
break;
}
}
if (error) {
throw error;
}
return mapped;
}
/**
* Get an object representation of this list
*
* @returns {Array}
*/;
_proto.toArray = function toArray() {
var l = this._model ? this.list.map(function (item) {
return item.toObject();
}) : this.list;
return l.reduce(function (a, b) {
if (is.isObject(b)) {
var obj = _objectSpread({}, b);
delete obj._prev;
delete obj._next;
delete obj._list;
a.push(obj);
} else {
a.push(b);
}
return a;
}, []);
};
return _createClass(List, [{
key: "duplicates",
get: function get() {
return this._duplicates;
}
/**
* Set list to allow duplicates
*
* @param {boolean|object} dup
*
* When dup is an object it can check on a property
* @example { prop: 'id' }
*/,
set: function set(dup) {
this._duplicates = dup;
this.checkOnDuplicates();
}
}, {
key: "sortOn",
get: function get() {
return this._sortOn;
}
/**
* Set the sort type of this list
*
* @param {boolean|string} sortType
*/,
set: function set(sortType) {
this._sortOn = sortType;
this.sort();
}
}, {
key: "linkedList",
get: function get() {
return this._linkedList;
}
/**
* Set current list as a linked list
*
* @param {boolean} linked
*/,
set: function set(linked) {
this._linkedList = linked;
this.linkItems();
}
}, {
key: "list",
get: function get() {
return this._list;
}
/**
* Reset the list
*
* @param {Array} l
* @fires List#change:list
*/,
set: function set(l) {
if (!Array.isArray(l)) {
throw new Error('List should be an array');
}
this._list = l;
if (this._linkedList) {
this.linkItems();
}
/**
* List event.
*
* @event List#change:list
* @type {Array}
*/
this.emit('change:list', l);
}
/**
* Get the length of list
*
* @returns {Number}
*/
}, {
key: "length",
get: function get() {
return this.list.length;
}
}]);
}(_events.Emitter);
List.Events = ['change:list', 'add', 'remove'];
var _default = exports["default"] = List;