UNPKG

spiritjs

Version:

The animation toolkit for the web

476 lines (451 loc) 14.3 kB
"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;