@base-framework/base 2.6.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.
Files changed (57) hide show
  1. package/.jshintrc +3 -0
  2. package/base.js +41 -0
  3. package/core.js +1 -0
  4. package/data-tracker.js +351 -0
  5. package/events.js +602 -0
  6. package/main.js +1331 -0
  7. package/modules/ajax/ajax.js +514 -0
  8. package/modules/animation/animation.js +236 -0
  9. package/modules/animations/animation-controller.js +231 -0
  10. package/modules/animations/animation.js +64 -0
  11. package/modules/animations/attr-movement.js +66 -0
  12. package/modules/animations/css-movement.js +170 -0
  13. package/modules/animations/movement.js +131 -0
  14. package/modules/animations/value.js +187 -0
  15. package/modules/atom/atom.js +54 -0
  16. package/modules/component/component.js +230 -0
  17. package/modules/component/event-helper.js +119 -0
  18. package/modules/component/jot.js +144 -0
  19. package/modules/component/state-helper.js +262 -0
  20. package/modules/component/unit.js +551 -0
  21. package/modules/data/attrs.js +40 -0
  22. package/modules/data/basic-data.js +500 -0
  23. package/modules/data/data-utils.js +29 -0
  24. package/modules/data/data.js +3 -0
  25. package/modules/data/deep-data.js +541 -0
  26. package/modules/data/model-service.js +528 -0
  27. package/modules/data/model.js +133 -0
  28. package/modules/data/simple-data.js +33 -0
  29. package/modules/data-binder/connection-tracker.js +113 -0
  30. package/modules/data-binder/connection.js +16 -0
  31. package/modules/data-binder/data-binder.js +352 -0
  32. package/modules/data-binder/data-pub-sub.js +141 -0
  33. package/modules/data-binder/data-source.js +56 -0
  34. package/modules/data-binder/element-source.js +219 -0
  35. package/modules/data-binder/one-way-connection.js +46 -0
  36. package/modules/data-binder/one-way-source.js +43 -0
  37. package/modules/data-binder/source.js +36 -0
  38. package/modules/data-binder/two-way-connection.js +75 -0
  39. package/modules/data-binder/two-way-source.js +41 -0
  40. package/modules/date/date.js +544 -0
  41. package/modules/history/history.js +89 -0
  42. package/modules/html-builder/html-builder.js +434 -0
  43. package/modules/import/import.js +390 -0
  44. package/modules/layout/layout-builder.js +1269 -0
  45. package/modules/layout/layout-parser.js +134 -0
  46. package/modules/layout/watcher-helper.js +282 -0
  47. package/modules/mouse/mouse.js +114 -0
  48. package/modules/router/component-helper.js +163 -0
  49. package/modules/router/history-controller.js +216 -0
  50. package/modules/router/nav-link.js +124 -0
  51. package/modules/router/route.js +401 -0
  52. package/modules/router/router.js +789 -0
  53. package/modules/router/utils.js +31 -0
  54. package/modules/state/state-target.js +91 -0
  55. package/modules/state/state.js +171 -0
  56. package/package.json +23 -0
  57. package/shared/objects.js +99 -0
@@ -0,0 +1,541 @@
1
+ import {BasicData} from './basic-data.js';
2
+ import {cloneObject} from './attrs.js';
3
+ import {DataUtils as utils} from './data-utils.js';
4
+ import {dataBinder} from '../data-binder/data-binder.js';
5
+
6
+ /**
7
+ * Data
8
+ *
9
+ * This will create a new data object that can be used to
10
+ * bind elements to values.
11
+ * @class
12
+ * @augments BasicData
13
+ */
14
+ export class Data extends BasicData
15
+ {
16
+ /**
17
+ * This will setup the stage and attributes object.
18
+ */
19
+ setup()
20
+ {
21
+ this.attributes = {};
22
+ this.stage = {};
23
+ }
24
+
25
+ /**
26
+ * This will update an attribute value.
27
+ *
28
+ * @protected
29
+ * @param {object} obj
30
+ * @param {string} attr
31
+ * @param {*} val
32
+ */
33
+ _updateAttr(obj, attr, val)
34
+ {
35
+ /* this will check if we need to update
36
+ deep nested data */
37
+ if(utils.hasDeepData(attr))
38
+ {
39
+ let prop,
40
+ props = utils.getSegments(attr),
41
+ length = props.length,
42
+ end = length - 1;
43
+
44
+ for (var i = 0; i < length; i++)
45
+ {
46
+ prop = props[i];
47
+
48
+ /* this will add the value to the last prop */
49
+ if(i === end)
50
+ {
51
+ obj[prop] = val;
52
+ break;
53
+ }
54
+
55
+ if (obj[prop] === undefined)
56
+ {
57
+ /* this will check to setup a new object
58
+ or an array if the prop is a number */
59
+ obj[prop] = isNaN(prop)? {} : [];
60
+ }
61
+ obj = obj[prop];
62
+ }
63
+ }
64
+ else
65
+ {
66
+ obj[attr] = val;
67
+ }
68
+ }
69
+
70
+ /**
71
+ * This will set the attribute value.
72
+ *
73
+ * @protected
74
+ * @param {string} attr
75
+ * @param {*} val
76
+ * @param {object} committer
77
+ * @param {boolean} stopMerge
78
+ */
79
+ _setAttr(attr, val, committer, stopMerge)
80
+ {
81
+ if(typeof val !== 'object' && val === this.get(attr))
82
+ {
83
+ return;
84
+ }
85
+
86
+ /* this will check to update the model based on who
87
+ updated it. if the data binder updated the data only
88
+ the stage data is updated */
89
+ if(!committer && stopMerge !== true)
90
+ {
91
+ /* this will update the attribute data because
92
+ it was updated outside the data binder */
93
+ this._updateAttr(this.attributes, attr, val);
94
+ }
95
+ else
96
+ {
97
+ if(this.dirty === false)
98
+ {
99
+ this.dirty = true;
100
+ }
101
+ }
102
+
103
+ this._updateAttr(this.stage, attr, val);
104
+
105
+ /* this will publish the data to the data binder
106
+ to update any ui elements that are subscribed */
107
+ committer = committer || this;
108
+ this._publish(attr, val, committer);
109
+ }
110
+
111
+ /**
112
+ * This will link a data attr object to another data object.
113
+ *
114
+ * @param {object} data
115
+ * @param {string} attr
116
+ */
117
+ linkAttr(data, attr)
118
+ {
119
+ let value = data.get(attr);
120
+ if(value)
121
+ {
122
+ for(var prop in value)
123
+ {
124
+ if(value.hasOwnProperty(prop))
125
+ {
126
+ this.link(data, attr + '.' + prop, prop);
127
+ }
128
+ }
129
+ }
130
+ }
131
+
132
+ /**
133
+ * This will create a new data source by scoping the parent
134
+ * data attr and linking the two sources.
135
+ *
136
+ * @param {string} attr
137
+ * @param {object} [constructor]
138
+ * @returns {object}
139
+ */
140
+ scope(attr, constructor)
141
+ {
142
+ let value = this.get(attr);
143
+ if(!value)
144
+ {
145
+ return false;
146
+ }
147
+
148
+ constructor = constructor || this.constructor;
149
+ let data = new constructor(value);
150
+
151
+ /* this will link the new data to the parent attr */
152
+ data.linkAttr(this, attr);
153
+ return data;
154
+ }
155
+
156
+ /**
157
+ * This will splice a value from an array and set
158
+ * the result.
159
+ *
160
+ * @param {string} attr
161
+ * @param {int} index
162
+ * @return {object} this
163
+ */
164
+ splice(attr, index)
165
+ {
166
+ this.delete(attr + '[' + index + ']');
167
+ this.refresh(attr);
168
+
169
+ return this;
170
+ }
171
+
172
+ /**
173
+ * This will add a value to an array and set the result.
174
+ *
175
+ * @param {string} attr
176
+ * @param {mixed} value
177
+ * @return {object} this
178
+ */
179
+ push(attr, value)
180
+ {
181
+ let currentValue = this.get(attr);
182
+ if(Array.isArray(currentValue) === false)
183
+ {
184
+ currentValue = [];
185
+ }
186
+
187
+ currentValue.push(value);
188
+ this.set(attr, currentValue);
189
+ return this;
190
+ }
191
+
192
+ /**
193
+ * This will add a value to an array and set the result.
194
+ *
195
+ * @param {string} attr
196
+ * @param {mixed} value
197
+ * @return {object} this
198
+ */
199
+ unshift(attr, value)
200
+ {
201
+ let currentValue = this.get(attr);
202
+ if(Array.isArray(currentValue) === false)
203
+ {
204
+ currentValue = [];
205
+ }
206
+
207
+ currentValue.unshift(value);
208
+ this.set(attr, currentValue);
209
+ return this;
210
+ }
211
+
212
+ /**
213
+ * This will add a value to an array and set the result.
214
+ *
215
+ * @param {string} attr
216
+ * @return {mixed} this
217
+ */
218
+ shift(attr)
219
+ {
220
+ let currentValue = this.get(attr);
221
+ if(Array.isArray(currentValue) === false)
222
+ {
223
+ return null;
224
+ }
225
+
226
+ let value = currentValue.shift();
227
+ this.set(attr, currentValue);
228
+ return value;
229
+ }
230
+
231
+ /**
232
+ * This will pop the last value from an array and set the result.
233
+ *
234
+ * @param {string} attr
235
+ * @return {mixed}
236
+ */
237
+ pop(attr)
238
+ {
239
+ let currentValue = this.get(attr);
240
+ if(Array.isArray(currentValue) === false)
241
+ {
242
+ return null;
243
+ }
244
+
245
+ let value = currentValue.pop();
246
+ this.set(attr, currentValue);
247
+ return value;
248
+ }
249
+
250
+ /**
251
+ * This will refresh the value.
252
+ *
253
+ * @param {string} attr
254
+ * @return {object} this
255
+ */
256
+ refresh(attr)
257
+ {
258
+ this.set(attr, this.get(attr));
259
+
260
+ return this;
261
+ }
262
+
263
+ /**
264
+ * This will publish an update to the data binder.
265
+ *
266
+ * @protected
267
+ * @param {string} attr
268
+ * @param {*} val
269
+ * @param {*} committer
270
+ */
271
+ _publish(attr, val, committer)
272
+ {
273
+ this.publish(attr, val, committer);
274
+ }
275
+
276
+ /**
277
+ * This will publish deep and simple data to the data binder.
278
+ *
279
+ * @protected
280
+ * @param {string} attr
281
+ * @param {*} val
282
+ * @param {object} committer
283
+ */
284
+ publishDeep(attr, val, committer)
285
+ {
286
+ if(utils.hasDeepData(attr))
287
+ {
288
+ let prop,
289
+ props = utils.getSegments(attr),
290
+ length = props.length,
291
+ end = length - 1;
292
+
293
+ /* the path is a string equivalent of the javascript dot notation path
294
+ of the object being published. */
295
+ let path = '',
296
+ obj = this.stage;
297
+ for (var i = 0; i < length; i++)
298
+ {
299
+ prop = props[i];
300
+
301
+ /* we need to setup the object to go to the next level
302
+ of the data object before calling the next property. */
303
+ obj = obj[prop];
304
+
305
+ if (i > 0)
306
+ {
307
+ /* this will add the property to the path based on if its an
308
+ object property or an array. */
309
+ if(isNaN(prop))
310
+ {
311
+ path += '.' + prop;
312
+ }
313
+ }
314
+ else
315
+ {
316
+ path = prop;
317
+ }
318
+
319
+ var publish;
320
+ if(i === end)
321
+ {
322
+ /* if the loop is on the last pass it only needs to publish
323
+ the val. */
324
+ publish = val;
325
+ }
326
+ else
327
+ {
328
+ /* we only want to publish the modified branches. we need to
329
+ get the next property in the props array and create a publish
330
+ object or array with the next property value. */
331
+ var nextProp = props[i + 1];
332
+ if(isNaN(nextProp) === false)
333
+ {
334
+ path += '[' + nextProp + ']';
335
+ continue;
336
+ }
337
+
338
+ var nextAttr = {};
339
+ nextAttr[nextProp] = obj[nextProp];
340
+ publish = nextAttr;
341
+ }
342
+
343
+ this.publish(path, publish, committer);
344
+ }
345
+ }
346
+ else
347
+ {
348
+ this.publish(attr, val, committer);
349
+ }
350
+ }
351
+
352
+ /**
353
+ * This will publish an update to the data binder.
354
+ *
355
+ * @protected
356
+ * @param {string} pathString
357
+ * @param {*} obj
358
+ * @param {*} committer
359
+ */
360
+ publish(pathString, obj, committer)
361
+ {
362
+ pathString = pathString || "";
363
+ this._publishAttr(pathString, obj, committer);
364
+
365
+ if(obj && typeof obj === 'object')
366
+ {
367
+ let subPath, value;
368
+ if(Array.isArray(obj))
369
+ {
370
+ let length = obj.length;
371
+ for(var i = 0; i < length; i++)
372
+ {
373
+ value = obj[i];
374
+ subPath = pathString + '[' + i + ']';
375
+ this._checkPublish(subPath, value, committer);
376
+ }
377
+ }
378
+ else
379
+ {
380
+ for(var prop in obj)
381
+ {
382
+ if(obj.hasOwnProperty(prop))
383
+ {
384
+ value = obj[prop];
385
+ subPath = pathString + '.' + prop;
386
+ this._checkPublish(subPath, value, committer);
387
+ }
388
+ }
389
+ }
390
+ }
391
+ }
392
+
393
+ _checkPublish(subPath, val, committer)
394
+ {
395
+ if(!val || typeof val !== 'object')
396
+ {
397
+ this._publishAttr(subPath, val, committer);
398
+ }
399
+ else
400
+ {
401
+ this.publish(subPath, val, committer);
402
+ }
403
+ }
404
+
405
+ /**
406
+ * This will publish an update on an attribute.
407
+ *
408
+ * @protected
409
+ * @param {string} subPath
410
+ * @param {*} val
411
+ * @param {object} committer
412
+ */
413
+ _publishAttr(subPath, val, committer)
414
+ {
415
+ /* save path and value */
416
+ dataBinder.publish(this._dataId + subPath, val, committer);
417
+
418
+ let message = subPath + ':change';
419
+ this.eventSub.publish(message, val, committer);
420
+ }
421
+
422
+ /**
423
+ * This will merge the attribute with the stage.
424
+ * @protected
425
+ */
426
+ mergeStage()
427
+ {
428
+ /* this will clone the stage object to the
429
+ attribute object */
430
+ this.attributes = cloneObject(this.stage);
431
+ this.dirty = false;
432
+ }
433
+
434
+ /**
435
+ * This will get the model data.
436
+ */
437
+ getModelData()
438
+ {
439
+ this.mergeStage();
440
+ return this.attributes;
441
+ }
442
+
443
+ /**
444
+ * This will revert the stage back to the previous attributes.
445
+ */
446
+ revert()
447
+ {
448
+ /* this will reset the stage to the previous
449
+ attributes */
450
+ this.set(this.attributes);
451
+ this.dirty = false;
452
+ }
453
+
454
+ /**
455
+ * This will delete an attribute.
456
+ *
457
+ * @param {object} obj
458
+ * @param {string} attr
459
+ * @return {*}
460
+ */
461
+ _deleteAttr(obj, attr)
462
+ {
463
+ if(utils.hasDeepData(attr))
464
+ {
465
+ let props = utils.getSegments(attr),
466
+ length = props.length,
467
+ end = length - 1;
468
+
469
+ for (var i = 0; i < length; i++)
470
+ {
471
+ var prop = props[i];
472
+ var propValue = obj[prop];
473
+ if (propValue !== undefined)
474
+ {
475
+ if(i === end)
476
+ {
477
+ if(Array.isArray(obj))
478
+ {
479
+ obj.splice(prop, 1);
480
+ break;
481
+ }
482
+
483
+ delete obj[prop];
484
+ break;
485
+ }
486
+ obj = propValue;
487
+ }
488
+ else
489
+ {
490
+ break;
491
+ }
492
+ }
493
+ }
494
+ else
495
+ {
496
+ delete obj[attr];
497
+ }
498
+ }
499
+
500
+ /**
501
+ * This will get the value of an attribute.
502
+ *
503
+ * @param {object} obj
504
+ * @param {string} attr
505
+ * @return {*}
506
+ */
507
+ _getAttr(obj, attr)
508
+ {
509
+ if(utils.hasDeepData(attr))
510
+ {
511
+ let props = utils.getSegments(attr),
512
+ length = props.length,
513
+ end = length - 1;
514
+
515
+ for (var i = 0; i < length; i++)
516
+ {
517
+ var prop = props[i];
518
+ var propValue = obj[prop];
519
+ if (propValue !== undefined)
520
+ {
521
+ obj = propValue;
522
+
523
+ if(i === end)
524
+ {
525
+ return obj;
526
+ }
527
+ }
528
+ else
529
+ {
530
+ break;
531
+ }
532
+ }
533
+
534
+ return undefined;
535
+ }
536
+ else
537
+ {
538
+ return obj[attr];
539
+ }
540
+ }
541
+ }