rasti 2.0.0-alpha.8 → 2.0.0
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/README.md +25 -14
- package/dist/rasti.js +4 -4
- package/dist/rasti.min.js +1 -1
- package/es/Component.js +61 -51
- package/es/Emitter.js +2 -2
- package/es/Model.js +60 -21
- package/es/View.js +13 -10
- package/lib/Component.js +62 -53
- package/lib/Emitter.js +4 -5
- package/lib/Model.js +62 -24
- package/lib/View.js +14 -12
- package/package.json +34 -34
- package/src/Component.js +63 -50
- package/src/Emitter.js +2 -2
- package/src/Model.js +55 -17
- package/src/View.js +11 -7
package/lib/Component.js
CHANGED
|
@@ -4,7 +4,6 @@ exports.__esModule = true;
|
|
|
4
4
|
exports["default"] = void 0;
|
|
5
5
|
var _View2 = _interopRequireDefault(require("./View.js"));
|
|
6
6
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
7
|
-
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
|
8
7
|
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
|
|
9
8
|
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
|
10
9
|
// This options keys will be extended on view instance.
|
|
@@ -51,9 +50,9 @@ var evalExpression = function evalExpression(expression, context) {
|
|
|
51
50
|
|
|
52
51
|
/**
|
|
53
52
|
* Components are a special kind of `View` that is designed to be easily composable,
|
|
54
|
-
* making it simple to add child views and build complex user interfaces
|
|
53
|
+
* making it simple to add child views and build complex user interfaces.
|
|
55
54
|
* Unlike views, which are render-agnostic, components have a specific set of rendering
|
|
56
|
-
* guidelines that allow for a more declarative development style
|
|
55
|
+
* guidelines that allow for a more declarative development style.
|
|
57
56
|
* Components are defined with the `create` static method, which takes a tagged template.
|
|
58
57
|
* @module
|
|
59
58
|
* @extends Rasti.View
|
|
@@ -76,32 +75,25 @@ var evalExpression = function evalExpression(expression, context) {
|
|
|
76
75
|
* // Increment `model.seconds` every second.
|
|
77
76
|
* setInterval(() => model.seconds++, 1000);
|
|
78
77
|
*/
|
|
79
|
-
var Component = /*#__PURE__*/function (_View) {
|
|
80
|
-
_inheritsLoose(Component, _View);
|
|
78
|
+
var Component = exports["default"] = /*#__PURE__*/function (_View) {
|
|
81
79
|
function Component() {
|
|
82
80
|
var _this;
|
|
83
81
|
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
84
|
-
_this = _View.
|
|
82
|
+
_this = _View.apply(this, arguments) || this;
|
|
85
83
|
// Extend "this" with options, mapping componentOptions keys.
|
|
86
84
|
Object.keys(options).forEach(function (key) {
|
|
87
85
|
if (componentOptions[key]) _this[key] = options[key];
|
|
88
86
|
});
|
|
89
87
|
// Store options by default.
|
|
90
88
|
_this.options = options;
|
|
91
|
-
// Ensure id.
|
|
92
|
-
_this.id = _this.attributes.id ?
|
|
93
|
-
// If id is provided, evaluate it.
|
|
94
|
-
evalExpression(_this.attributes.id, _assertThisInitialized(_this), _assertThisInitialized(_this)) :
|
|
95
|
-
// Generate a unique id and set it as id attribute.
|
|
96
|
-
Component.ID_TEMPLATE(_this.uid);
|
|
97
89
|
// Bind onChange to this to be used as listener.
|
|
98
90
|
// Store bound version, so it can be removed on onDestroy method.
|
|
99
|
-
_this.onChange = _this.onChange.bind(
|
|
91
|
+
_this.onChange = _this.onChange.bind(_this);
|
|
100
92
|
// Listen to model changes and call onChange.
|
|
101
|
-
if (_this.model) _this.model.on('change', _this.onChange);
|
|
102
|
-
if (_this.state) _this.state.on('change', _this.onChange);
|
|
93
|
+
if (_this.model && _this.model.on) _this.model.on('change', _this.onChange);
|
|
94
|
+
if (_this.state && _this.state.on) _this.state.on('change', _this.onChange);
|
|
103
95
|
// Call life cycle method.
|
|
104
|
-
_this.onCreate.apply(
|
|
96
|
+
_this.onCreate.apply(_this, arguments);
|
|
105
97
|
return _this;
|
|
106
98
|
}
|
|
107
99
|
|
|
@@ -109,10 +101,22 @@ var Component = /*#__PURE__*/function (_View) {
|
|
|
109
101
|
* Override. We don't want to ensure an element on instantiation.
|
|
110
102
|
* We will provide it later.
|
|
111
103
|
*/
|
|
104
|
+
_inheritsLoose(Component, _View);
|
|
112
105
|
var _proto = Component.prototype;
|
|
113
106
|
_proto.ensureElement = function ensureElement() {
|
|
114
107
|
// If el is provided, delegate events.
|
|
115
|
-
if (this.el)
|
|
108
|
+
if (this.el) {
|
|
109
|
+
this.delegateEvents();
|
|
110
|
+
this.id = this.el.id;
|
|
111
|
+
}
|
|
112
|
+
// Ensure id.
|
|
113
|
+
if (!this.id) {
|
|
114
|
+
this.id = this.attributes && this.attributes.id ?
|
|
115
|
+
// If id is provided, evaluate it.
|
|
116
|
+
evalExpression(this.attributes.id, this, this) :
|
|
117
|
+
// Generate a unique id and set it as id attribute.
|
|
118
|
+
Component.ID_TEMPLATE(this.uid);
|
|
119
|
+
}
|
|
116
120
|
}
|
|
117
121
|
|
|
118
122
|
/*
|
|
@@ -127,32 +131,34 @@ var Component = /*#__PURE__*/function (_View) {
|
|
|
127
131
|
*/;
|
|
128
132
|
_proto.getAttributes = function getAttributes() {
|
|
129
133
|
var _this2 = this;
|
|
130
|
-
var add = {
|
|
134
|
+
var add = {
|
|
135
|
+
id: this.id
|
|
136
|
+
};
|
|
131
137
|
var remove = {};
|
|
132
|
-
var
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
138
|
+
var html = ["id=\"" + this.id + "\""];
|
|
139
|
+
if (this.attributes) {
|
|
140
|
+
Object.keys(this.attributes).forEach(function (key) {
|
|
141
|
+
if (key === 'id') return;
|
|
142
|
+
// Evaluate attribute value.
|
|
143
|
+
var value = evalExpression(_this2.attributes[key], _this2, _this2);
|
|
137
144
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
attrs.push("id=\"" + this.id + "\"");
|
|
145
|
+
// Transform bool attribute values
|
|
146
|
+
if (value === false) {
|
|
147
|
+
remove[key] = true;
|
|
148
|
+
} else if (value === true) {
|
|
149
|
+
add[key] = '';
|
|
150
|
+
html.push(key);
|
|
151
|
+
} else {
|
|
152
|
+
if (value === null || typeof value === 'undefined') value = '';
|
|
153
|
+
add[key] = value;
|
|
154
|
+
html.push(key + "=\"" + value + "\"");
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
152
158
|
return {
|
|
153
159
|
add: add,
|
|
154
160
|
remove: remove,
|
|
155
|
-
html:
|
|
161
|
+
html: html.join(' ')
|
|
156
162
|
};
|
|
157
163
|
}
|
|
158
164
|
|
|
@@ -190,8 +196,8 @@ var Component = /*#__PURE__*/function (_View) {
|
|
|
190
196
|
_View.prototype.destroy.apply(this, arguments);
|
|
191
197
|
// Stop listening to `change`.
|
|
192
198
|
// Set destroyed flag to prevent a last render after destroyed. TODO: Review
|
|
193
|
-
if (this.model) this.model.off('change', this.onChange);
|
|
194
|
-
if (this.state) this.state.off('change', this.onChange);
|
|
199
|
+
if (this.model && this.model.off) this.model.off('change', this.onChange);
|
|
200
|
+
if (this.state && this.state.off) this.state.off('change', this.onChange);
|
|
195
201
|
this.destroyed = true;
|
|
196
202
|
}
|
|
197
203
|
|
|
@@ -208,8 +214,8 @@ var Component = /*#__PURE__*/function (_View) {
|
|
|
208
214
|
* Maybe comparing new attributes with previous ones and calling
|
|
209
215
|
* render when needed. Or doing some dom transformation.
|
|
210
216
|
* @param model {Rasti.Model} The model that emitted the event.
|
|
211
|
-
* @param
|
|
212
|
-
* @param
|
|
217
|
+
* @param changed {object} Object containing keys and values that has changed.
|
|
218
|
+
* @param [...args] {any} Any extra arguments passed to set method.
|
|
213
219
|
*/;
|
|
214
220
|
_proto.onChange = function onChange() {
|
|
215
221
|
this.render();
|
|
@@ -270,13 +276,17 @@ var Component = /*#__PURE__*/function (_View) {
|
|
|
270
276
|
var _this5 = this;
|
|
271
277
|
// Normally there won't be any children, but if there are, destroy them.
|
|
272
278
|
this.destroyChildren();
|
|
273
|
-
//
|
|
274
|
-
var
|
|
279
|
+
// Get tag name.
|
|
280
|
+
var tag = this.tag || 'div';
|
|
281
|
+
// Get attributes.
|
|
282
|
+
var attributes = this.getAttributes().html;
|
|
283
|
+
// Replace expressions of inner template.
|
|
284
|
+
var inner = this.template && this.template.inner && this.replaceExpressions(this.template.inner, function (component) {
|
|
275
285
|
// Add child component.
|
|
276
286
|
return _this5.addChild(component);
|
|
277
287
|
});
|
|
278
288
|
// Generate outer template.
|
|
279
|
-
return inner ? "<" +
|
|
289
|
+
return inner ? "<" + tag + " " + attributes + ">" + inner + "</" + tag + ">" : "<" + tag + " " + attributes + " />";
|
|
280
290
|
}
|
|
281
291
|
|
|
282
292
|
/*
|
|
@@ -302,7 +312,7 @@ var Component = /*#__PURE__*/function (_View) {
|
|
|
302
312
|
_this6.el.setAttribute(key, attributes.add[key]);
|
|
303
313
|
});
|
|
304
314
|
// Check for `template.inner` to see if view has innerHTML.
|
|
305
|
-
if (this.template.inner) {
|
|
315
|
+
if (this.template && this.template.inner) {
|
|
306
316
|
var previousChildren = this.children;
|
|
307
317
|
this.children = [];
|
|
308
318
|
var nextChildren = [];
|
|
@@ -317,8 +327,10 @@ var Component = /*#__PURE__*/function (_View) {
|
|
|
317
327
|
return previousChild.key === component.key;
|
|
318
328
|
});
|
|
319
329
|
if (found) {
|
|
330
|
+
var tag = found.el.tagName.toLowerCase();
|
|
331
|
+
var id = found.el.id;
|
|
320
332
|
// If child already exists, replace it html by its root element.
|
|
321
|
-
out = "<" +
|
|
333
|
+
out = "<" + tag + " id=\"" + id + "\"></" + tag + ">";
|
|
322
334
|
// Add child to recycled children.
|
|
323
335
|
recycledChildren.push(found);
|
|
324
336
|
// Destroy new child component. Use recycled one instead.
|
|
@@ -362,10 +374,10 @@ var Component = /*#__PURE__*/function (_View) {
|
|
|
362
374
|
Component.extend = function extend(object) {
|
|
363
375
|
var Current = this;
|
|
364
376
|
var Extended = /*#__PURE__*/function (_Current) {
|
|
365
|
-
_inheritsLoose(Extended, _Current);
|
|
366
377
|
function Extended() {
|
|
367
378
|
return _Current.apply(this, arguments) || this;
|
|
368
379
|
}
|
|
380
|
+
_inheritsLoose(Extended, _Current);
|
|
369
381
|
return Extended;
|
|
370
382
|
}(Current);
|
|
371
383
|
Object.assign(Extended.prototype, typeof object === 'function' ? object(Current.prototype) : object);
|
|
@@ -383,10 +395,7 @@ var Component = /*#__PURE__*/function (_View) {
|
|
|
383
395
|
* @param {boolean} hydrate If true, the view will use existing html.
|
|
384
396
|
* @return {Rasti.Component}
|
|
385
397
|
*/;
|
|
386
|
-
Component.mount = function mount() {
|
|
387
|
-
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
388
|
-
var el = arguments.length > 1 ? arguments[1] : undefined;
|
|
389
|
-
var hydrate = arguments.length > 2 ? arguments[2] : undefined;
|
|
398
|
+
Component.mount = function mount(options, el, hydrate) {
|
|
390
399
|
// Instantiate view.
|
|
391
400
|
var view = new this(options);
|
|
392
401
|
// If `el` is passed, mount component.
|
|
@@ -405,6 +414,7 @@ var Component = /*#__PURE__*/function (_View) {
|
|
|
405
414
|
// Return view instance.
|
|
406
415
|
return view;
|
|
407
416
|
}
|
|
417
|
+
|
|
408
418
|
/**
|
|
409
419
|
* Takes a tagged template containing an HTML string,
|
|
410
420
|
* and returns a new `Component` class.
|
|
@@ -483,7 +493,6 @@ var Component = /*#__PURE__*/function (_View) {
|
|
|
483
493
|
};
|
|
484
494
|
return Component;
|
|
485
495
|
}(_View2["default"]);
|
|
486
|
-
exports["default"] = Component;
|
|
487
496
|
Component.ID_TEMPLATE = function (uid) {
|
|
488
497
|
return "rasti-component-" + uid;
|
|
489
498
|
};
|
package/lib/Emitter.js
CHANGED
|
@@ -4,8 +4,8 @@ exports.__esModule = true;
|
|
|
4
4
|
exports["default"] = void 0;
|
|
5
5
|
/**
|
|
6
6
|
* `Emitter` is a class that provides an easy way to implement the observer pattern
|
|
7
|
-
* in your applications
|
|
8
|
-
* It can be extended to create new classes that have the ability to emit and bind custom named events
|
|
7
|
+
* in your applications.
|
|
8
|
+
* It can be extended to create new classes that have the ability to emit and bind custom named events.
|
|
9
9
|
* Emitter is used by `Model` and `View` classes, which inherit from it to implement
|
|
10
10
|
* event-driven functionality.
|
|
11
11
|
*
|
|
@@ -39,7 +39,7 @@ exports["default"] = void 0;
|
|
|
39
39
|
* cart.addItem(item1); // Output: "Item added to cart: Smartphone - Price: $1000"
|
|
40
40
|
* cart.addItem(item2); // Output: "Item added to cart: Headphones - Price: $150"
|
|
41
41
|
*/
|
|
42
|
-
var Emitter = /*#__PURE__*/function () {
|
|
42
|
+
var Emitter = exports["default"] = /*#__PURE__*/function () {
|
|
43
43
|
function Emitter() {}
|
|
44
44
|
var _proto = Emitter.prototype;
|
|
45
45
|
/**
|
|
@@ -124,5 +124,4 @@ var Emitter = /*#__PURE__*/function () {
|
|
|
124
124
|
});
|
|
125
125
|
};
|
|
126
126
|
return Emitter;
|
|
127
|
-
}();
|
|
128
|
-
exports["default"] = Emitter;
|
|
127
|
+
}();
|
package/lib/Model.js
CHANGED
|
@@ -4,17 +4,16 @@ exports.__esModule = true;
|
|
|
4
4
|
exports["default"] = void 0;
|
|
5
5
|
var _Emitter2 = _interopRequireDefault(require("./Emitter.js"));
|
|
6
6
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
7
|
-
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
|
8
7
|
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
|
|
9
8
|
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
|
10
9
|
/**
|
|
11
10
|
* - Orchestrates data and business logic.
|
|
12
11
|
* - Emits events when data changes.
|
|
13
12
|
*
|
|
14
|
-
* A `Model` manages an internal table of data attributes and triggers change events when any of its data is modified
|
|
13
|
+
* A `Model` manages an internal table of data attributes and triggers change events when any of its data is modified.
|
|
15
14
|
* Models may handle syncing data with a persistence layer. To design your models, create atomic, reusable objects
|
|
16
|
-
* that contain all the necessary functions for manipulating their specific data
|
|
17
|
-
* Models should be easily passed throughout your app and used anywhere the corresponding data is needed
|
|
15
|
+
* that contain all the necessary functions for manipulating their specific data.
|
|
16
|
+
* Models should be easily passed throughout your app and used anywhere the corresponding data is needed.
|
|
18
17
|
* Rasti models stores its attributes in `this.attributes`, which is extended from `this.defaults` and the
|
|
19
18
|
* constructor `attrs` parameter. For every attribute, a getter is generated to retrieve the model property
|
|
20
19
|
* from `this.attributes`, and a setter is created to set the model property in `this.attributes` and emit `change`
|
|
@@ -52,20 +51,19 @@ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Objec
|
|
|
52
51
|
* // Apply a 10% discount to the product.
|
|
53
52
|
* product.setDiscount(10); // Output: "New Price: 900"
|
|
54
53
|
*/
|
|
55
|
-
var Model = /*#__PURE__*/function (_Emitter) {
|
|
56
|
-
_inheritsLoose(Model, _Emitter);
|
|
54
|
+
var Model = exports["default"] = /*#__PURE__*/function (_Emitter) {
|
|
57
55
|
function Model() {
|
|
58
56
|
var _this;
|
|
59
57
|
var attrs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
60
58
|
_this = _Emitter.call(this) || this;
|
|
61
59
|
// Call preinitialize.
|
|
62
|
-
_this.preinitialize.apply(
|
|
60
|
+
_this.preinitialize.apply(_this, arguments);
|
|
63
61
|
// attributes object.
|
|
64
62
|
_this.attributes = Object.assign({}, _this.defaults || {}, attrs);
|
|
65
63
|
// Previous attributes.
|
|
66
64
|
_this.previous = {};
|
|
67
65
|
// Generate getters/setters for every attr.
|
|
68
|
-
Object.keys(_this.attributes).forEach(_this.defineAttribute.bind(
|
|
66
|
+
Object.keys(_this.attributes).forEach(_this.defineAttribute.bind(_this));
|
|
69
67
|
return _this;
|
|
70
68
|
}
|
|
71
69
|
|
|
@@ -73,6 +71,7 @@ var Model = /*#__PURE__*/function (_Emitter) {
|
|
|
73
71
|
* 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.
|
|
74
72
|
* @param {object} attrs Object containing model attributes to extend `this.attributes`.
|
|
75
73
|
*/
|
|
74
|
+
_inheritsLoose(Model, _Emitter);
|
|
76
75
|
var _proto = Model.prototype;
|
|
77
76
|
_proto.preinitialize = function preinitialize() {}
|
|
78
77
|
|
|
@@ -105,11 +104,13 @@ var Model = /*#__PURE__*/function (_Emitter) {
|
|
|
105
104
|
}
|
|
106
105
|
|
|
107
106
|
/**
|
|
108
|
-
* Set an attribute into `this.attributes`.
|
|
109
|
-
* Emit `change` and `change:attribute` if value change.
|
|
107
|
+
* Set an attribute into `this.attributes`.
|
|
108
|
+
* Emit `change` and `change:attribute` if a value change.
|
|
110
109
|
* Could be called in two forms, `this.set('key', value)` and
|
|
111
|
-
* `this.set({ key : value })`.
|
|
112
|
-
* This method is called internally by generated setters.
|
|
110
|
+
* `this.set({ key : value })`.
|
|
111
|
+
* This method is called internally by generated setters.
|
|
112
|
+
* The `change` event listener will receive the model instance, an object containing the changed attributes, and the rest of the arguments passed to `set` method.
|
|
113
|
+
* The `change:attribute` event listener will receive the model instance, the new attribute value, and the rest of the arguments passed to `set` method.
|
|
113
114
|
* @param {string} key Attribute key or object containing keys/values.
|
|
114
115
|
* @param [value] Attribute value.
|
|
115
116
|
* @return {this} This model.
|
|
@@ -117,19 +118,57 @@ var Model = /*#__PURE__*/function (_Emitter) {
|
|
|
117
118
|
* @emits change:attribute
|
|
118
119
|
*/;
|
|
119
120
|
_proto.set = function set(key, value) {
|
|
120
|
-
var
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
var _this3 = this;
|
|
122
|
+
var attrs, args;
|
|
123
|
+
// Handle both `"key", value` and `{key: value}` style arguments.
|
|
124
|
+
for (var _len = arguments.length, rest = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
|
|
125
|
+
rest[_key - 2] = arguments[_key];
|
|
126
|
+
}
|
|
127
|
+
if (typeof key === 'object') {
|
|
128
|
+
attrs = key;
|
|
129
|
+
args = [value].concat(rest);
|
|
130
|
+
} else {
|
|
131
|
+
var _attrs;
|
|
132
|
+
attrs = (_attrs = {}, _attrs[key] = value, _attrs);
|
|
133
|
+
args = rest;
|
|
134
|
+
}
|
|
135
|
+
// Are we in a nested `set` call?
|
|
136
|
+
// Calling a `set` inside a `change:attribute` or `change` event listener
|
|
137
|
+
var changing = this._changing;
|
|
138
|
+
this._changing = true;
|
|
139
|
+
// Store changed attributes.
|
|
140
|
+
var changed = {};
|
|
141
|
+
// Store previous attributes.
|
|
142
|
+
if (!changing) {
|
|
143
|
+
this.previous = Object.assign({}, this.attributes);
|
|
144
|
+
}
|
|
145
|
+
// Set attributes.
|
|
123
146
|
Object.keys(attrs).forEach(function (key) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if (changed) {
|
|
129
|
-
_this3.emit('change', _this3, key, attrs[key]);
|
|
130
|
-
_this3.emit("change:" + key, _this3, attrs[key]);
|
|
147
|
+
// Use equality to determine if value changed.
|
|
148
|
+
if (attrs[key] !== _this3.attributes[key]) {
|
|
149
|
+
changed[key] = attrs[key];
|
|
150
|
+
_this3.attributes[key] = attrs[key];
|
|
131
151
|
}
|
|
132
152
|
});
|
|
153
|
+
var changedKeys = Object.keys(changed);
|
|
154
|
+
// Pending `change` event arguments.
|
|
155
|
+
if (changedKeys.length) this._pending = ['change', this, changed].concat(args);
|
|
156
|
+
// Emit `change:attribute` events.
|
|
157
|
+
changedKeys.forEach(function (key) {
|
|
158
|
+
_this3.emit.apply(_this3, ["change:" + key, _this3, attrs[key]].concat(args));
|
|
159
|
+
});
|
|
160
|
+
// Don't emit `change` event until the end of the nested
|
|
161
|
+
// `set` calls inside `change:attribute` event listeners.
|
|
162
|
+
if (changing) return this;
|
|
163
|
+
// Emit `change` events, that might be nested.
|
|
164
|
+
while (this._pending) {
|
|
165
|
+
var pendingChange = this._pending;
|
|
166
|
+
this._pending = null;
|
|
167
|
+
this.emit.apply(this, pendingChange);
|
|
168
|
+
}
|
|
169
|
+
// Reset flags.
|
|
170
|
+
this._pending = null;
|
|
171
|
+
this._changing = false;
|
|
133
172
|
return this;
|
|
134
173
|
}
|
|
135
174
|
|
|
@@ -142,5 +181,4 @@ var Model = /*#__PURE__*/function (_Emitter) {
|
|
|
142
181
|
return this.attributes;
|
|
143
182
|
};
|
|
144
183
|
return Model;
|
|
145
|
-
}(_Emitter2["default"]);
|
|
146
|
-
exports["default"] = Model;
|
|
184
|
+
}(_Emitter2["default"]);
|
package/lib/View.js
CHANGED
|
@@ -4,7 +4,6 @@ exports.__esModule = true;
|
|
|
4
4
|
exports["default"] = void 0;
|
|
5
5
|
var _Emitter2 = _interopRequireDefault(require("./Emitter.js"));
|
|
6
6
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
7
|
-
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
|
8
7
|
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
|
|
9
8
|
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
|
10
9
|
// This options keys will be extended on view instance.
|
|
@@ -24,10 +23,10 @@ var viewOptions = {
|
|
|
24
23
|
* - Sends captured input to the model.
|
|
25
24
|
*
|
|
26
25
|
* A `View` is an atomic unit of the user interface that can render the data from a specific model or multiple models.
|
|
27
|
-
* However, views can also be independent and have no associated data
|
|
26
|
+
* However, views can also be independent and have no associated data.
|
|
28
27
|
* Models must be unaware of views. Views, on the other hand, may render model data and listen to the change events
|
|
29
|
-
* emitted by the models to re-render themselves based on changes
|
|
30
|
-
* Each `View` has a root element, `this.el`, which is used for event delegation
|
|
28
|
+
* emitted by the models to re-render themselves based on changes.
|
|
29
|
+
* Each `View` has a root element, `this.el`, which is used for event delegation.
|
|
31
30
|
* All element lookups are scoped to this element, and any rendering or DOM manipulations should be done inside it.
|
|
32
31
|
* If `this.el` is not present, an element will be created using `this.tag` (defaulting to div) and `this.attributes`.
|
|
33
32
|
* @module
|
|
@@ -60,14 +59,13 @@ var viewOptions = {
|
|
|
60
59
|
* // Render view and append view's element into body.
|
|
61
60
|
* document.body.appendChild(new Timer().render().el);
|
|
62
61
|
*/
|
|
63
|
-
var View = /*#__PURE__*/function (_Emitter) {
|
|
64
|
-
_inheritsLoose(View, _Emitter);
|
|
62
|
+
var View = exports["default"] = /*#__PURE__*/function (_Emitter) {
|
|
65
63
|
function View() {
|
|
66
64
|
var _this;
|
|
67
65
|
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
68
66
|
_this = _Emitter.call(this) || this;
|
|
69
67
|
// Call preinitialize.
|
|
70
|
-
_this.preinitialize.apply(
|
|
68
|
+
_this.preinitialize.apply(_this, arguments);
|
|
71
69
|
// Generate unique id.
|
|
72
70
|
// Useful to generate elements ids.
|
|
73
71
|
_this.uid = "uid" + ++View.uid;
|
|
@@ -90,6 +88,7 @@ var View = /*#__PURE__*/function (_Emitter) {
|
|
|
90
88
|
* If you define a preinitialize method, it will be invoked when the view is first created, before any instantiation logic is run.
|
|
91
89
|
* @param {object} attrs Object containing model attributes to extend `this.attributes`.
|
|
92
90
|
*/
|
|
91
|
+
_inheritsLoose(View, _Emitter);
|
|
93
92
|
var _proto = View.prototype;
|
|
94
93
|
_proto.preinitialize = function preinitialize() {}
|
|
95
94
|
|
|
@@ -116,6 +115,7 @@ var View = /*#__PURE__*/function (_Emitter) {
|
|
|
116
115
|
/**
|
|
117
116
|
* Destroy the view.
|
|
118
117
|
* Destroy children views if any, undelegate events, stop listening to events, call `onDestroy` lifecycle method.
|
|
118
|
+
* @return {Rasti.View} Return `this` for chaining.
|
|
119
119
|
*/;
|
|
120
120
|
_proto.destroy = function destroy() {
|
|
121
121
|
// Call destroy on children.
|
|
@@ -193,18 +193,21 @@ var View = /*#__PURE__*/function (_Emitter) {
|
|
|
193
193
|
|
|
194
194
|
/**
|
|
195
195
|
* Remove `this.el` from DOM.
|
|
196
|
+
* @return {Rasti.View} Return `this` for chaining.
|
|
196
197
|
*/;
|
|
197
198
|
_proto.removeElement = function removeElement() {
|
|
198
199
|
this.el.parentNode.removeChild(this.el);
|
|
200
|
+
// Return `this` for chaining.
|
|
201
|
+
return this;
|
|
199
202
|
}
|
|
200
203
|
|
|
201
204
|
/**
|
|
202
|
-
* Provide declarative listeners for DOM events within a view. If an events hash is not passed directly, uses `this.events` as the source
|
|
205
|
+
* Provide declarative listeners for DOM events within a view. If an events hash is not passed directly, uses `this.events` as the source.
|
|
203
206
|
* 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.
|
|
204
|
-
* Omitting the selector causes the event to be bound to the view's root element (`this.el`)
|
|
207
|
+
* Omitting the selector causes the event to be bound to the view's root element (`this.el`).
|
|
205
208
|
* By default, `delegateEvents` is called within the View's constructor,
|
|
206
|
-
* 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.
|
|
207
|
-
* All attached listeners are bound to the view automatically, so when the listeners are invoked, `this` continues to refer to the view object
|
|
209
|
+
* 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.
|
|
210
|
+
* All attached listeners are bound to the view automatically, so when the listeners are invoked, `this` continues to refer to the view object.
|
|
208
211
|
* When `delegateEvents` is run again, perhaps with a different events hash, all listeners are removed and delegated afresh.
|
|
209
212
|
* @param {object} [events] Object in the format `{'event selector' : 'listener'}`. Used to bind delegated event listeners to root element.
|
|
210
213
|
* @return {Rasti.View} Return `this` for chaining.
|
|
@@ -291,5 +294,4 @@ var View = /*#__PURE__*/function (_Emitter) {
|
|
|
291
294
|
/*
|
|
292
295
|
* Unique Id
|
|
293
296
|
*/
|
|
294
|
-
exports["default"] = View;
|
|
295
297
|
View.uid = 0;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rasti",
|
|
3
|
-
"version": "2.0.0
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Rasti is a minimalistic JavaScript library for building user interfaces.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"jsnext:main": "es/index.js",
|
|
7
7
|
"files": [
|
|
@@ -39,39 +39,39 @@
|
|
|
39
39
|
"author": "Alberto Masuelli <alberto.masuelli@gmail.com> (https://github.com/8tentaculos)",
|
|
40
40
|
"license": "MIT",
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@babel/cli": "^7.
|
|
43
|
-
"@babel/core": "^7.
|
|
44
|
-
"@babel/eslint-parser": "^7.
|
|
45
|
-
"@babel/plugin-transform-arrow-functions": "^7.
|
|
46
|
-
"@babel/plugin-transform-block-scoped-functions": "^7.
|
|
47
|
-
"@babel/plugin-transform-block-scoping": "^7.
|
|
48
|
-
"@babel/plugin-transform-classes": "^7.
|
|
49
|
-
"@babel/plugin-transform-computed-properties": "^7.
|
|
50
|
-
"@babel/plugin-transform-destructuring": "^7.
|
|
51
|
-
"@babel/plugin-transform-for-of": "^7.
|
|
52
|
-
"@babel/plugin-transform-function-name": "^7.
|
|
53
|
-
"@babel/plugin-transform-literals": "^7.
|
|
54
|
-
"@babel/plugin-transform-member-expression-literals": "^7.
|
|
55
|
-
"@babel/plugin-transform-modules-commonjs": "^7.
|
|
56
|
-
"@babel/plugin-transform-object-super": "^7.
|
|
57
|
-
"@babel/plugin-transform-parameters": "^7.
|
|
58
|
-
"@babel/plugin-transform-property-literals": "^7.
|
|
59
|
-
"@babel/plugin-transform-shorthand-properties": "^7.
|
|
60
|
-
"@babel/plugin-transform-spread": "^7.
|
|
61
|
-
"@babel/plugin-transform-sticky-regex": "^7.
|
|
62
|
-
"@babel/plugin-transform-template-literals": "^7.
|
|
63
|
-
"@babel/plugin-transform-unicode-regex": "^7.
|
|
64
|
-
"@babel/register": "^7.
|
|
65
|
-
"babel-loader": "^9.1.
|
|
66
|
-
"chai": "^4.
|
|
67
|
-
"cross-env": "^
|
|
68
|
-
"eslint": "^8.
|
|
69
|
-
"jsdoc-to-markdown": "^8.0.
|
|
70
|
-
"jsdom": "^
|
|
42
|
+
"@babel/cli": "^7.24.1",
|
|
43
|
+
"@babel/core": "^7.24.3",
|
|
44
|
+
"@babel/eslint-parser": "^7.24.1",
|
|
45
|
+
"@babel/plugin-transform-arrow-functions": "^7.24.1",
|
|
46
|
+
"@babel/plugin-transform-block-scoped-functions": "^7.24.1",
|
|
47
|
+
"@babel/plugin-transform-block-scoping": "^7.24.1",
|
|
48
|
+
"@babel/plugin-transform-classes": "^7.24.1",
|
|
49
|
+
"@babel/plugin-transform-computed-properties": "^7.24.1",
|
|
50
|
+
"@babel/plugin-transform-destructuring": "^7.24.1",
|
|
51
|
+
"@babel/plugin-transform-for-of": "^7.24.1",
|
|
52
|
+
"@babel/plugin-transform-function-name": "^7.24.1",
|
|
53
|
+
"@babel/plugin-transform-literals": "^7.24.1",
|
|
54
|
+
"@babel/plugin-transform-member-expression-literals": "^7.24.1",
|
|
55
|
+
"@babel/plugin-transform-modules-commonjs": "^7.24.1",
|
|
56
|
+
"@babel/plugin-transform-object-super": "^7.24.1",
|
|
57
|
+
"@babel/plugin-transform-parameters": "^7.24.1",
|
|
58
|
+
"@babel/plugin-transform-property-literals": "^7.24.1",
|
|
59
|
+
"@babel/plugin-transform-shorthand-properties": "^7.24.1",
|
|
60
|
+
"@babel/plugin-transform-spread": "^7.24.1",
|
|
61
|
+
"@babel/plugin-transform-sticky-regex": "^7.24.1",
|
|
62
|
+
"@babel/plugin-transform-template-literals": "^7.24.1",
|
|
63
|
+
"@babel/plugin-transform-unicode-regex": "^7.24.1",
|
|
64
|
+
"@babel/register": "^7.23.7",
|
|
65
|
+
"babel-loader": "^9.1.3",
|
|
66
|
+
"chai": "^4.4.1",
|
|
67
|
+
"cross-env": "^7.0.3",
|
|
68
|
+
"eslint": "^8.57.0",
|
|
69
|
+
"jsdoc-to-markdown": "^8.0.1",
|
|
70
|
+
"jsdom": "^24.0.0",
|
|
71
71
|
"jsdom-global": "3.0.2",
|
|
72
|
-
"mocha": "^10.
|
|
73
|
-
"rimraf": "^5.0.
|
|
74
|
-
"webpack": "^5.
|
|
72
|
+
"mocha": "^10.4.0",
|
|
73
|
+
"rimraf": "^5.0.5",
|
|
74
|
+
"webpack": "^5.91.0",
|
|
75
75
|
"webpack-cli": "^5.1.4"
|
|
76
76
|
},
|
|
77
77
|
"directories": {
|