Move the utility functions into a Rivets.Util object. Better comment the code for annotated source.
Showing
2 changed files
with
106 additions
and
75 deletions
... | @@ -4,7 +4,7 @@ module.exports = (grunt) -> | ... | @@ -4,7 +4,7 @@ module.exports = (grunt) -> |
4 | 4 | ||
5 | meta: | 5 | meta: |
6 | banner: | 6 | banner: |
7 | '// rivets.js\n' + | 7 | '// Rivets.js\n' + |
8 | '// version: <%= pkg.version %>\n' + | 8 | '// version: <%= pkg.version %>\n' + |
9 | '// author: <%= pkg.author %>\n' + | 9 | '// author: <%= pkg.author %>\n' + |
10 | '// license: <%= pkg.licenses[0].type %>\n' | 10 | '// license: <%= pkg.licenses[0].type %>\n' | ... | ... |
1 | # rivets.js | 1 | # Rivets.js |
2 | # version : 0.5.0 | 2 | # ========= |
3 | # author : Michael Richards | 3 | |
4 | # license : MIT | 4 | # > version: 0.5.0 |
5 | # > author: Michael Richards | ||
6 | # > license: MIT | ||
7 | # > | ||
8 | # > http://rivetsjs.com/ | ||
9 | |||
10 | # --- | ||
5 | 11 | ||
6 | # The Rivets namespace. | 12 | # The Rivets namespace. |
7 | Rivets = {} | 13 | Rivets = {} |
8 | 14 | ||
9 | # Polyfill For String::trim. | 15 | # Polyfill For `String::trim`. |
10 | unless String::trim then String::trim = -> @replace /^\s+|\s+$/g, '' | 16 | unless String::trim then String::trim = -> @replace /^\s+|\s+$/g, '' |
11 | 17 | ||
18 | # Rivets.Binding | ||
19 | # -------------- | ||
20 | |||
12 | # A single binding between a model attribute and a DOM element. | 21 | # A single binding between a model attribute and a DOM element. |
13 | class Rivets.Binding | 22 | class Rivets.Binding |
14 | # All information about the binding is passed into the constructor; the | 23 | # All information about the binding is passed into the constructor; the |
... | @@ -67,7 +76,7 @@ class Rivets.Binding | ... | @@ -67,7 +76,7 @@ class Rivets.Binding |
67 | 76 | ||
68 | # Publishes the value currently set on the input element back to the model. | 77 | # Publishes the value currently set on the input element back to the model. |
69 | publish: => | 78 | publish: => |
70 | value = getInputValue @el | 79 | value = Rivets.Util.getInputValue @el |
71 | 80 | ||
72 | for formatter in @formatters.slice(0).reverse() | 81 | for formatter in @formatters.slice(0).reverse() |
73 | args = formatter.split /\s+/ | 82 | args = formatter.split /\s+/ |
... | @@ -128,7 +137,10 @@ class Rivets.Binding | ... | @@ -128,7 +137,10 @@ class Rivets.Binding |
128 | @model = @view.models[@key] | 137 | @model = @view.models[@key] |
129 | @bind() | 138 | @bind() |
130 | 139 | ||
131 | # A collection of bindings built from a set of parent elements. | 140 | # Rivets.View |
141 | # ----------- | ||
142 | |||
143 | # A collection of bindings built from a set of parent nodes. | ||
132 | class Rivets.View | 144 | class Rivets.View |
133 | # The DOM elements and the model objects for binding are passed into the | 145 | # The DOM elements and the model objects for binding are passed into the |
134 | # constructor along with any local options that should be used throughout the | 146 | # constructor along with any local options that should be used throughout the |
... | @@ -148,9 +160,9 @@ class Rivets.View | ... | @@ -148,9 +160,9 @@ class Rivets.View |
148 | prefix = @config.prefix | 160 | prefix = @config.prefix |
149 | if prefix then new RegExp("^data-#{prefix}-") else /^data-/ | 161 | if prefix then new RegExp("^data-#{prefix}-") else /^data-/ |
150 | 162 | ||
151 | # Parses the DOM tree and builds Rivets.Binding instances for every matched | 163 | # Parses the DOM tree and builds `Rivets.Binding` instances for every matched |
152 | # binding declaration. Subsequent calls to build will replace the previous | 164 | # binding declaration. Subsequent calls to build will replace the previous |
153 | # Rivets.Binding instances with new ones, so be sure to unbind them first. | 165 | # `Rivets.Binding` instances with new ones, so be sure to unbind them first. |
154 | build: => | 166 | build: => |
155 | @bindings = [] | 167 | @bindings = [] |
156 | skipNodes = [] | 168 | skipNodes = [] |
... | @@ -233,53 +245,57 @@ class Rivets.View | ... | @@ -233,53 +245,57 @@ class Rivets.View |
233 | @models[key] = model | 245 | @models[key] = model |
234 | binding.update() for binding in @select (b) -> b.key is key | 246 | binding.update() for binding in @select (b) -> b.key is key |
235 | 247 | ||
236 | # Cross-browser event binding. | 248 | # Rivets.Util |
237 | bindEvent = (el, event, handler, context) -> | 249 | # ----------- |
238 | fn = (e) -> handler.call context, e | 250 | |
239 | 251 | # Houses common utility functions used internally by Rivets.js. | |
240 | # Check to see if jQuery is loaded. | 252 | Rivets.Util = |
241 | if window.jQuery? | 253 | # Create a single DOM event binding. |
242 | el = jQuery el | 254 | bindEvent: (el, event, handler, context) -> |
243 | if el.on? then el.on event, fn else el.bind event, fn | 255 | fn = (e) -> handler.call context, e |
244 | # Check to see if addEventListener is available. | 256 | |
245 | else if window.addEventListener? | 257 | if window.jQuery? |
246 | el.addEventListener event, fn, false | 258 | el = jQuery el |
247 | else | 259 | if el.on? then el.on event, fn else el.bind event, fn |
248 | # Assume we are in IE and use attachEvent. | 260 | else if window.addEventListener? |
249 | event = 'on' + event | 261 | el.addEventListener event, fn, false |
250 | el.attachEvent event, fn | 262 | else |
251 | 263 | event = 'on' + event | |
252 | fn | 264 | el.attachEvent event, fn |
253 | 265 | ||
254 | # Cross-browser event unbinding. | 266 | fn |
255 | unbindEvent = (el, event, fn) -> | 267 | |
256 | # Check to see if jQuery is loaded. | 268 | # Remove a single DOM event binding. |
257 | if window.jQuery? | 269 | unbindEvent: (el, event, fn) -> |
258 | el = jQuery el | 270 | if window.jQuery? |
259 | if el.off? then el.off event, fn else el.unbind event, fn | 271 | el = jQuery el |
260 | # Check to see if addEventListener is available. | 272 | if el.off? then el.off event, fn else el.unbind event, fn |
261 | else if window.removeEventListener | 273 | else if window.removeEventListener |
262 | el.removeEventListener event, fn, false | 274 | el.removeEventListener event, fn, false |
263 | else | 275 | else |
264 | # Assume we are in IE and use attachEvent. | 276 | event = 'on' + event |
265 | event = 'on' + event | 277 | el.detachEvent event, fn |
266 | el.detachEvent event, fn | 278 | |
267 | 279 | # Get the current value of an input node. | |
268 | # Cross-browser input value getter. | 280 | getInputValue: (el) -> |
269 | getInputValue = (el) -> | 281 | if window.jQuery? |
270 | if window.jQuery? | 282 | el = jQuery el |
271 | el = jQuery el | 283 | |
272 | 284 | switch el[0].type | |
273 | switch el[0].type | 285 | when 'checkbox' then el.is ':checked' |
274 | when 'checkbox' then el.is ':checked' | 286 | else el.val() |
275 | else el.val() | 287 | else |
276 | else | 288 | switch el.type |
277 | switch el.type | 289 | when 'checkbox' then el.checked |
278 | when 'checkbox' then el.checked | 290 | when 'select-multiple' then o.value for o in el when o.selected |
279 | when 'select-multiple' then o.value for o in el when o.selected | 291 | else el.value |
280 | else el.value | 292 | |
281 | 293 | # Rivets.binders | |
282 | # Core binding routines. | 294 | # -------------- |
295 | |||
296 | # Core binders that are included with Rivets.js, publicly available on | ||
297 | # `module.binders`. Can be overridden globally or local to a `Rivets.View` | ||
298 | # instance. | ||
283 | Rivets.binders = | 299 | Rivets.binders = |
284 | enabled: (el, value) -> | 300 | enabled: (el, value) -> |
285 | el.disabled = !value | 301 | el.disabled = !value |
... | @@ -290,9 +306,9 @@ Rivets.binders = | ... | @@ -290,9 +306,9 @@ Rivets.binders = |
290 | checked: | 306 | checked: |
291 | publishes: true | 307 | publishes: true |
292 | bind: (el) -> | 308 | bind: (el) -> |
293 | @currentListener = bindEvent el, 'change', @publish | 309 | @currentListener = Rivets.Util.bindEvent el, 'change', @publish |
294 | unbind: (el) -> | 310 | unbind: (el) -> |
295 | unbindEvent el, 'change', @currentListener | 311 | Rivets.Util.unbindEvent el, 'change', @currentListener |
296 | routine: (el, value) -> | 312 | routine: (el, value) -> |
297 | if el.type is 'radio' | 313 | if el.type is 'radio' |
298 | el.checked = el.value?.toString() is value?.toString() | 314 | el.checked = el.value?.toString() is value?.toString() |
... | @@ -302,9 +318,9 @@ Rivets.binders = | ... | @@ -302,9 +318,9 @@ Rivets.binders = |
302 | unchecked: | 318 | unchecked: |
303 | publishes: true | 319 | publishes: true |
304 | bind: (el) -> | 320 | bind: (el) -> |
305 | @currentListener = bindEvent el, 'change', @publish | 321 | @currentListener = Rivets.Util.bindEvent el, 'change', @publish |
306 | unbind: (el) -> | 322 | unbind: (el) -> |
307 | unbindEvent el, 'change', @currentListener | 323 | Rivets.Util.unbindEvent el, 'change', @currentListener |
308 | routine: (el, value) -> | 324 | routine: (el, value) -> |
309 | if el.type is 'radio' | 325 | if el.type is 'radio' |
310 | el.checked = el.value?.toString() isnt value?.toString() | 326 | el.checked = el.value?.toString() isnt value?.toString() |
... | @@ -323,9 +339,9 @@ Rivets.binders = | ... | @@ -323,9 +339,9 @@ Rivets.binders = |
323 | value: | 339 | value: |
324 | publishes: true | 340 | publishes: true |
325 | bind: (el) -> | 341 | bind: (el) -> |
326 | @currentListener = bindEvent el, 'change', @publish | 342 | @currentListener = Rivets.Util.bindEvent el, 'change', @publish |
327 | unbind: (el) -> | 343 | unbind: (el) -> |
328 | unbindEvent el, 'change', @currentListener | 344 | Rivets.Util.unbindEvent el, 'change', @currentListener |
329 | routine: (el, value) -> | 345 | routine: (el, value) -> |
330 | if window.jQuery? | 346 | if window.jQuery? |
331 | el = jQuery el | 347 | el = jQuery el |
... | @@ -347,8 +363,8 @@ Rivets.binders = | ... | @@ -347,8 +363,8 @@ Rivets.binders = |
347 | "on-*": | 363 | "on-*": |
348 | function: true | 364 | function: true |
349 | routine: (el, value) -> | 365 | routine: (el, value) -> |
350 | unbindEvent el, @args[0], @currentListener if @currentListener | 366 | Rivets.Util.unbindEvent el, @args[0], @currentListener if @currentListener |
351 | @currentListener = bindEvent el, @args[0], value, @model | 367 | @currentListener = Rivets.Util.bindEvent el, @args[0], value, @model |
352 | 368 | ||
353 | "each-*": | 369 | "each-*": |
354 | block: true | 370 | block: true |
... | @@ -400,15 +416,27 @@ Rivets.binders = | ... | @@ -400,15 +416,27 @@ Rivets.binders = |
400 | else | 416 | else |
401 | el.removeAttribute @type | 417 | el.removeAttribute @type |
402 | 418 | ||
403 | # Default configuration. | 419 | # Rivets.config |
420 | # ------------- | ||
421 | |||
422 | # Default configuration, publicly accessible on `module.config`. Can be | ||
423 | # overridden globally or local to a `Rivets.View` instance. | ||
404 | Rivets.config = | 424 | Rivets.config = |
405 | preloadData: true | 425 | preloadData: true |
406 | 426 | ||
407 | # Default formatters. There aren't any. | 427 | # Rivets.formatters |
428 | # ----------------- | ||
429 | |||
430 | # Default formatters (there aren't any), publicly accessible on | ||
431 | # `module.formatters`. Can be overridden globally or local to a `Rivets.View` | ||
432 | # instance. | ||
408 | Rivets.formatters = {} | 433 | Rivets.formatters = {} |
409 | 434 | ||
410 | # The rivets module. This is the public interface that gets exported. | 435 | # Rivets.factory |
411 | factory = (exports) -> | 436 | # -------------- |
437 | |||
438 | # The Rivets.js module factory. | ||
439 | Rivets.factory = (exports) -> | ||
412 | # Exposes the core binding routines that can be extended or stripped down. | 440 | # Exposes the core binding routines that can be extended or stripped down. |
413 | exports.binders = Rivets.binders | 441 | exports.binders = Rivets.binders |
414 | 442 | ||
... | @@ -425,19 +453,22 @@ factory = (exports) -> | ... | @@ -425,19 +453,22 @@ factory = (exports) -> |
425 | Rivets.config[property] = value | 453 | Rivets.config[property] = value |
426 | return | 454 | return |
427 | 455 | ||
428 | # Binds a set of model objects to a parent DOM element. Returns a Rivets.View | 456 | # Binds a set of model objects to a parent DOM element and returns a |
429 | # instance. | 457 | # `Rivets.View` instance. |
430 | exports.bind = (el, models = {}, options = {}) -> | 458 | exports.bind = (el, models = {}, options = {}) -> |
431 | view = new Rivets.View(el, models, options) | 459 | view = new Rivets.View(el, models, options) |
432 | view.bind() | 460 | view.bind() |
433 | view | 461 | view |
434 | 462 | ||
435 | # Exports rivets for CommonJS, AMD and the browser. | 463 | # Export |
464 | # ------ | ||
465 | |||
466 | # Exports Rivets.js for CommonJS, AMD and the browser. | ||
436 | if typeof exports == 'object' | 467 | if typeof exports == 'object' |
437 | factory(exports) | 468 | Rivets.factory(exports) |
438 | else if typeof define == 'function' && define.amd | 469 | else if typeof define == 'function' && define.amd |
439 | define ['exports'], (exports) -> | 470 | define ['exports'], (exports) -> |
440 | factory(@rivets = exports) | 471 | Rivets.factory(@rivets = exports) |
441 | return exports | 472 | return exports |
442 | else | 473 | else |
443 | factory(@rivets = {}) | 474 | Rivets.factory(@rivets = {}) | ... | ... |
-
Please register or sign in to post a comment