@base-framework/base 2.6.0 → 2.6.1

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 (190) hide show
  1. package/base.min.js +1 -0
  2. package/es5/base.js +2968 -0
  3. package/es5/modules/ajax.js +663 -0
  4. package/es5/modules/animation.js +188 -0
  5. package/es5/modules/animations.js +1080 -0
  6. package/es5/modules/atom.js +65 -0
  7. package/es5/modules/component.js +1310 -0
  8. package/es5/modules/data-binder.js +1131 -0
  9. package/es5/modules/data.js +1808 -0
  10. package/es5/modules/date.js +525 -0
  11. package/es5/modules/form-validator.js +324 -0
  12. package/es5/modules/history.js +126 -0
  13. package/es5/modules/html-builder.js +461 -0
  14. package/es5/modules/layout.js +1679 -0
  15. package/es5/modules/mouse.js +124 -0
  16. package/es5/modules/nav-link.js +123 -0
  17. package/es5/modules/olderversions/animations-ease.js +1095 -0
  18. package/es5/modules/olderversions/animations-update.js +1048 -0
  19. package/es5/modules/olderversions/base-animations.js +636 -0
  20. package/es5/modules/olderversions/base-component-class.js +100 -0
  21. package/es5/modules/olderversions/base-data-binder-1.js +407 -0
  22. package/es5/modules/olderversions/base-data-binder-class.js +358 -0
  23. package/es5/modules/olderversions/base-layout-parser-class.js +172 -0
  24. package/es5/modules/olderversions/base-mode-1.js +777 -0
  25. package/es5/modules/olderversions/base-model-class.js +585 -0
  26. package/es5/modules/olderversions/data-binder/element-binding/base-data-binder-class.js +358 -0
  27. package/es5/modules/olderversions/data-binder/element-binding/base-model-class.js +585 -0
  28. package/es5/modules/olderversions/data-binder/model-binding/base-data-binder-class.js +353 -0
  29. package/es5/modules/olderversions/data-binder/model-binding/base-model-class.js +604 -0
  30. package/es5/modules/olderversions/data-binder-update-watcher.js +640 -0
  31. package/es5/modules/olderversions/data-tracker.js +187 -0
  32. package/es5/modules/olderversions/event-update.js +666 -0
  33. package/es5/modules/olderversions/nav-link.js +119 -0
  34. package/es5/modules/olderversions/router-with-templates-1.js +785 -0
  35. package/es5/modules/olderversions/router-with-templates.js +701 -0
  36. package/es5/modules/prototypes/ajax.js +657 -0
  37. package/es5/modules/prototypes/atom.js +65 -0
  38. package/es5/modules/prototypes/component.js +972 -0
  39. package/es5/modules/prototypes/data-binder.js +1089 -0
  40. package/es5/modules/prototypes/data.js +1290 -0
  41. package/es5/modules/prototypes/html-builder.js +414 -0
  42. package/es5/modules/prototypes/layout.js +879 -0
  43. package/es5/modules/router.js +1680 -0
  44. package/es5/modules/state.js +274 -0
  45. package/es6/.jshintrc +3 -0
  46. package/es6/base.js +41 -0
  47. package/es6/core.js +1 -0
  48. package/es6/data-tracker.js +351 -0
  49. package/es6/events.js +602 -0
  50. package/es6/legacy/es5/base.js +2968 -0
  51. package/es6/legacy/es5/modules/ajax.js +663 -0
  52. package/es6/legacy/es5/modules/animation.js +188 -0
  53. package/es6/legacy/es5/modules/animations.js +1080 -0
  54. package/es6/legacy/es5/modules/atom.js +65 -0
  55. package/es6/legacy/es5/modules/component.js +1310 -0
  56. package/es6/legacy/es5/modules/data-binder.js +1131 -0
  57. package/es6/legacy/es5/modules/data.js +1808 -0
  58. package/es6/legacy/es5/modules/date.js +525 -0
  59. package/es6/legacy/es5/modules/form-validator.js +324 -0
  60. package/es6/legacy/es5/modules/history.js +126 -0
  61. package/es6/legacy/es5/modules/html-builder.js +461 -0
  62. package/es6/legacy/es5/modules/layout.js +1679 -0
  63. package/es6/legacy/es5/modules/mouse.js +124 -0
  64. package/es6/legacy/es5/modules/nav-link.js +123 -0
  65. package/es6/legacy/es5/modules/olderversions/animations-ease.js +1095 -0
  66. package/es6/legacy/es5/modules/olderversions/animations-update.js +1048 -0
  67. package/es6/legacy/es5/modules/olderversions/base-animations.js +636 -0
  68. package/es6/legacy/es5/modules/olderversions/base-component-class.js +100 -0
  69. package/es6/legacy/es5/modules/olderversions/base-data-binder-1.js +407 -0
  70. package/es6/legacy/es5/modules/olderversions/base-data-binder-class.js +358 -0
  71. package/es6/legacy/es5/modules/olderversions/base-layout-parser-class.js +172 -0
  72. package/es6/legacy/es5/modules/olderversions/base-mode-1.js +777 -0
  73. package/es6/legacy/es5/modules/olderversions/base-model-class.js +585 -0
  74. package/es6/legacy/es5/modules/olderversions/data-binder/element-binding/base-data-binder-class.js +358 -0
  75. package/es6/legacy/es5/modules/olderversions/data-binder/element-binding/base-model-class.js +585 -0
  76. package/es6/legacy/es5/modules/olderversions/data-binder/model-binding/base-data-binder-class.js +353 -0
  77. package/es6/legacy/es5/modules/olderversions/data-binder/model-binding/base-model-class.js +604 -0
  78. package/es6/legacy/es5/modules/olderversions/data-binder-update-watcher.js +640 -0
  79. package/es6/legacy/es5/modules/olderversions/data-tracker.js +187 -0
  80. package/es6/legacy/es5/modules/olderversions/event-update.js +666 -0
  81. package/es6/legacy/es5/modules/olderversions/nav-link.js +119 -0
  82. package/es6/legacy/es5/modules/olderversions/router-with-templates-1.js +785 -0
  83. package/es6/legacy/es5/modules/olderversions/router-with-templates.js +701 -0
  84. package/es6/legacy/es5/modules/prototypes/ajax.js +657 -0
  85. package/es6/legacy/es5/modules/prototypes/atom.js +65 -0
  86. package/es6/legacy/es5/modules/prototypes/component.js +972 -0
  87. package/es6/legacy/es5/modules/prototypes/data-binder.js +1089 -0
  88. package/es6/legacy/es5/modules/prototypes/data.js +1290 -0
  89. package/es6/legacy/es5/modules/prototypes/html-builder.js +414 -0
  90. package/es6/legacy/es5/modules/prototypes/layout.js +879 -0
  91. package/es6/legacy/es5/modules/router.js +1680 -0
  92. package/es6/legacy/es5/modules/state.js +274 -0
  93. package/es6/main.js +1331 -0
  94. package/es6/modules/ajax/ajax.js +514 -0
  95. package/es6/modules/animation/animation.js +236 -0
  96. package/es6/modules/animations/animation-controller.js +231 -0
  97. package/es6/modules/animations/animation.js +64 -0
  98. package/es6/modules/animations/attr-movement.js +66 -0
  99. package/es6/modules/animations/css-movement.js +170 -0
  100. package/es6/modules/animations/movement.js +131 -0
  101. package/es6/modules/animations/value.js +187 -0
  102. package/es6/modules/atom/atom.js +54 -0
  103. package/es6/modules/component/component.js +230 -0
  104. package/es6/modules/component/event-helper.js +119 -0
  105. package/es6/modules/component/jot.js +144 -0
  106. package/es6/modules/component/state-helper.js +262 -0
  107. package/es6/modules/component/unit.js +551 -0
  108. package/es6/modules/data/attrs.js +40 -0
  109. package/es6/modules/data/basic-data.js +500 -0
  110. package/es6/modules/data/data-utils.js +29 -0
  111. package/es6/modules/data/data.js +3 -0
  112. package/es6/modules/data/deep-data.js +541 -0
  113. package/es6/modules/data/model-service.js +528 -0
  114. package/es6/modules/data/model.js +133 -0
  115. package/es6/modules/data/simple-data.js +33 -0
  116. package/es6/modules/data-binder/connection-tracker.js +113 -0
  117. package/es6/modules/data-binder/connection.js +16 -0
  118. package/es6/modules/data-binder/data-binder.js +352 -0
  119. package/es6/modules/data-binder/data-pub-sub.js +141 -0
  120. package/es6/modules/data-binder/data-source.js +56 -0
  121. package/es6/modules/data-binder/element-source.js +219 -0
  122. package/es6/modules/data-binder/one-way-connection.js +46 -0
  123. package/es6/modules/data-binder/one-way-source.js +43 -0
  124. package/es6/modules/data-binder/source.js +36 -0
  125. package/es6/modules/data-binder/two-way-connection.js +75 -0
  126. package/es6/modules/data-binder/two-way-source.js +41 -0
  127. package/es6/modules/date/date.js +544 -0
  128. package/es6/modules/history/history.js +89 -0
  129. package/es6/modules/html-builder/html-builder.js +434 -0
  130. package/es6/modules/import/import.js +390 -0
  131. package/es6/modules/layout/layout-builder.js +1269 -0
  132. package/es6/modules/layout/layout-parser.js +134 -0
  133. package/es6/modules/layout/watcher-helper.js +282 -0
  134. package/es6/modules/mouse/mouse.js +114 -0
  135. package/es6/modules/router/component-helper.js +163 -0
  136. package/es6/modules/router/history-controller.js +216 -0
  137. package/es6/modules/router/nav-link.js +124 -0
  138. package/es6/modules/router/route.js +401 -0
  139. package/es6/modules/router/router.js +789 -0
  140. package/es6/modules/router/utils.js +31 -0
  141. package/es6/modules/state/state-target.js +91 -0
  142. package/es6/modules/state/state.js +171 -0
  143. package/es6/package-lock.json +13 -0
  144. package/es6/package.json +28 -0
  145. package/es6/shared/objects.js +99 -0
  146. package/legacy/es5/base.js +2968 -0
  147. package/legacy/es5/modules/ajax.js +663 -0
  148. package/legacy/es5/modules/animation.js +188 -0
  149. package/legacy/es5/modules/animations.js +1080 -0
  150. package/legacy/es5/modules/atom.js +65 -0
  151. package/legacy/es5/modules/component.js +1310 -0
  152. package/legacy/es5/modules/data-binder.js +1131 -0
  153. package/legacy/es5/modules/data.js +1808 -0
  154. package/legacy/es5/modules/date.js +525 -0
  155. package/legacy/es5/modules/form-validator.js +324 -0
  156. package/legacy/es5/modules/history.js +126 -0
  157. package/legacy/es5/modules/html-builder.js +461 -0
  158. package/legacy/es5/modules/layout.js +1679 -0
  159. package/legacy/es5/modules/mouse.js +124 -0
  160. package/legacy/es5/modules/nav-link.js +123 -0
  161. package/legacy/es5/modules/olderversions/animations-ease.js +1095 -0
  162. package/legacy/es5/modules/olderversions/animations-update.js +1048 -0
  163. package/legacy/es5/modules/olderversions/base-animations.js +636 -0
  164. package/legacy/es5/modules/olderversions/base-component-class.js +100 -0
  165. package/legacy/es5/modules/olderversions/base-data-binder-1.js +407 -0
  166. package/legacy/es5/modules/olderversions/base-data-binder-class.js +358 -0
  167. package/legacy/es5/modules/olderversions/base-layout-parser-class.js +172 -0
  168. package/legacy/es5/modules/olderversions/base-mode-1.js +777 -0
  169. package/legacy/es5/modules/olderversions/base-model-class.js +585 -0
  170. package/legacy/es5/modules/olderversions/data-binder/element-binding/base-data-binder-class.js +358 -0
  171. package/legacy/es5/modules/olderversions/data-binder/element-binding/base-model-class.js +585 -0
  172. package/legacy/es5/modules/olderversions/data-binder/model-binding/base-data-binder-class.js +353 -0
  173. package/legacy/es5/modules/olderversions/data-binder/model-binding/base-model-class.js +604 -0
  174. package/legacy/es5/modules/olderversions/data-binder-update-watcher.js +640 -0
  175. package/legacy/es5/modules/olderversions/data-tracker.js +187 -0
  176. package/legacy/es5/modules/olderversions/event-update.js +666 -0
  177. package/legacy/es5/modules/olderversions/nav-link.js +119 -0
  178. package/legacy/es5/modules/olderversions/router-with-templates-1.js +785 -0
  179. package/legacy/es5/modules/olderversions/router-with-templates.js +701 -0
  180. package/legacy/es5/modules/prototypes/ajax.js +657 -0
  181. package/legacy/es5/modules/prototypes/atom.js +65 -0
  182. package/legacy/es5/modules/prototypes/component.js +972 -0
  183. package/legacy/es5/modules/prototypes/data-binder.js +1089 -0
  184. package/legacy/es5/modules/prototypes/data.js +1290 -0
  185. package/legacy/es5/modules/prototypes/html-builder.js +414 -0
  186. package/legacy/es5/modules/prototypes/layout.js +879 -0
  187. package/legacy/es5/modules/router.js +1680 -0
  188. package/legacy/es5/modules/state.js +274 -0
  189. package/package.json +8 -3
  190. package/update +16 -0
@@ -0,0 +1,640 @@
1
+ /* base framework module */
2
+ (function()
3
+ {
4
+ "use strict";
5
+
6
+ /*
7
+ DataPubSub
8
+
9
+ this will create a pub sub object
10
+ to allow messages to be subscribed to and
11
+ publish changes that will be pushed to the
12
+ subscribers.
13
+
14
+ */
15
+ var DataPubSub = base.Class.extend(
16
+ {
17
+ constructor: function()
18
+ {
19
+ this.callBacks = {};
20
+ this.lastToken = -1;
21
+ },
22
+
23
+ /* this will get the subscriber array for the
24
+ message or create a new subscriber array if none
25
+ is setup already.
26
+ @param (string) msg
27
+ @return (array) subscriber array */
28
+ get: function(msg)
29
+ {
30
+ var callBacks = this.callBacks;
31
+ return (callBacks[msg] || (callBacks[msg] = []));
32
+ },
33
+
34
+ reset: function()
35
+ {
36
+ this.callBacks = {};
37
+ },
38
+
39
+ on: function(msg, callBack)
40
+ {
41
+ var token = (++this.lastToken);
42
+ var list = this.get(msg);
43
+ list.push({
44
+ token: token,
45
+ callBack: callBack
46
+ });
47
+ return token;
48
+ },
49
+
50
+ off: function(msg, token)
51
+ {
52
+ var list = this.callBacks[msg] || false;
53
+ if(list)
54
+ {
55
+ var length = list.length;
56
+ for (var i = 0; i < length; i++ )
57
+ {
58
+ var item = list[i];
59
+ if(item.token === token)
60
+ {
61
+ list.splice(i, 1);
62
+ break;
63
+ }
64
+ }
65
+ }
66
+ },
67
+
68
+ remove: function(msg)
69
+ {
70
+ var callBacks = this.callBacks;
71
+ if(callBacks[msg])
72
+ {
73
+ delete callBacks[msg];
74
+ }
75
+ },
76
+
77
+ publish: function(msg)
78
+ {
79
+ var i, length,
80
+ list = this.callBacks[msg] || false;
81
+ if(list !== false)
82
+ {
83
+ length = list.length;
84
+ for (i = 0; i < length; i++ )
85
+ {
86
+ list[i].callBack.apply(this, arguments);
87
+ }
88
+ }
89
+ }
90
+ });
91
+
92
+ var pubSub = new DataPubSub();
93
+ base.extend.DataPubSub = DataPubSub;
94
+
95
+ var Source = base.Class.extend(
96
+ {
97
+ constructor: function()
98
+ {
99
+ this.msg = null;
100
+ this.token = null;
101
+ },
102
+
103
+ setToken: function(token)
104
+ {
105
+ this.token = token;
106
+ },
107
+
108
+ callBack: null,
109
+
110
+ subscribe: function(msg)
111
+ {
112
+ this.msg = msg;
113
+ var callBack = base.bind(this, this.callBack);
114
+ this.token = pubSub.on(msg, callBack);
115
+ },
116
+
117
+ unsubscribe: function()
118
+ {
119
+ pubSub.off(this.msg, this.token);
120
+ }
121
+ });
122
+
123
+ var DataSource = Source.extend(
124
+ {
125
+ constructor: function(data, prop)
126
+ {
127
+ Source.call(this);
128
+ this.data = data;
129
+ this.prop = prop;
130
+ },
131
+
132
+ set: function(value)
133
+ {
134
+ this.data.set(this.prop, value);
135
+ },
136
+
137
+ get: function()
138
+ {
139
+ return this.data.get(this.prop);
140
+ },
141
+
142
+ callBack: function(evt, prop, value, committer)
143
+ {
144
+ if(this.data !== this.committer)
145
+ {
146
+ this.data.set(prop, value, committer);
147
+ }
148
+ }
149
+ });
150
+
151
+ var ElementSource = Source.extend(
152
+ {
153
+ constructor: function(element, attr, filter)
154
+ {
155
+ Source.call(this);
156
+ this.element = element;
157
+ this.attr = this.getAttrBind(attr);
158
+
159
+ if(typeof filter === 'string')
160
+ {
161
+ filter = this.setupFilter(filter);
162
+ }
163
+ this.filter = filter;
164
+ },
165
+
166
+ getAttrBind: function(customAttr)
167
+ {
168
+ /* this will setup the custom attr if the prop
169
+ has specified one. */
170
+ if(customAttr)
171
+ {
172
+ return customAttr;
173
+ }
174
+
175
+ var attr = 'textContent';
176
+ /* if no custom attr has been requested we will get the
177
+ default attr of the element */
178
+ var element = this.element;
179
+ if(element && typeof element === 'object')
180
+ {
181
+ var tagName = element.tagName.toLowerCase();
182
+ if (tagName === "input" || tagName === "textarea" || tagName === "select")
183
+ {
184
+ var type = element.type;
185
+ if(type && (type === 'checkbox' || type === 'radio'))
186
+ {
187
+ attr = 'checked';
188
+ }
189
+ else
190
+ {
191
+ attr = 'value';
192
+ }
193
+ }
194
+ }
195
+ return attr;
196
+ },
197
+
198
+ setupFilter: function(filter)
199
+ {
200
+ var pattern = /(\[\[[^\]]+\]\])/;
201
+ return function(value)
202
+ {
203
+ return filter.replace(pattern, value);
204
+ };
205
+ },
206
+
207
+ /* this will set a value on an elememnt.
208
+ @param (mixed) value */
209
+ set: function(value)
210
+ {
211
+ var element = this.element;
212
+ if(element && typeof element === 'object')
213
+ {
214
+ /* this will check to apply the option filter before
215
+ settings the value */
216
+ if(this.filter)
217
+ {
218
+ value = this.filter(value);
219
+ }
220
+
221
+ var attr = this.attr,
222
+ type = element.type;
223
+ if(type && (type === 'checkbox' || type === 'radio'))
224
+ {
225
+ value = (value == 1);
226
+ }
227
+
228
+ if(attr.substring(0, 5) === 'data-')
229
+ {
230
+ base.data(element, attr, value);
231
+ }
232
+ else
233
+ {
234
+ element[attr] = value;
235
+ }
236
+ }
237
+ },
238
+
239
+ /* this will get a value on an elememnt.
240
+ @return (mixed) the element value */
241
+ get: function()
242
+ {
243
+ var value = '',
244
+ element = this.element;
245
+ if(element && typeof element === 'object')
246
+ {
247
+ var attr = this.attr;
248
+ if(attr.substring(0, 5) === 'data-')
249
+ {
250
+ value = base.data(element, attr);
251
+ }
252
+ else
253
+ {
254
+ value = element[attr];
255
+ }
256
+ }
257
+ return value;
258
+ },
259
+
260
+ callBack: function(evt, prop, value, committer)
261
+ {
262
+ if(committer !== this.element)
263
+ {
264
+ this.set(value);
265
+ }
266
+ }
267
+ });
268
+
269
+ var Connection = base.Class.extend(
270
+ {
271
+ constructor: function()
272
+ {
273
+ this.element = null;
274
+ this.data = null;
275
+ },
276
+
277
+ addElement: function(element, attr, filter)
278
+ {
279
+ return (this.element = new ElementSource(element, attr, filter));
280
+ },
281
+
282
+ addData: function(data, prop)
283
+ {
284
+ return (this.data = new DataSource(data, prop));
285
+ },
286
+
287
+ unsubscribeSource: function(source)
288
+ {
289
+ if(source)
290
+ {
291
+ source.unsubscribe();
292
+ }
293
+ },
294
+
295
+ unsubscribe: function()
296
+ {
297
+ this.unsubscribeSource(this.element);
298
+ this.unsubscribeSource(this.data);
299
+
300
+ this.element = null;
301
+ this.data = null;
302
+ }
303
+ });
304
+
305
+ var ConnectionTracker = base.Class.extend(
306
+ {
307
+ constructor: function()
308
+ {
309
+ this.connections = {};
310
+ },
311
+
312
+ add: function(id, connection)
313
+ {
314
+ var connections = this.connections;
315
+ return (connections[id] = connection);
316
+ },
317
+
318
+ get: function(id)
319
+ {
320
+ return (this.connections[id] || false);
321
+ },
322
+
323
+ remove: function(id)
324
+ {
325
+ var connection = this.connections[id];
326
+ if(connection)
327
+ {
328
+ connection.unsubscribe();
329
+ delete this.connections[id];
330
+ }
331
+ }
332
+ });
333
+
334
+ var WatcherTracker = base.Class.extend(
335
+ {
336
+ constructor: function()
337
+ {
338
+ this.watchers = {};
339
+ },
340
+
341
+ find: function(id)
342
+ {
343
+ var watchers = this.watchers;
344
+ return (watchers[id] || (watchers[id] = []));
345
+ },
346
+
347
+ add: function(id, data, prop, callBack)
348
+ {
349
+ var subscriptions = this.find(id);
350
+ subscriptions.push({
351
+ data: data,
352
+ msg: prop,
353
+ token: this.getSubscription(data, prop, callBack)
354
+ });
355
+ },
356
+
357
+ getSubscription: function(data, prop, callBack)
358
+ {
359
+ return data.on(prop, callBack);
360
+ },
361
+
362
+ get: function(id)
363
+ {
364
+ return (this.watchers[id] || false);
365
+ },
366
+
367
+ remove: function(id)
368
+ {
369
+ var subscriptions = this.watchers[id];
370
+ if(subscriptions)
371
+ {
372
+ for(var i = 0, length = subscriptions.length; i < length; i++)
373
+ {
374
+ var subscription = subscriptions[i];
375
+ if(subscription)
376
+ {
377
+ subscription.data.off(subscription.msg, subscription.token);
378
+ }
379
+ }
380
+ delete this.watchers[id];
381
+ }
382
+ }
383
+ });
384
+
385
+ /*
386
+ DataBinder
387
+
388
+ this create a data bind module to add
389
+ two way data binding to base models.
390
+ */
391
+ var DataBinder = base.Class.extend(
392
+ {
393
+ constructor: function()
394
+ {
395
+ this.version = "1.0.1";
396
+ this.attr = 'data-bind';
397
+
398
+ this.connections = new ConnectionTracker();
399
+ this.watchers = new WatcherTracker();
400
+
401
+ this.idCount = 0;
402
+ this.setup();
403
+ },
404
+
405
+ setup: function()
406
+ {
407
+ this.setupEvents();
408
+ },
409
+
410
+ /* this will add the data bind attr on an
411
+ element for a model property.
412
+ @param (object) element
413
+ @param (object) data
414
+ @param (string) prop
415
+ @return (object) the instance of the data binder */
416
+ bind: function(element, data, prop, filter)
417
+ {
418
+ var bindSettings = this.getPropSettings(prop);
419
+ prop = bindSettings.prop;
420
+
421
+ /* this will setup the model bind attr to the
422
+ element and assign a bind id attr to support
423
+ two way binding */
424
+ var connection = this.setupConnection(element, data, prop, bindSettings.attr, filter);
425
+
426
+ /* we want to get the starting value of the
427
+ data and set it on our element */
428
+ var connectionElement = connection.element,
429
+ value = data.get(prop);
430
+ if(typeof value !== 'undefined')
431
+ {
432
+ connectionElement.set(value);
433
+ }
434
+ else
435
+ {
436
+ /* this will set the element value
437
+ as the prop value */
438
+ value = connectionElement.get();
439
+ if(value !== '')
440
+ {
441
+ connection.data.set(value);
442
+ }
443
+ }
444
+ return this;
445
+ },
446
+
447
+ setupConnection: function(element, data, prop, customAttr, filter)
448
+ {
449
+ var connection = new Connection();
450
+
451
+ var id = this.getBindId(element);
452
+ var dataSource = connection.addData(data, prop);
453
+ dataSource.subscribe(id);
454
+
455
+ /* this will add the data binding
456
+ attr to out element so it will subscribe to
457
+ the two data changes */
458
+ var dataId = data.getDataId(),
459
+ msg = dataId + ':' + prop;
460
+
461
+ var elementSource = connection.addElement(element, customAttr, filter);
462
+ elementSource.subscribe(msg);
463
+
464
+ this.addConnection(id, connection);
465
+
466
+ return connection;
467
+ },
468
+
469
+ addConnection: function(id, connection)
470
+ {
471
+ this.connections.add(id, connection);
472
+ },
473
+
474
+ setBindId: function(element)
475
+ {
476
+ var id = 'bs-db-' + this.idCount++;
477
+ base.attr(element, this.attr + '-id', id);
478
+ return id;
479
+ },
480
+
481
+ getBindId: function(element)
482
+ {
483
+ var id = base.attr(element, this.attr + '-id');
484
+ if(!id)
485
+ {
486
+ id = this.setBindId(element);
487
+ }
488
+ return id;
489
+ },
490
+
491
+ getPropSettings: function(prop)
492
+ {
493
+ var bindProp = prop,
494
+ bindAttr = null;
495
+
496
+ /* this will setup the custom attr if the prop
497
+ has specified one. */
498
+ var parts = prop.split(':');
499
+ if(parts.length > 1)
500
+ {
501
+ bindProp = parts[1];
502
+ bindAttr = parts[0];
503
+ }
504
+
505
+ return {
506
+ prop: bindProp,
507
+ attr: bindAttr
508
+ };
509
+ },
510
+
511
+ /* this will remove an element from the data binder
512
+ @param (object) element
513
+ @return (object) the instance of the data binder*/
514
+ unbind: function(element)
515
+ {
516
+ var id = base.data(element, this.attr + '-id');
517
+ if(id)
518
+ {
519
+ this.connections.remove(id);
520
+ this.watchers.remove(id);
521
+ }
522
+ return this;
523
+ },
524
+
525
+ watch: function(element, data, prop, callBack)
526
+ {
527
+ if(!element || typeof element !== 'object')
528
+ {
529
+ return false;
530
+ }
531
+
532
+ var id = this.getBindId(element);
533
+ this.watchers.add(id, data, prop, callBack);
534
+ },
535
+
536
+ unwatch: function(element)
537
+ {
538
+ if(!element || typeof element !== 'object')
539
+ {
540
+ return false;
541
+ }
542
+
543
+ var id = base.attr(element, this.attr + '-id');
544
+ if(id)
545
+ {
546
+ this.watchers.remove(element);
547
+ }
548
+ },
549
+
550
+ /* this will publish a change to the data binder.
551
+ @param (string) message e.g id:change
552
+ @param (string) attrName = the model prop name
553
+ @param (mixed) the prop value
554
+ @param (object) the object committing the change */
555
+ publish: function(msg, attr, value, committer)
556
+ {
557
+ pubSub.publish(msg, attr, value, committer);
558
+ return this;
559
+ },
560
+
561
+ isDataBound: function(element)
562
+ {
563
+ if(element)
564
+ {
565
+ var dataAttr = this.attr;
566
+ var id = base.data(element, dataAttr + '-id');
567
+ if(id)
568
+ {
569
+ return id;
570
+ }
571
+ }
572
+ return false;
573
+ },
574
+
575
+ blockedKeys: [
576
+ 17, //ctrl
577
+ 9, //tab
578
+ 16, //shift
579
+ 18, //alt
580
+ 20, //caps lock
581
+ 37, //arrows
582
+ 38,
583
+ 39,
584
+ 40
585
+ ],
586
+
587
+ bindHandler: function(evt)
588
+ {
589
+ if(evt.type === 'keyup')
590
+ {
591
+ /* this will check to block ctrl, shift or alt +
592
+ buttons */
593
+ if(evt.ctrlKey !== false || evt.shiftKey !== false || evt.altKey !== false || base.inArray(this.blockedKeys, evt.keyCode) !== -1)
594
+ {
595
+ return true;
596
+ }
597
+ }
598
+
599
+ var target = evt.target || evt.srcElement;
600
+ var id = this.isDataBound(target);
601
+ if(id)
602
+ {
603
+ var connection = this.connections.get(id);
604
+ if(connection)
605
+ {
606
+ var value = connection.element.get();
607
+ /* this will publish to the ui and to the
608
+ model that subscribes to the element */
609
+ pubSub.publish(id, connection.data.prop, value, target);
610
+ }
611
+ }
612
+ evt.stopPropagation();
613
+ },
614
+
615
+ /* this will setup the on change handler and
616
+ add the events. this needs to be setup before adding
617
+ the events. */
618
+ changeHandler: null,
619
+ setupEvents: function()
620
+ {
621
+ this.changeHandler = base.bind(this, this.bindHandler);
622
+
623
+ this.addEvents();
624
+ },
625
+
626
+ /* this will add the binder events */
627
+ addEvents: function()
628
+ {
629
+ base.on(["change", "keyup"], document, this.changeHandler, false);
630
+ },
631
+
632
+ /* this will remove the binder events */
633
+ removeEvents: function()
634
+ {
635
+ base.off(["change", "keyup"], document, this.changeHandler, false);
636
+ }
637
+ });
638
+
639
+ base.extend.DataBinder = new DataBinder();
640
+ })();