rasti 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2018 Alberto Masuelli
3
+ Copyright (c) 2018-present Alberto Masuelli
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # <a href='http://rasti.js.org'><img src='logo.svg' height='80' alt='Rasti' aria-label='rasti.js.org' /></a>
1
+ # <a href="http://rasti.js.org"><img src="docs/logo.svg" height="80" alt="Rasti" aria-label="rasti.js.org" /></a>
2
2
 
3
3
  Rasti is a minimalistic JavaScript MV library for building user interfaces.<br />
4
4
  It gives structure to applications by providing [models](docs/api.md#module_Model) that emit events on properties changes, and [views](docs/api.md#module_View) with declarative DOM events handling to define UI components.<br />
package/dist/rasti.js CHANGED
@@ -1,3 +1,11 @@
1
+ /*
2
+ * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
3
+ * This devtool is neither made for production nor for readable output files.
4
+ * It uses "eval()" calls to create a separate source file in the browser devtools.
5
+ * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
6
+ * or disable the default devtool with "devtool: false".
7
+ * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
8
+ */
1
9
  (function webpackUniversalModuleDefinition(root, factory) {
2
10
  if(typeof exports === 'object' && typeof module === 'object')
3
11
  module.exports = factory();
@@ -7,104 +15,18 @@
7
15
  exports["Rasti"] = factory();
8
16
  else
9
17
  root["Rasti"] = factory();
10
- })(window, function() {
11
- return /******/ (function(modules) { // webpackBootstrap
12
- /******/ // The module cache
13
- /******/ var installedModules = {};
14
- /******/
15
- /******/ // The require function
16
- /******/ function __webpack_require__(moduleId) {
17
- /******/
18
- /******/ // Check if module is in cache
19
- /******/ if(installedModules[moduleId]) {
20
- /******/ return installedModules[moduleId].exports;
21
- /******/ }
22
- /******/ // Create a new module (and put it into the cache)
23
- /******/ var module = installedModules[moduleId] = {
24
- /******/ i: moduleId,
25
- /******/ l: false,
26
- /******/ exports: {}
27
- /******/ };
28
- /******/
29
- /******/ // Execute the module function
30
- /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
31
- /******/
32
- /******/ // Flag the module as loaded
33
- /******/ module.l = true;
34
- /******/
35
- /******/ // Return the exports of the module
36
- /******/ return module.exports;
37
- /******/ }
38
- /******/
39
- /******/
40
- /******/ // expose the modules object (__webpack_modules__)
41
- /******/ __webpack_require__.m = modules;
42
- /******/
43
- /******/ // expose the module cache
44
- /******/ __webpack_require__.c = installedModules;
45
- /******/
46
- /******/ // define getter function for harmony exports
47
- /******/ __webpack_require__.d = function(exports, name, getter) {
48
- /******/ if(!__webpack_require__.o(exports, name)) {
49
- /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
50
- /******/ }
51
- /******/ };
52
- /******/
53
- /******/ // define __esModule on exports
54
- /******/ __webpack_require__.r = function(exports) {
55
- /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
56
- /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
57
- /******/ }
58
- /******/ Object.defineProperty(exports, '__esModule', { value: true });
59
- /******/ };
60
- /******/
61
- /******/ // create a fake namespace object
62
- /******/ // mode & 1: value is a module id, require it
63
- /******/ // mode & 2: merge all properties of value into the ns
64
- /******/ // mode & 4: return value when already ns object
65
- /******/ // mode & 8|1: behave like require
66
- /******/ __webpack_require__.t = function(value, mode) {
67
- /******/ if(mode & 1) value = __webpack_require__(value);
68
- /******/ if(mode & 8) return value;
69
- /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
70
- /******/ var ns = Object.create(null);
71
- /******/ __webpack_require__.r(ns);
72
- /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
73
- /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
74
- /******/ return ns;
75
- /******/ };
76
- /******/
77
- /******/ // getDefaultExport function for compatibility with non-harmony modules
78
- /******/ __webpack_require__.n = function(module) {
79
- /******/ var getter = module && module.__esModule ?
80
- /******/ function getDefault() { return module['default']; } :
81
- /******/ function getModuleExports() { return module; };
82
- /******/ __webpack_require__.d(getter, 'a', getter);
83
- /******/ return getter;
84
- /******/ };
85
- /******/
86
- /******/ // Object.prototype.hasOwnProperty.call
87
- /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
88
- /******/
89
- /******/ // __webpack_public_path__
90
- /******/ __webpack_require__.p = "";
91
- /******/
92
- /******/
93
- /******/ // Load entry module and return exports
94
- /******/ return __webpack_require__(__webpack_require__.s = 0);
95
- /******/ })
96
- /************************************************************************/
97
- /******/ ({
18
+ })(self, () => {
19
+ return /******/ (() => { // webpackBootstrap
20
+ /******/ "use strict";
21
+ /******/ var __webpack_modules__ = ({
98
22
 
99
23
  /***/ "./src/Emitter.js":
100
24
  /*!************************!*\
101
25
  !*** ./src/Emitter.js ***!
102
26
  \************************/
103
- /*! no static exports found */
104
- /***/ (function(module, exports, __webpack_require__) {
27
+ /***/ ((__unused_webpack_module, exports) => {
105
28
 
106
- "use strict";
107
- eval("\n\nexports.__esModule = true;\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/**\n * Emitter is a class that can be extended giving the subclass the ability to emit \n * and bind custom named events. Model and View inherits from it.\n * @module\n * @example\n * import { Emitter } from 'rasti';\n * // Define App class, inherits from Emitter.\n * class App extends Emitter {\n * constructor() {\n * super()\n * // Fetch data and emit `ready` event.\n * fetch('/api/init').then(() => this.emit('ready')); \n * }\n * }\n * // Instantiate App.\n * const app = new App();\n * // Add event listener to ready event.\n * app.on('ready', () => console.log('app is ready!'));\n */\nvar Emitter = function () {\n function Emitter() {\n _classCallCheck(this, Emitter);\n }\n\n /**\n * Adds event listener.\n * @param {string} type Type of the event (e.g. `change`).\n * @param {function} listener Callback function to be called when the event is emitted.\n * @example\n * this.model.on('change', this.render.bind(this)); // Re render when model changes.\n */\n Emitter.prototype.on = function on(type, listener) {\n if (typeof listener !== 'function') {\n throw TypeError('Listener must be a function');\n }\n\n if (!this.listeners) this.listeners = {};\n if (!this.listeners[type]) this.listeners[type] = [];\n\n this.listeners[type].push(listener);\n };\n\n /**\n * Adds event listener that executes once.\n * @param {string} type Type of the event (e.g. `change`).\n * @param {function} listener Callback function to be called when the event is emitted.\n * @example\n * this.model.once('change', () => console.log('This will happen once'));\n */\n\n\n Emitter.prototype.once = function once(type, _listener2) {\n if (typeof _listener2 === 'function') {\n var self = this;\n var _listener = _listener2;\n\n _listener2 = function listener() {\n _listener.apply(undefined, arguments);\n self.off(type, _listener2);\n };\n }\n this.on(type, _listener2);\n };\n\n /**\n * Removes event listeners.\n * @param {string} [type] Type of the event (e.g. `change`). If is not provided, it removes all listeners.\n * @param {function} [listener] Callback function to be called when the event is emitted. If listener is not provided, it removes all listeners for specified type.\n * @example\n * this.model.off('change'); // Stop listening to changes.\n */\n\n\n Emitter.prototype.off = function off(type, listener) {\n if (!type) {\n this.listeners = {};\n } else {\n if (!listener) {\n delete this.listeners[type];\n } else {\n var listeners = this.listeners[type];\n if (listeners) {\n var copy = listeners.slice();\n\n copy.forEach(function (fn, idx) {\n if (fn === listener) listeners.splice(idx, 1);\n });\n\n if (!listeners.length) {\n delete this.listeners[type];\n }\n }\n }\n }\n };\n\n /**\n * Emits event of specified type. Listeners will receive specified arguments.\n * @param {string} type Type of the event (e.g. `change`).\n * @param {any} [...args] Arguments to be passed to listener.\n * @example\n * this.emit('invalid'); // Emit validation error event.\n */\n\n\n Emitter.prototype.emit = function emit(type) {\n for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n\n var listeners = this.listeners && this.listeners[type];\n\n if (!listeners || !listeners.length) return;\n\n var copy = listeners.slice();\n\n copy.forEach(function (fn) {\n fn.apply(undefined, args);\n });\n };\n\n return Emitter;\n}();\n\nexports['default'] = Emitter;\n\n//# sourceURL=webpack://Rasti/./src/Emitter.js?");
29
+ eval("\n\nexports.__esModule = true;\nexports[\"default\"] = void 0;\n/**\n * Emitter is a class that can be extended giving the subclass the ability to emit \n * and bind custom named events. Model and View inherits from it.\n * @module\n * @example\n * import { Emitter } from 'rasti';\n * // Define App class, inherits from Emitter.\n * class App extends Emitter {\n * constructor() {\n * super()\n * // Fetch data and emit `ready` event.\n * fetch('/api/init').then(() => this.emit('ready')); \n * }\n * }\n * // Instantiate App.\n * const app = new App();\n * // Add event listener to ready event.\n * app.on('ready', () => console.log('app is ready!'));\n */\nvar Emitter = /*#__PURE__*/function () {\n function Emitter() {}\n var _proto = Emitter.prototype;\n /**\n * Adds event listener.\n * @param {string} type Type of the event (e.g. `change`).\n * @param {function} listener Callback function to be called when the event is emitted.\n * @example\n * this.model.on('change', this.render.bind(this)); // Re render when model changes.\n */\n _proto.on = function on(type, listener) {\n if (typeof listener !== 'function') {\n throw TypeError('Listener must be a function');\n }\n if (!this.listeners) this.listeners = {};\n if (!this.listeners[type]) this.listeners[type] = [];\n this.listeners[type].push(listener);\n }\n\n /**\n * Adds event listener that executes once.\n * @param {string} type Type of the event (e.g. `change`).\n * @param {function} listener Callback function to be called when the event is emitted.\n * @example\n * this.model.once('change', () => console.log('This will happen once'));\n */;\n _proto.once = function once(type, _listener2) {\n if (typeof _listener2 === 'function') {\n var self = this;\n var _listener = _listener2;\n _listener2 = function listener() {\n _listener.apply(void 0, arguments);\n self.off(type, _listener2);\n };\n }\n this.on(type, _listener2);\n }\n\n /**\n * Removes event listeners.\n * @param {string} [type] Type of the event (e.g. `change`). If is not provided, it removes all listeners.\n * @param {function} [listener] Callback function to be called when the event is emitted. If listener is not provided, it removes all listeners for specified type.\n * @example\n * this.model.off('change'); // Stop listening to changes.\n */;\n _proto.off = function off(type, listener) {\n if (!type) {\n this.listeners = {};\n } else {\n if (!listener) {\n delete this.listeners[type];\n } else {\n var listeners = this.listeners[type];\n if (listeners) {\n var copy = listeners.slice();\n copy.forEach(function (fn, idx) {\n if (fn === listener) listeners.splice(idx, 1);\n });\n if (!listeners.length) {\n delete this.listeners[type];\n }\n }\n }\n }\n }\n\n /**\n * Emits event of specified type. Listeners will receive specified arguments.\n * @param {string} type Type of the event (e.g. `change`).\n * @param {any} [...args] Arguments to be passed to listener.\n * @example\n * this.emit('invalid'); // Emit validation error event.\n */;\n _proto.emit = function emit(type) {\n for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n var listeners = this.listeners && this.listeners[type];\n if (!listeners || !listeners.length) return;\n var copy = listeners.slice();\n copy.forEach(function (fn) {\n fn.apply(void 0, args);\n });\n };\n return Emitter;\n}();\nexports[\"default\"] = Emitter;\n\n//# sourceURL=webpack://Rasti/./src/Emitter.js?");
108
30
 
109
31
  /***/ }),
110
32
 
@@ -112,11 +34,9 @@ eval("\n\nexports.__esModule = true;\n\nfunction _classCallCheck(instance, Const
112
34
  /*!**********************!*\
113
35
  !*** ./src/Model.js ***!
114
36
  \**********************/
115
- /*! no static exports found */
116
- /***/ (function(module, exports, __webpack_require__) {
37
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
117
38
 
118
- "use strict";
119
- eval("\n\nexports.__esModule = true;\n\nvar _Emitter2 = __webpack_require__(/*! ./Emitter */ \"./src/Emitter.js\");\n\nvar _Emitter3 = _interopRequireDefault(_Emitter2);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n/**\n * - Orchestrates data and business logic.\n * - Emits events when data changes.\n * \n * A Model manages an internal table of data attributes, and triggers \"change\" events \n * when any of its data is modified.<br />\n * Models may handle syncing data with a persistence layer.<br />\n * Design your models as the atomic reusable objects containing all of the helpful functions for \n * manipulating their particular bit of data.<br /> \n * Models should be able to be passed around throughout your app, and used anywhere that bit of data is needed.<br />\n * Rasti Models stores its attributes in `this.attributes`, which is extended from `this.defaults` and constructor `attrs` parameter.\n * For every attribute, a getter is generated, which retrieve the model property from `this.attributes`.\n * And a setter, which sets the model property in `this.attributes` and emits `change` and `change:attribute` events.\n * @module\n * @param {object} attrs Object containing model attributes to extend `this.attributes`. Getters and setters are generated for `this.attributtes`, in order to emit `change` events.\n * @example\n * // Todo model\n * class TodoModel extends Rasti.Model {\n * toggle() {\n * // Set completed property. This will call a setter that will set `completed` \n * // in this.attributes, and emit `change` and `change:completed` events.\n * this.completed = !this.completed; \n * }\n * }\n * // Todo model has `title` and `completed` default attributes. `defaults` will extend `this.attributes`. Getters and setters are generated for `this.attributtes`, in order to emit `change` events.\n * TodoModel.prototype.defaults = {\n * title : '',\n * completed : false\n * };\n * // Create todo. Pass `title` attribute as argument.\n * const todo = new TodoModel({ title : 'Learn Rasti' });\n * // Listen to `change:completed` event.\n * todo.on('change:completed', () => console.log('Completed:', todo.completed));\n * // Complete todo.\n * todo.toggle(); // Completed: true\n */\nvar Model = function (_Emitter) {\n _inherits(Model, _Emitter);\n\n function Model() {\n var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n _classCallCheck(this, Model);\n\n // Call preinitialize.\n var _this = _possibleConstructorReturn(this, _Emitter.call(this));\n\n _this.preinitialize.apply(_this, arguments);\n // attributes object.\n _this.attributes = Object.assign({}, _this.defaults || {}, attrs);\n // Previous attributes.\n _this.previous = {};\n // Generate getters/setters for every attr.\n Object.keys(_this.attributes).forEach(_this.defineAttribute.bind(_this));\n return _this;\n }\n\n /**\n * If you define a preinitialize method, it will be invoked when the Model is first created, before any instantiation logic is run for the Model.\n * @param {object} attrs Object containing model attributes to extend `this.attributes`.\n */\n\n\n Model.prototype.preinitialize = function preinitialize() {};\n\n /**\n * Generate getter/setter for the given key. In order to emit `change` events.\n * This method is called internally by the constructor\n * for `this.attributes`.\n * @param {string} key Attribute key.\n */\n\n\n Model.prototype.defineAttribute = function defineAttribute(key) {\n var _this2 = this;\n\n Object.defineProperty(this, key, {\n get: function get() {\n return _this2.get(key);\n },\n set: function set(value) {\n return _this2.set(key, value);\n }\n });\n };\n\n /**\n * Get an attribute from `this.attributes`.\n * This method is called internally by generated getters.\n * @param {string} key Attribute key.\n * @return {any} The attribute value.\n */\n\n\n Model.prototype.get = function get(key) {\n return this.attributes[key];\n };\n\n /**\n * Set an attribute into `this.attributes`.\n * Emit `change` and `change:attribute` if value change.\n * Could be called in two forms, `this.set('key', value)` and\n * `this.set({ key : value })`.\n * This method is called internally by generated setters.\n * @param {string} key Attribute key or object containing keys/values.\n * @param [value] Attribute value.\n * @return {this} This model.\n * @emits change\n * @emits change:attribute\n */\n\n\n Model.prototype.set = function set(key, value) {\n var _ref,\n _this3 = this;\n\n var attrs = typeof key === 'object' ? key : (_ref = {}, _ref[key] = value, _ref);\n Object.keys(attrs).forEach(function (key) {\n var changed = key in _this3.attributes && attrs[key] !== _this3.attributes[key];\n\n _this3.previous[key] = _this3.attributes[key];\n _this3.attributes[key] = attrs[key];\n // Emit change events.\n if (changed) {\n _this3.emit('change', _this3, key, attrs[key]);\n _this3.emit('change:' + key, _this3, attrs[key]);\n }\n });\n return this;\n };\n\n /**\n * Return object representation of the model to be used for JSON serialization.\n * By default returns `this.attributes`.\n * @return {object} Object representation of the model to be used for JSON serialization.\n */\n\n\n Model.prototype.toJSON = function toJSON() {\n return this.attributes;\n };\n\n return Model;\n}(_Emitter3['default']);\n\nexports['default'] = Model;\n\n//# sourceURL=webpack://Rasti/./src/Model.js?");
39
+ eval("\n\nexports.__esModule = true;\nexports[\"default\"] = void 0;\nvar _Emitter2 = _interopRequireDefault(__webpack_require__(/*! ./Emitter */ \"./src/Emitter.js\"));\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; }\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n/**\n * - Orchestrates data and business logic.\n * - Emits events when data changes.\n * \n * A Model manages an internal table of data attributes, and triggers \"change\" events \n * when any of its data is modified.<br />\n * Models may handle syncing data with a persistence layer.<br />\n * Design your models as the atomic reusable objects containing all of the helpful functions for \n * manipulating their particular bit of data.<br /> \n * Models should be able to be passed around throughout your app, and used anywhere that bit of data is needed.<br />\n * Rasti Models stores its attributes in `this.attributes`, which is extended from `this.defaults` and constructor `attrs` parameter.\n * For every attribute, a getter is generated, which retrieve the model property from `this.attributes`.\n * And a setter, which sets the model property in `this.attributes` and emits `change` and `change:attribute` events.\n * @module\n * @param {object} attrs Object containing model attributes to extend `this.attributes`. Getters and setters are generated for `this.attributtes`, in order to emit `change` events.\n * @example\n * // Todo model\n * class TodoModel extends Rasti.Model {\n * toggle() {\n * // Set completed property. This will call a setter that will set `completed` \n * // in this.attributes, and emit `change` and `change:completed` events.\n * this.completed = !this.completed; \n * }\n * }\n * // Todo model has `title` and `completed` default attributes. `defaults` will extend `this.attributes`. Getters and setters are generated for `this.attributtes`, in order to emit `change` events.\n * TodoModel.prototype.defaults = {\n * title : '',\n * completed : false\n * };\n * // Create todo. Pass `title` attribute as argument.\n * const todo = new TodoModel({ title : 'Learn Rasti' });\n * // Listen to `change:completed` event.\n * todo.on('change:completed', () => console.log('Completed:', todo.completed));\n * // Complete todo.\n * todo.toggle(); // Completed: true\n */\nvar Model = /*#__PURE__*/function (_Emitter) {\n _inheritsLoose(Model, _Emitter);\n function Model() {\n var _this;\n var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n _this = _Emitter.call(this) || this;\n // Call preinitialize.\n _this.preinitialize.apply(_assertThisInitialized(_this), arguments);\n // attributes object.\n _this.attributes = Object.assign({}, _this.defaults || {}, attrs);\n // Previous attributes.\n _this.previous = {};\n // Generate getters/setters for every attr.\n Object.keys(_this.attributes).forEach(_this.defineAttribute.bind(_assertThisInitialized(_this)));\n return _this;\n }\n\n /**\n * If you define a preinitialize method, it will be invoked when the Model is first created, before any instantiation logic is run for the Model.\n * @param {object} attrs Object containing model attributes to extend `this.attributes`.\n */\n var _proto = Model.prototype;\n _proto.preinitialize = function preinitialize() {}\n\n /**\n * Generate getter/setter for the given key. In order to emit `change` events.\n * This method is called internally by the constructor\n * for `this.attributes`.\n * @param {string} key Attribute key.\n */;\n _proto.defineAttribute = function defineAttribute(key) {\n var _this2 = this;\n Object.defineProperty(this, key, {\n get: function get() {\n return _this2.get(key);\n },\n set: function set(value) {\n _this2.set(key, value);\n }\n });\n }\n\n /**\n * Get an attribute from `this.attributes`.\n * This method is called internally by generated getters.\n * @param {string} key Attribute key.\n * @return {any} The attribute value.\n */;\n _proto.get = function get(key) {\n return this.attributes[key];\n }\n\n /**\n * Set an attribute into `this.attributes`.\n * Emit `change` and `change:attribute` if value change.\n * Could be called in two forms, `this.set('key', value)` and\n * `this.set({ key : value })`.\n * This method is called internally by generated setters.\n * @param {string} key Attribute key or object containing keys/values.\n * @param [value] Attribute value.\n * @return {this} This model.\n * @emits change\n * @emits change:attribute\n */;\n _proto.set = function set(key, value) {\n var _ref,\n _this3 = this;\n var attrs = typeof key === 'object' ? key : (_ref = {}, _ref[key] = value, _ref);\n Object.keys(attrs).forEach(function (key) {\n var changed = key in _this3.attributes && attrs[key] !== _this3.attributes[key];\n _this3.previous[key] = _this3.attributes[key];\n _this3.attributes[key] = attrs[key];\n // Emit change events.\n if (changed) {\n _this3.emit('change', _this3, key, attrs[key]);\n _this3.emit(\"change:\" + key, _this3, attrs[key]);\n }\n });\n return this;\n }\n\n /**\n * Return object representation of the model to be used for JSON serialization.\n * By default returns `this.attributes`.\n * @return {object} Object representation of the model to be used for JSON serialization.\n */;\n _proto.toJSON = function toJSON() {\n return this.attributes;\n };\n return Model;\n}(_Emitter2[\"default\"]);\nexports[\"default\"] = Model;\n\n//# sourceURL=webpack://Rasti/./src/Model.js?");
120
40
 
121
41
  /***/ }),
122
42
 
@@ -124,11 +44,9 @@ eval("\n\nexports.__esModule = true;\n\nvar _Emitter2 = __webpack_require__(/*!
124
44
  /*!*********************!*\
125
45
  !*** ./src/View.js ***!
126
46
  \*********************/
127
- /*! no static exports found */
128
- /***/ (function(module, exports, __webpack_require__) {
47
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
129
48
 
130
- "use strict";
131
- eval("\n\nexports.__esModule = true;\n\nvar _Emitter2 = __webpack_require__(/*! ./Emitter */ \"./src/Emitter.js\");\n\nvar _Emitter3 = _interopRequireDefault(_Emitter2);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\n// This options keys will be extended on view instance.\nvar viewOptions = {\n el: true,\n tag: true,\n attributes: true,\n events: true,\n model: true,\n template: true,\n onDestroy: true\n};\n\n/**\n * - Listens for changes and renders UI.\n * - Handles user input and interactivity.\n * - Sends captured input to the model.\n *\n * A View is an atomic chunk of user interface. It often renders the data from a specific model, \n * or number of models, but views can also be data-less chunks of UI that stand alone.<br /> \n * Models must be unaware of views. Instead, views listen to the model \"change\" events, \n * and react or re-render themselves appropriately.<br />\n * Views has a root element, `this.el`. That element is used for event delegation. Elements lookups are scoped to that element. And render and dom manipulations should be done inside that element. \n * If `this.el` is not present, an element will be created using `this.tag` (or `div` as default), and `this.attributes`.<br />\n * @module\n * @param {object} options Object containing options. The following keys will be merged to `this`: el, tag, attributes, events, model, template, onDestroy.\n * @property {node} el Every view has a root element, `this.el`. If not present it will be created.\n * @property {string} tag If `this.el` is not present, an element will be created using `this.tag`. Default is `div`.\n * @property {object} attributes If `this.el` is not present, an element will be created using `this.attributes`.\n * @property {object} events Object in the format `{'event selector' : 'listener\"'}`. Used to bind delegated event listeners to root element.\n * @property {object} model A `Rasti.Model` or any object containing data and business logic.\n * @property {function} template A function that receives data and returns a markup string (html for example).\n * @example\n * // Counter view.\n * class CounterView extends View {\n * constructor(options) {\n * super(options);\n * // Bind method to `this`, to be called as listener.\n * this.render = this.render.bind(this);\n * // Listen to model change and re render.\n * this.model.on('change:count', this.render);\n * }\n * onDestroy() {\n * // Unbind events when destroyed.\n * this.model.off('change:count', this.render);\n * }\n * // Listener method. Called when button is clicked.\n * onClickIncrement() {\n * // Increment count on model.\n * this.model.count++;\n * }\n * }\n * Object.assign(CounterView.prototype, {\n * // Set delegated events.\n * // Call `onClickIncrement` when button is clicked.\n * events : {\n * 'click button' : 'onClickIncrement'\n * },\n * // View's template.\n * template : (model) => `\n * <div>The count is: ${model.count}</div>\n * <button>Increment</button>\n * `\n * });\n * // Model.\n * const model = new Model({ count : 0 });\n * // Instantiate CounterView.\n * const counterView = new CounterView({ model });\n * // Add to DOM.\n * document.body.appendChild(counterView.render().el);\n */\n\nvar View = function (_Emitter) {\n _inherits(View, _Emitter);\n\n function View() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n _classCallCheck(this, View);\n\n // Call preinitialize.\n var _this = _possibleConstructorReturn(this, _Emitter.call(this));\n\n _this.preinitialize.apply(_this, arguments);\n // Generate unique id.\n // Useful to generate elements ids.\n _this.uid = 'uid' + ++View.uid;\n // Store delegated events listeners,\n // so they can be unbinded later.\n _this.delegatedEventListeners = [];\n // Store child views,\n // so they can be destroyed.\n _this.children = [];\n // Extend \"this\" with options, mapping viewOptions keys.\n Object.keys(options).forEach(function (key) {\n if (viewOptions[key]) _this[key] = options[key];\n });\n // Ensure that the view has a root element at `this.el`.\n _this.ensureElement();\n return _this;\n }\n\n /**\n * If you define a preinitialize method, it will be invoked when the view is first created, before any instantiation logic is run.\n * @param {object} attrs Object containing model attributes to extend `this.attributes`.\n */\n\n\n View.prototype.preinitialize = function preinitialize() {};\n\n /**\n * Returns the first element that match the selector, \n * scoped to DOM elements within the current view's root element (`this.el`).\n * @param {string} selector CSS selector.\n * @return {node} Element matching selector within the view's root element (`this.el`).\n */\n\n\n View.prototype.$ = function $(selector) {\n return this.el.querySelector(selector);\n };\n\n /**\n * Returns a list of elements that match the selector, \n * scoped to DOM elements within the current view's root element (`this.el`).\n * @param {string} selector CSS selector.\n * @return {node[]} List of elements matching selector within the view's root element (`this.el`).\n */\n\n\n View.prototype.$$ = function $$(selector) {\n return this.el.querySelectorAll(selector);\n };\n\n /**\n * Destroy the view.\n * Destroy children views if any, undelegate events, stop listening to events, call `onDestroy` lifecycle method.\n * Pass options.remove as true to remove the view's root element (`this.el`) from the DOM.\n * @param {object} options.remove Remove the view's root element (`this.el`) from the DOM.\n */\n\n\n View.prototype.destroy = function destroy() {\n var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n remove = _ref.remove;\n\n // Call destroy on children.\n this.destroyChildren();\n // Undelegate `this.el` event listeners\n this.undelegateEvents();\n // Unbind `this` events.\n this.off();\n // Remove `this.el` if \"options.remove\" is true.\n if (remove) this.removeElement();\n // Call onDestroy lifecycle method\n this.onDestroy();\n };\n\n /**\n * `onDestroy` lifecycle method is called after view is destroyed.\n * Override with your code. Useful to stop listening to model's events.\n */\n\n\n View.prototype.onDestroy = function onDestroy() {};\n\n /**\n * Add a view as a child.\n * Children views are stored at `this.children`, and destroyed when the parent is destroyed.\n * Returns the child for chaining.\n * @param {Rasti.View} child\n * @return {Rasti.View}\n */\n\n\n View.prototype.addChild = function addChild(child) {\n this.children.push(child);\n return child;\n };\n\n /**\n * Call destroy method on children views.\n */\n\n\n View.prototype.destroyChildren = function destroyChildren() {\n while (this.children.length) {\n this.children.shift().destroy();\n }\n };\n\n /**\n * Ensure that the view has a root element at `this.el`.\n * You shouldn't call this method directly. It's called from constructor.\n * You may override it if you want to use a different logic or to \n * postpone element creation.\n */\n\n\n View.prototype.ensureElement = function ensureElement() {\n // If \"this.el\" is not present,\n // create a new element according \"this.tag\"\n // and \"this.attributes\".\n if (!this.el) this.el = this.createElement(this.tag, this.attributes);\n // Delegate events on element.\n this.delegateEvents();\n };\n\n /**\n * Create an element.\n * Called from constructor if `this.el` is undefined, to ensure\n * the view to have a root element.\n * @param {string} tag Tag for the element. Default to `div`\n * @param {object} attrs Attributes for the element.\n * @return {node} The created element.\n */\n\n\n View.prototype.createElement = function createElement() {\n var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div';\n var attrs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n // Create dom element.\n var el = document.createElement(tag);\n // Add element attributes.\n Object.keys(attrs).forEach(function (key) {\n return el.setAttribute(key, attrs[key]);\n });\n\n return el;\n };\n\n /**\n * Remove `this.el` from DOM.\n */\n\n\n View.prototype.removeElement = function removeElement() {\n this.el.parentNode.removeChild(this.el);\n };\n\n /**\n * Provide declarative listeners for DOM events within a view. If an events hash is not passed directly, uses `this.events` as the source.<br />\n * Events are written in the format `{'event selector' : 'listener'}`. The listener may be either the name of a method on the view, or a direct function body.\n * Omitting the selector causes the event to be bound to the view's root element (`this.el`).<br />\n * By default, `delegateEvents` is called within the View's constructor, \n * so if you have a simple events hash, all of your DOM events will always already be connected, and you will never have to call this function yourself. <br />\n * All attached listeners are bound to the view automatically, so when the listeners are invoked, `this` continues to refer to the view object.<br />\n * When `delegateEvents` is run again, perhaps with a different events hash, all listeners are removed and delegated afresh.\n * @param {object} [events] Object in the format `{'event selector' : 'listener'}`. Used to bind delegated event listeners to root element.\n * @return {Rasti.View} Return `this` for chaining.\n * @example\n * MyView.prototype.events = {\n * 'click button.ok' : 'onClickOkButton',\n * 'click button.cancel' : function() {}\n * };\n */\n\n\n View.prototype.delegateEvents = function delegateEvents() {\n var _this2 = this;\n\n var events = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.events;\n\n if (!events) return this;\n\n if (this.delegatedEventListeners.length) this.undelegateEvents();\n\n // Store events by type i.e.: \"click\", \"submit\", etc.\n var eventTypes = {};\n\n Object.keys(events).forEach(function (key) {\n var keyParts = key.split(' '),\n type = keyParts.shift(),\n selector = keyParts.join(' '),\n listener = events[key];\n\n listener = (typeof listener === 'string' ? _this2[listener] : listener).bind(_this2);\n\n if (!eventTypes[type]) eventTypes[type] = [];\n\n eventTypes[type].push({ selector: selector, listener: listener });\n });\n\n var indexOf = Array.prototype.indexOf;\n\n Object.keys(eventTypes).forEach(function (type) {\n var self = _this2;\n var typeListener = function typeListener(event) {\n eventTypes[type].forEach(function (_ref2) {\n var selector = _ref2.selector,\n listener = _ref2.listener;\n\n if (!selector && self.el === event.target || indexOf.call(self.el.querySelectorAll(selector), event.target) > -1) {\n listener(event, self);\n }\n });\n };\n\n _this2.delegatedEventListeners.push({ type: type, listener: typeListener });\n _this2.el.addEventListener(type, typeListener);\n });\n\n return this;\n };\n\n /**\n * Removes all of the view's delegated events. Useful if you want to disable or remove a view from the DOM temporarily. Called automatically when the view is destroyed.\n * @return {Rasti.View} Return `this` for chaining.\n */\n\n\n View.prototype.undelegateEvents = function undelegateEvents() {\n var _this3 = this;\n\n this.delegatedEventListeners.forEach(function (_ref3) {\n var type = _ref3.type,\n listener = _ref3.listener;\n\n _this3.el.removeEventListener(type, listener);\n });\n\n this.delegatedEventListeners = [];\n\n return this;\n };\n\n /**\n * Render the view.\n * This method should be overridden with custom logic.\n * The default implementation sets innerHTML of `this.el` with `this.template`.\n * Conventions are to only manipulate the dom in the scope of `this.el`, \n * and to return `this` for chaining.\n * If you added any child view, you must call `this.destroyChildren`.\n * @return {Rasti.View} Return `this` for chaining.\n */\n\n\n View.prototype.render = function render() {\n if (this.template) this.el.innerHTML = this.template(this.model);\n return this;\n };\n\n return View;\n}(_Emitter3['default']);\n\n/*\n * Unique Id\n */\n\n\nexports['default'] = View;\nView.uid = 0;\n\n//# sourceURL=webpack://Rasti/./src/View.js?");
49
+ eval("\n\nexports.__esModule = true;\nexports[\"default\"] = void 0;\nvar _Emitter2 = _interopRequireDefault(__webpack_require__(/*! ./Emitter */ \"./src/Emitter.js\"));\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; }\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n// This options keys will be extended on view instance.\nvar viewOptions = {\n el: true,\n tag: true,\n attributes: true,\n events: true,\n model: true,\n template: true,\n onDestroy: true\n};\n\n/**\n * - Listens for changes and renders UI.\n * - Handles user input and interactivity.\n * - Sends captured input to the model.\n *\n * A View is an atomic chunk of user interface. It often renders the data from a specific model, \n * or number of models, but views can also be data-less chunks of UI that stand alone.<br /> \n * Models must be unaware of views. Instead, views listen to the model \"change\" events, \n * and react or re-render themselves appropriately.<br />\n * Views has a root element, `this.el`. That element is used for event delegation. Elements lookups are scoped to that element. And render and dom manipulations should be done inside that element. \n * If `this.el` is not present, an element will be created using `this.tag` (or `div` as default), and `this.attributes`.<br />\n * @module\n * @param {object} options Object containing options. The following keys will be merged to `this`: el, tag, attributes, events, model, template, onDestroy.\n * @property {node} el Every view has a root element, `this.el`. If not present it will be created.\n * @property {string} tag If `this.el` is not present, an element will be created using `this.tag`. Default is `div`.\n * @property {object} attributes If `this.el` is not present, an element will be created using `this.attributes`.\n * @property {object} events Object in the format `{'event selector' : 'listener'}`. Used to bind delegated event listeners to root element.\n * @property {object} model A `Rasti.Model` or any object containing data and business logic.\n * @property {function} template A function that receives data and returns a markup string (html for example).\n * @example\n * // Counter view.\n * class CounterView extends View {\n * constructor(options) {\n * super(options);\n * // Bind method to `this`, to be called as listener.\n * this.render = this.render.bind(this);\n * // Listen to model change and re render.\n * this.model.on('change:count', this.render);\n * }\n * onDestroy() {\n * // Unbind events when destroyed.\n * this.model.off('change:count', this.render);\n * }\n * // Listener method. Called when button is clicked.\n * onClickIncrement() {\n * // Increment count on model.\n * this.model.count++;\n * }\n * }\n * Object.assign(CounterView.prototype, {\n * // Set delegated events.\n * // Call `onClickIncrement` when button is clicked.\n * events : {\n * 'click button' : 'onClickIncrement'\n * },\n * // View's template.\n * template : (model) => `\n * <div>The count is: ${model.count}</div>\n * <button>Increment</button>\n * `\n * });\n * // Model.\n * const model = new Model({ count : 0 });\n * // Instantiate CounterView.\n * const counterView = new CounterView({ model });\n * // Add to DOM.\n * document.body.appendChild(counterView.render().el);\n */\nvar View = /*#__PURE__*/function (_Emitter) {\n _inheritsLoose(View, _Emitter);\n function View() {\n var _this;\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n _this = _Emitter.call(this) || this;\n // Call preinitialize.\n _this.preinitialize.apply(_assertThisInitialized(_this), arguments);\n // Generate unique id.\n // Useful to generate elements ids.\n _this.uid = \"uid\" + ++View.uid;\n // Store delegated events listeners,\n // so they can be unbinded later.\n _this.delegatedEventListeners = [];\n // Store child views,\n // so they can be destroyed.\n _this.children = [];\n // Extend \"this\" with options, mapping viewOptions keys.\n Object.keys(options).forEach(function (key) {\n if (viewOptions[key]) _this[key] = options[key];\n });\n // Ensure that the view has a root element at `this.el`.\n _this.ensureElement();\n return _this;\n }\n\n /**\n * If you define a preinitialize method, it will be invoked when the view is first created, before any instantiation logic is run.\n * @param {object} attrs Object containing model attributes to extend `this.attributes`.\n */\n var _proto = View.prototype;\n _proto.preinitialize = function preinitialize() {}\n\n /**\n * Returns the first element that match the selector, \n * scoped to DOM elements within the current view's root element (`this.el`).\n * @param {string} selector CSS selector.\n * @return {node} Element matching selector within the view's root element (`this.el`).\n */;\n _proto.$ = function $(selector) {\n return this.el.querySelector(selector);\n }\n\n /**\n * Returns a list of elements that match the selector, \n * scoped to DOM elements within the current view's root element (`this.el`).\n * @param {string} selector CSS selector.\n * @return {node[]} List of elements matching selector within the view's root element (`this.el`).\n */;\n _proto.$$ = function $$(selector) {\n return this.el.querySelectorAll(selector);\n }\n\n /**\n * Destroy the view.\n * Destroy children views if any, undelegate events, stop listening to events, call `onDestroy` lifecycle method.\n * Pass options.remove as true to remove the view's root element (`this.el`) from the DOM.\n * @param {object} options.remove Remove the view's root element (`this.el`) from the DOM.\n */;\n _proto.destroy = function destroy() {\n var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},\n remove = _ref.remove;\n // Call destroy on children.\n this.destroyChildren();\n // Undelegate `this.el` event listeners\n this.undelegateEvents();\n // Unbind `this` events.\n this.off();\n // Remove `this.el` if \"options.remove\" is true.\n if (remove) this.removeElement();\n // Call onDestroy lifecycle method\n this.onDestroy();\n }\n\n /**\n * `onDestroy` lifecycle method is called after view is destroyed.\n * Override with your code. Useful to stop listening to model's events.\n */;\n _proto.onDestroy = function onDestroy() {}\n\n /**\n * Add a view as a child.\n * Children views are stored at `this.children`, and destroyed when the parent is destroyed.\n * Returns the child for chaining.\n * @param {Rasti.View} child\n * @return {Rasti.View}\n */;\n _proto.addChild = function addChild(child) {\n this.children.push(child);\n return child;\n }\n\n /**\n * Call destroy method on children views.\n */;\n _proto.destroyChildren = function destroyChildren() {\n while (this.children.length) this.children.shift().destroy();\n }\n\n /**\n * Ensure that the view has a root element at `this.el`.\n * You shouldn't call this method directly. It's called from constructor.\n * You may override it if you want to use a different logic or to \n * postpone element creation.\n */;\n _proto.ensureElement = function ensureElement() {\n // If \"this.el\" is not present,\n // create a new element according \"this.tag\"\n // and \"this.attributes\".\n if (!this.el) this.el = this.createElement(this.tag, this.attributes);\n // Delegate events on element.\n this.delegateEvents();\n }\n\n /**\n * Create an element.\n * Called from constructor if `this.el` is undefined, to ensure\n * the view to have a root element.\n * @param {string} tag Tag for the element. Default to `div`\n * @param {object} attrs Attributes for the element.\n * @return {node} The created element.\n */;\n _proto.createElement = function createElement() {\n var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'div';\n var attrs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n // Create dom element.\n var el = document.createElement(tag);\n // Add element attributes.\n Object.keys(attrs).forEach(function (key) {\n return el.setAttribute(key, attrs[key]);\n });\n return el;\n }\n\n /**\n * Remove `this.el` from DOM.\n */;\n _proto.removeElement = function removeElement() {\n this.el.parentNode.removeChild(this.el);\n }\n\n /**\n * Provide declarative listeners for DOM events within a view. If an events hash is not passed directly, uses `this.events` as the source.<br />\n * Events are written in the format `{'event selector' : 'listener'}`. The listener may be either the name of a method on the view, or a direct function body.\n * Omitting the selector causes the event to be bound to the view's root element (`this.el`).<br />\n * By default, `delegateEvents` is called within the View's constructor, \n * so if you have a simple events hash, all of your DOM events will always already be connected, and you will never have to call this function yourself. <br />\n * All attached listeners are bound to the view automatically, so when the listeners are invoked, `this` continues to refer to the view object.<br />\n * When `delegateEvents` is run again, perhaps with a different events hash, all listeners are removed and delegated afresh.\n * @param {object} [events] Object in the format `{'event selector' : 'listener'}`. Used to bind delegated event listeners to root element.\n * @return {Rasti.View} Return `this` for chaining.\n * @example\n * MyView.prototype.events = {\n * 'click button.ok' : 'onClickOkButton',\n * 'click button.cancel' : function() {}\n * };\n */;\n _proto.delegateEvents = function delegateEvents() {\n var _this2 = this;\n var events = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.events;\n if (!events) return this;\n if (this.delegatedEventListeners.length) this.undelegateEvents();\n\n // Store events by type i.e.: \"click\", \"submit\", etc.\n var eventTypes = {};\n Object.keys(events).forEach(function (key) {\n var keyParts = key.split(' '),\n type = keyParts.shift(),\n selector = keyParts.join(' '),\n listener = events[key];\n listener = (typeof listener === 'string' ? _this2[listener] : listener).bind(_this2);\n if (!eventTypes[type]) eventTypes[type] = [];\n eventTypes[type].push({\n selector: selector,\n listener: listener\n });\n });\n var indexOf = Array.prototype.indexOf;\n Object.keys(eventTypes).forEach(function (type) {\n var self = _this2;\n var typeListener = function typeListener(event) {\n eventTypes[type].forEach(function (_ref2) {\n var selector = _ref2.selector,\n listener = _ref2.listener;\n if (indexOf.call(selector ? self.el.querySelectorAll(selector) : [self.el], event.target) > -1) {\n listener(event, self);\n }\n });\n };\n _this2.delegatedEventListeners.push({\n type: type,\n listener: typeListener\n });\n _this2.el.addEventListener(type, typeListener);\n });\n return this;\n }\n\n /**\n * Removes all of the view's delegated events. Useful if you want to disable or remove a view from the DOM temporarily. Called automatically when the view is destroyed.\n * @return {Rasti.View} Return `this` for chaining.\n */;\n _proto.undelegateEvents = function undelegateEvents() {\n var _this3 = this;\n this.delegatedEventListeners.forEach(function (_ref3) {\n var type = _ref3.type,\n listener = _ref3.listener;\n _this3.el.removeEventListener(type, listener);\n });\n this.delegatedEventListeners = [];\n return this;\n }\n\n /**\n * Render the view.\n * This method should be overridden with custom logic.\n * The default implementation sets innerHTML of `this.el` with `this.template`.\n * Conventions are to only manipulate the dom in the scope of `this.el`, \n * and to return `this` for chaining.\n * If you added any child view, you must call `this.destroyChildren`.\n * @return {Rasti.View} Return `this` for chaining.\n */;\n _proto.render = function render() {\n if (this.template) this.el.innerHTML = this.template(this.model);\n return this;\n };\n return View;\n}(_Emitter2[\"default\"]);\n/*\n * Unique Id\n */\nexports[\"default\"] = View;\nView.uid = 0;\n\n//# sourceURL=webpack://Rasti/./src/View.js?");
132
50
 
133
51
  /***/ }),
134
52
 
@@ -136,24 +54,46 @@ eval("\n\nexports.__esModule = true;\n\nvar _Emitter2 = __webpack_require__(/*!
136
54
  /*!**********************!*\
137
55
  !*** ./src/index.js ***!
138
56
  \**********************/
139
- /*! no static exports found */
140
- /***/ (function(module, exports, __webpack_require__) {
57
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
141
58
 
142
- "use strict";
143
- eval("\n\nexports.__esModule = true;\nexports.View = exports.Model = exports.Emitter = undefined;\n\nvar _Emitter = __webpack_require__(/*! ./Emitter */ \"./src/Emitter.js\");\n\nvar _Emitter2 = _interopRequireDefault(_Emitter);\n\nvar _Model = __webpack_require__(/*! ./Model */ \"./src/Model.js\");\n\nvar _Model2 = _interopRequireDefault(_Model);\n\nvar _View = __webpack_require__(/*! ./View */ \"./src/View.js\");\n\nvar _View2 = _interopRequireDefault(_View);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nexports.Emitter = _Emitter2['default'];\nexports.Model = _Model2['default'];\nexports.View = _View2['default'];\n\n//# sourceURL=webpack://Rasti/./src/index.js?");
144
-
145
- /***/ }),
146
-
147
- /***/ 0:
148
- /*!*************************!*\
149
- !*** multi ./src/index ***!
150
- \*************************/
151
- /*! no static exports found */
152
- /***/ (function(module, exports, __webpack_require__) {
153
-
154
- eval("module.exports = __webpack_require__(/*! ./src/index */\"./src/index.js\");\n\n\n//# sourceURL=webpack://Rasti/multi_./src/index?");
59
+ eval("\n\nexports.__esModule = true;\nvar _Emitter = _interopRequireDefault(__webpack_require__(/*! ./Emitter */ \"./src/Emitter.js\"));\nexports.Emitter = _Emitter[\"default\"];\nvar _Model = _interopRequireDefault(__webpack_require__(/*! ./Model */ \"./src/Model.js\"));\nexports.Model = _Model[\"default\"];\nvar _View = _interopRequireDefault(__webpack_require__(/*! ./View */ \"./src/View.js\"));\nexports.View = _View[\"default\"];\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; }\n\n//# sourceURL=webpack://Rasti/./src/index.js?");
155
60
 
156
61
  /***/ })
157
62
 
158
- /******/ });
63
+ /******/ });
64
+ /************************************************************************/
65
+ /******/ // The module cache
66
+ /******/ var __webpack_module_cache__ = {};
67
+ /******/
68
+ /******/ // The require function
69
+ /******/ function __webpack_require__(moduleId) {
70
+ /******/ // Check if module is in cache
71
+ /******/ var cachedModule = __webpack_module_cache__[moduleId];
72
+ /******/ if (cachedModule !== undefined) {
73
+ /******/ return cachedModule.exports;
74
+ /******/ }
75
+ /******/ // Create a new module (and put it into the cache)
76
+ /******/ var module = __webpack_module_cache__[moduleId] = {
77
+ /******/ // no module.id needed
78
+ /******/ // no module.loaded needed
79
+ /******/ exports: {}
80
+ /******/ };
81
+ /******/
82
+ /******/ // Execute the module function
83
+ /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
84
+ /******/
85
+ /******/ // Return the exports of the module
86
+ /******/ return module.exports;
87
+ /******/ }
88
+ /******/
89
+ /************************************************************************/
90
+ /******/
91
+ /******/ // startup
92
+ /******/ // Load entry module and return exports
93
+ /******/ // This entry module can't be inlined because the eval devtool is used.
94
+ /******/ var __webpack_exports__ = __webpack_require__("./src/index.js");
95
+ /******/
96
+ /******/ return __webpack_exports__;
97
+ /******/ })()
98
+ ;
159
99
  });
package/dist/rasti.min.js CHANGED
@@ -1 +1 @@
1
- !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Rasti=e():t.Rasti=e()}(window,(function(){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=1)}([function(t,e,n){"use strict";e.__esModule=!0;var r=function(){function t(){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t)}return t.prototype.on=function(t,e){if("function"!=typeof e)throw TypeError("Listener must be a function");this.listeners||(this.listeners={}),this.listeners[t]||(this.listeners[t]=[]),this.listeners[t].push(e)},t.prototype.once=function(t,e){if("function"==typeof e){var n=this,r=e;e=function(){r.apply(void 0,arguments),n.off(t,e)}}this.on(t,e)},t.prototype.off=function(t,e){if(t)if(e){var n=this.listeners[t];if(n)n.slice().forEach((function(t,r){t===e&&n.splice(r,1)})),n.length||delete this.listeners[t]}else delete this.listeners[t];else this.listeners={}},t.prototype.emit=function(t){for(var e=arguments.length,n=Array(e>1?e-1:0),r=1;r<e;r++)n[r-1]=arguments[r];var o=this.listeners&&this.listeners[t];if(o&&o.length){var i=o.slice();i.forEach((function(t){t.apply(void 0,n)}))}},t}();e.default=r},function(t,e,n){t.exports=n(2)},function(t,e,n){"use strict";e.__esModule=!0,e.View=e.Model=e.Emitter=void 0;var r=s(n(0)),o=s(n(3)),i=s(n(4));function s(t){return t&&t.__esModule?t:{default:t}}e.Emitter=r.default,e.Model=o.default,e.View=i.default},function(t,e,n){"use strict";e.__esModule=!0;var r,o=n(0);function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function s(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}var u=function(t){function e(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};i(this,e);var r=s(this,t.call(this));return r.preinitialize.apply(r,arguments),r.attributes=Object.assign({},r.defaults||{},n),r.previous={},Object.keys(r.attributes).forEach(r.defineAttribute.bind(r)),r}return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}(e,t),e.prototype.preinitialize=function(){},e.prototype.defineAttribute=function(t){var e=this;Object.defineProperty(this,t,{get:function(){return e.get(t)},set:function(n){return e.set(t,n)}})},e.prototype.get=function(t){return this.attributes[t]},e.prototype.set=function(t,e){var n,r=this,o="object"==typeof t?t:((n={})[t]=e,n);return Object.keys(o).forEach((function(t){var e=t in r.attributes&&o[t]!==r.attributes[t];r.previous[t]=r.attributes[t],r.attributes[t]=o[t],e&&(r.emit("change",r,t,o[t]),r.emit("change:"+t,r,o[t]))})),this},e.prototype.toJSON=function(){return this.attributes},e}(((r=o)&&r.__esModule?r:{default:r}).default);e.default=u},function(t,e,n){"use strict";e.__esModule=!0;var r,o=n(0),i=(r=o)&&r.__esModule?r:{default:r};function s(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function u(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}var l={el:!0,tag:!0,attributes:!0,events:!0,model:!0,template:!0,onDestroy:!0},f=function(t){function e(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};s(this,e);var r=u(this,t.call(this));return r.preinitialize.apply(r,arguments),r.uid="uid"+ ++e.uid,r.delegatedEventListeners=[],r.children=[],Object.keys(n).forEach((function(t){l[t]&&(r[t]=n[t])})),r.ensureElement(),r}return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}(e,t),e.prototype.preinitialize=function(){},e.prototype.$=function(t){return this.el.querySelector(t)},e.prototype.$$=function(t){return this.el.querySelectorAll(t)},e.prototype.destroy=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.remove;this.destroyChildren(),this.undelegateEvents(),this.off(),e&&this.removeElement(),this.onDestroy()},e.prototype.onDestroy=function(){},e.prototype.addChild=function(t){return this.children.push(t),t},e.prototype.destroyChildren=function(){for(;this.children.length;)this.children.shift().destroy()},e.prototype.ensureElement=function(){this.el||(this.el=this.createElement(this.tag,this.attributes)),this.delegateEvents()},e.prototype.createElement=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"div",e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=document.createElement(t);return Object.keys(e).forEach((function(t){return n.setAttribute(t,e[t])})),n},e.prototype.removeElement=function(){this.el.parentNode.removeChild(this.el)},e.prototype.delegateEvents=function(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.events;if(!e)return this;this.delegatedEventListeners.length&&this.undelegateEvents();var n={};Object.keys(e).forEach((function(r){var o=r.split(" "),i=o.shift(),s=o.join(" "),u=e[r];u=("string"==typeof u?t[u]:u).bind(t),n[i]||(n[i]=[]),n[i].push({selector:s,listener:u})}));var r=Array.prototype.indexOf;return Object.keys(n).forEach((function(e){var o=t,i=function(t){n[e].forEach((function(e){var n=e.selector,i=e.listener;(!n&&o.el===t.target||r.call(o.el.querySelectorAll(n),t.target)>-1)&&i(t,o)}))};t.delegatedEventListeners.push({type:e,listener:i}),t.el.addEventListener(e,i)})),this},e.prototype.undelegateEvents=function(){var t=this;return this.delegatedEventListeners.forEach((function(e){var n=e.type,r=e.listener;t.el.removeEventListener(n,r)})),this.delegatedEventListeners=[],this},e.prototype.render=function(){return this.template&&(this.el.innerHTML=this.template(this.model)),this},e}(i.default);e.default=f,f.uid=0}])}));
1
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Rasti=t():e.Rasti=t()}(self,(()=>(()=>{"use strict";var e={30:(e,t)=>{t.__esModule=!0,t.default=void 0;var n=function(){function e(){}var t=e.prototype;return t.on=function(e,t){if("function"!=typeof t)throw TypeError("Listener must be a function");this.listeners||(this.listeners={}),this.listeners[e]||(this.listeners[e]=[]),this.listeners[e].push(t)},t.once=function(e,t){if("function"==typeof t){var n=this,i=t;t=function(){i.apply(void 0,arguments),n.off(e,t)}}this.on(e,t)},t.off=function(e,t){if(e)if(t){var n=this.listeners[e];n&&(n.slice().forEach((function(e,i){e===t&&n.splice(i,1)})),n.length||delete this.listeners[e])}else delete this.listeners[e];else this.listeners={}},t.emit=function(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),i=1;i<t;i++)n[i-1]=arguments[i];var r=this.listeners&&this.listeners[e];r&&r.length&&r.slice().forEach((function(e){e.apply(void 0,n)}))},e}();t.default=n},289:(e,t,n)=>{var i;function r(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function s(e,t){return s=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},s(e,t)}t.__esModule=!0,t.default=void 0;var o=function(e){var t,n;function i(){var t,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return(t=e.call(this)||this).preinitialize.apply(r(t),arguments),t.attributes=Object.assign({},t.defaults||{},n),t.previous={},Object.keys(t.attributes).forEach(t.defineAttribute.bind(r(t))),t}n=e,(t=i).prototype=Object.create(n.prototype),t.prototype.constructor=t,s(t,n);var o=i.prototype;return o.preinitialize=function(){},o.defineAttribute=function(e){var t=this;Object.defineProperty(this,e,{get:function(){return t.get(e)},set:function(n){t.set(e,n)}})},o.get=function(e){return this.attributes[e]},o.set=function(e,t){var n,i=this,r="object"==typeof e?e:((n={})[e]=t,n);return Object.keys(r).forEach((function(e){var t=e in i.attributes&&r[e]!==i.attributes[e];i.previous[e]=i.attributes[e],i.attributes[e]=r[e],t&&(i.emit("change",i,e,r[e]),i.emit("change:"+e,i,r[e]))})),this},o.toJSON=function(){return this.attributes},i}(((i=n(30))&&i.__esModule?i:{default:i}).default);t.default=o},789:(e,t,n)=>{t.__esModule=!0,t.default=void 0;var i,r=(i=n(30))&&i.__esModule?i:{default:i};function s(e,t){return s=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},s(e,t)}var o={el:!0,tag:!0,attributes:!0,events:!0,model:!0,template:!0,onDestroy:!0},u=function(e){var t,n;function i(){var t,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return(t=e.call(this)||this).preinitialize.apply(function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(t),arguments),t.uid="uid"+ ++i.uid,t.delegatedEventListeners=[],t.children=[],Object.keys(n).forEach((function(e){o[e]&&(t[e]=n[e])})),t.ensureElement(),t}n=e,(t=i).prototype=Object.create(n.prototype),t.prototype.constructor=t,s(t,n);var r=i.prototype;return r.preinitialize=function(){},r.$=function(e){return this.el.querySelector(e)},r.$$=function(e){return this.el.querySelectorAll(e)},r.destroy=function(){var e=(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}).remove;this.destroyChildren(),this.undelegateEvents(),this.off(),e&&this.removeElement(),this.onDestroy()},r.onDestroy=function(){},r.addChild=function(e){return this.children.push(e),e},r.destroyChildren=function(){for(;this.children.length;)this.children.shift().destroy()},r.ensureElement=function(){this.el||(this.el=this.createElement(this.tag,this.attributes)),this.delegateEvents()},r.createElement=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"div",t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=document.createElement(e);return Object.keys(t).forEach((function(e){return n.setAttribute(e,t[e])})),n},r.removeElement=function(){this.el.parentNode.removeChild(this.el)},r.delegateEvents=function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.events;if(!t)return this;this.delegatedEventListeners.length&&this.undelegateEvents();var n={};Object.keys(t).forEach((function(i){var r=i.split(" "),s=r.shift(),o=r.join(" "),u=t[i];u=("string"==typeof u?e[u]:u).bind(e),n[s]||(n[s]=[]),n[s].push({selector:o,listener:u})}));var i=Array.prototype.indexOf;return Object.keys(n).forEach((function(t){var r=e,s=function(e){n[t].forEach((function(t){var n=t.selector,s=t.listener;i.call(n?r.el.querySelectorAll(n):[r.el],e.target)>-1&&s(e,r)}))};e.delegatedEventListeners.push({type:t,listener:s}),e.el.addEventListener(t,s)})),this},r.undelegateEvents=function(){var e=this;return this.delegatedEventListeners.forEach((function(t){var n=t.type,i=t.listener;e.el.removeEventListener(n,i)})),this.delegatedEventListeners=[],this},r.render=function(){return this.template&&(this.el.innerHTML=this.template(this.model)),this},i}(r.default);t.default=u,u.uid=0}},t={};function n(i){var r=t[i];if(void 0!==r)return r.exports;var s=t[i]={exports:{}};return e[i](s,s.exports,n),s.exports}var i={};return(()=>{var e=i;e.__esModule=!0;var t=o(n(30));e.Emitter=t.default;var r=o(n(289));e.Model=r.default;var s=o(n(789));function o(e){return e&&e.__esModule?e:{default:e}}e.View=s.default})(),i})()));
package/es/Emitter.js CHANGED
@@ -1,5 +1,3 @@
1
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2
-
3
1
  /**
4
2
  * Emitter is a class that can be extended giving the subclass the ability to emit
5
3
  * and bind custom named events. Model and View inherits from it.
@@ -19,109 +17,90 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
19
17
  * // Add event listener to ready event.
20
18
  * app.on('ready', () => console.log('app is ready!'));
21
19
  */
22
- var Emitter = function () {
23
- function Emitter() {
24
- _classCallCheck(this, Emitter);
20
+ var Emitter = /*#__PURE__*/function () {
21
+ function Emitter() {}
22
+ var _proto = Emitter.prototype;
23
+ /**
24
+ * Adds event listener.
25
+ * @param {string} type Type of the event (e.g. `change`).
26
+ * @param {function} listener Callback function to be called when the event is emitted.
27
+ * @example
28
+ * this.model.on('change', this.render.bind(this)); // Re render when model changes.
29
+ */
30
+ _proto.on = function on(type, listener) {
31
+ if (typeof listener !== 'function') {
32
+ throw TypeError('Listener must be a function');
25
33
  }
26
-
27
- /**
28
- * Adds event listener.
29
- * @param {string} type Type of the event (e.g. `change`).
30
- * @param {function} listener Callback function to be called when the event is emitted.
31
- * @example
32
- * this.model.on('change', this.render.bind(this)); // Re render when model changes.
33
- */
34
- Emitter.prototype.on = function on(type, listener) {
35
- if (typeof listener !== 'function') {
36
- throw TypeError('Listener must be a function');
37
- }
38
-
39
- if (!this.listeners) this.listeners = {};
40
- if (!this.listeners[type]) this.listeners[type] = [];
41
-
42
- this.listeners[type].push(listener);
43
- };
44
-
45
- /**
46
- * Adds event listener that executes once.
47
- * @param {string} type Type of the event (e.g. `change`).
48
- * @param {function} listener Callback function to be called when the event is emitted.
49
- * @example
50
- * this.model.once('change', () => console.log('This will happen once'));
51
- */
52
-
53
-
54
- Emitter.prototype.once = function once(type, _listener2) {
55
- if (typeof _listener2 === 'function') {
56
- var self = this;
57
- var _listener = _listener2;
58
-
59
- _listener2 = function listener() {
60
- _listener.apply(undefined, arguments);
61
- self.off(type, _listener2);
62
- };
63
- }
64
- this.on(type, _listener2);
65
- };
66
-
67
- /**
68
- * Removes event listeners.
69
- * @param {string} [type] Type of the event (e.g. `change`). If is not provided, it removes all listeners.
70
- * @param {function} [listener] Callback function to be called when the event is emitted. If listener is not provided, it removes all listeners for specified type.
71
- * @example
72
- * this.model.off('change'); // Stop listening to changes.
73
- */
74
-
75
-
76
- Emitter.prototype.off = function off(type, listener) {
77
- if (!type) {
78
- this.listeners = {};
79
- } else {
80
- if (!listener) {
81
- delete this.listeners[type];
82
- } else {
83
- var listeners = this.listeners[type];
84
- if (listeners) {
85
- var copy = listeners.slice();
86
-
87
- copy.forEach(function (fn, idx) {
88
- if (fn === listener) listeners.splice(idx, 1);
89
- });
90
-
91
- if (!listeners.length) {
92
- delete this.listeners[type];
93
- }
94
- }
95
- }
96
- }
97
- };
98
-
99
- /**
100
- * Emits event of specified type. Listeners will receive specified arguments.
101
- * @param {string} type Type of the event (e.g. `change`).
102
- * @param {any} [...args] Arguments to be passed to listener.
103
- * @example
104
- * this.emit('invalid'); // Emit validation error event.
105
- */
106
-
107
-
108
- Emitter.prototype.emit = function emit(type) {
109
- for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
110
- args[_key - 1] = arguments[_key];
34
+ if (!this.listeners) this.listeners = {};
35
+ if (!this.listeners[type]) this.listeners[type] = [];
36
+ this.listeners[type].push(listener);
37
+ }
38
+
39
+ /**
40
+ * Adds event listener that executes once.
41
+ * @param {string} type Type of the event (e.g. `change`).
42
+ * @param {function} listener Callback function to be called when the event is emitted.
43
+ * @example
44
+ * this.model.once('change', () => console.log('This will happen once'));
45
+ */;
46
+ _proto.once = function once(type, _listener2) {
47
+ if (typeof _listener2 === 'function') {
48
+ var self = this;
49
+ var _listener = _listener2;
50
+ _listener2 = function listener() {
51
+ _listener.apply(void 0, arguments);
52
+ self.off(type, _listener2);
53
+ };
54
+ }
55
+ this.on(type, _listener2);
56
+ }
57
+
58
+ /**
59
+ * Removes event listeners.
60
+ * @param {string} [type] Type of the event (e.g. `change`). If is not provided, it removes all listeners.
61
+ * @param {function} [listener] Callback function to be called when the event is emitted. If listener is not provided, it removes all listeners for specified type.
62
+ * @example
63
+ * this.model.off('change'); // Stop listening to changes.
64
+ */;
65
+ _proto.off = function off(type, listener) {
66
+ if (!type) {
67
+ this.listeners = {};
68
+ } else {
69
+ if (!listener) {
70
+ delete this.listeners[type];
71
+ } else {
72
+ var listeners = this.listeners[type];
73
+ if (listeners) {
74
+ var copy = listeners.slice();
75
+ copy.forEach(function (fn, idx) {
76
+ if (fn === listener) listeners.splice(idx, 1);
77
+ });
78
+ if (!listeners.length) {
79
+ delete this.listeners[type];
80
+ }
111
81
  }
112
-
113
- var listeners = this.listeners && this.listeners[type];
114
-
115
- if (!listeners || !listeners.length) return;
116
-
117
- var copy = listeners.slice();
118
-
119
- copy.forEach(function (fn) {
120
- fn.apply(undefined, args);
121
- });
122
- };
123
-
124
- return Emitter;
82
+ }
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Emits event of specified type. Listeners will receive specified arguments.
88
+ * @param {string} type Type of the event (e.g. `change`).
89
+ * @param {any} [...args] Arguments to be passed to listener.
90
+ * @example
91
+ * this.emit('invalid'); // Emit validation error event.
92
+ */;
93
+ _proto.emit = function emit(type) {
94
+ for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
95
+ args[_key - 1] = arguments[_key];
96
+ }
97
+ var listeners = this.listeners && this.listeners[type];
98
+ if (!listeners || !listeners.length) return;
99
+ var copy = listeners.slice();
100
+ copy.forEach(function (fn) {
101
+ fn.apply(void 0, args);
102
+ });
103
+ };
104
+ return Emitter;
125
105
  }();
126
-
127
- export default Emitter;
106
+ export { Emitter as default };