| 
									
										
										
										
											2014-08-11 10:17:30 +08:00
										 |  |  | var _ = require('../util') | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  | var Watcher = require('../watcher') | 
					
						
							| 
									
										
										
										
											2014-08-11 10:17:30 +08:00
										 |  |  | var textParser = require('../parse/text') | 
					
						
							|  |  |  | var dirParser = require('../parse/directive') | 
					
						
							|  |  |  | var expParser = require('../parse/expression') | 
					
						
							|  |  |  | var filterRE = /[^|]\|[^|]/ | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Get the value from an expression on this vm. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @param {String} exp | 
					
						
							|  |  |  |  * @return {*} | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | exports.$get = function (exp) { | 
					
						
							|  |  |  |   var res = expParser.parse(exp) | 
					
						
							|  |  |  |   if (res) { | 
					
						
							|  |  |  |     return res.get.call(this, this.$scope) | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-09 03:57:47 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Set the value from an expression on this vm. | 
					
						
							| 
									
										
										
										
											2014-08-11 02:12:22 +08:00
										 |  |  |  * The expression must be a valid left-hand | 
					
						
							|  |  |  |  * expression in an assignment. | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * @param {String} exp | 
					
						
							|  |  |  |  * @param {*} val | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | exports.$set = function (exp, val) { | 
					
						
							|  |  |  |   var res = expParser.parse(exp, true) | 
					
						
							|  |  |  |   if (res && res.set) { | 
					
						
							|  |  |  |     res.set.call(this, this.$scope, val) | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-09 03:57:47 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2014-08-11 02:12:22 +08:00
										 |  |  |  * Add a property on the VM | 
					
						
							|  |  |  |  * (and also on $scope and $data) | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * @param {String} key | 
					
						
							|  |  |  |  * @param {*} val | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | exports.$add = function (key, val) { | 
					
						
							|  |  |  |   this.$scope.$add(key, val) | 
					
						
							| 
									
										
										
										
											2014-07-14 22:43:48 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2014-08-11 02:12:22 +08:00
										 |  |  |  * Delete a property on the VM | 
					
						
							|  |  |  |  * (and also on $scope and $data) | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * @param {String} key | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | exports.$delete = function (key) { | 
					
						
							|  |  |  |   this.$scope.$delete(key) | 
					
						
							| 
									
										
										
										
											2014-07-14 22:43:48 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2014-08-11 02:12:22 +08:00
										 |  |  |  * Watch an expression, trigger callback when its | 
					
						
							|  |  |  |  * value changes. Returns the created watcher's | 
					
						
							|  |  |  |  * id so it can be teardown later. | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * @param {String} exp | 
					
						
							|  |  |  |  * @param {Function} cb | 
					
						
							|  |  |  |  * @return {Number} | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | exports.$watch = function (exp, cb) { | 
					
						
							|  |  |  |   var watcher = new Watcher(this, exp, cb, this) | 
					
						
							|  |  |  |   this._watchers[watcher.id] = watcher | 
					
						
							|  |  |  |   return watcher.id | 
					
						
							| 
									
										
										
										
											2014-07-09 03:57:47 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Teardown a watcher with given id. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @param {Number} id | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | exports.$unwatch = function (id) { | 
					
						
							|  |  |  |   var watcher = this._watchers[id] | 
					
						
							|  |  |  |   if (watcher) { | 
					
						
							|  |  |  |     watcher.teardown() | 
					
						
							| 
									
										
										
										
											2014-08-11 02:15:04 +08:00
										 |  |  |     this._watchers[id] = null | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-14 22:43:48 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-11 10:17:30 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Evaluate a text directive, including filters. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @param {String} text | 
					
						
							|  |  |  |  * @return {String} | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | exports.$eval = function (text) { | 
					
						
							|  |  |  |   // check for filters.
 | 
					
						
							|  |  |  |   if (filterRE.test(text)) { | 
					
						
							|  |  |  |     var dir = dirParser.parse(text)[0] | 
					
						
							|  |  |  |     // the filter regex check might give false positive
 | 
					
						
							|  |  |  |     // for pipes inside strings, so it's possible that
 | 
					
						
							|  |  |  |     // we don't get any filters here
 | 
					
						
							|  |  |  |     return dir.filters | 
					
						
							|  |  |  |       ? _.applyFilters( | 
					
						
							|  |  |  |           this.$get(dir.expression), | 
					
						
							| 
									
										
										
										
											2014-08-17 10:40:59 +08:00
										 |  |  |           _.resolveFilters(this, dir.filters).read, | 
					
						
							|  |  |  |           this | 
					
						
							| 
									
										
										
										
											2014-08-11 10:17:30 +08:00
										 |  |  |         ) | 
					
						
							|  |  |  |       : this.$get(dir.expression) | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     // no filter
 | 
					
						
							|  |  |  |     return this.$get(text) | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2014-08-11 04:46:20 +08:00
										 |  |  |  * Interpolate a piece of template text. | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2014-08-11 04:46:20 +08:00
										 |  |  |  * @param {String} text | 
					
						
							| 
									
										
										
										
											2014-08-11 02:12:22 +08:00
										 |  |  |  * @return {String} | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-11 04:46:20 +08:00
										 |  |  | exports.$interpolate = function (text) { | 
					
						
							| 
									
										
										
										
											2014-08-11 10:17:30 +08:00
										 |  |  |   var tokens = textParser.parse(text) | 
					
						
							|  |  |  |   var vm = this | 
					
						
							|  |  |  |   if (tokens) { | 
					
						
							| 
									
										
										
										
											2014-08-16 17:41:18 +08:00
										 |  |  |     return tokens.length === 1 | 
					
						
							|  |  |  |       ? vm.$eval(tokens[0].value) | 
					
						
							|  |  |  |       : tokens.map(function (token) { | 
					
						
							|  |  |  |           return token.tag | 
					
						
							|  |  |  |             ? vm.$eval(token.value) | 
					
						
							|  |  |  |             : token.value | 
					
						
							|  |  |  |         }).join('') | 
					
						
							| 
									
										
										
										
											2014-08-11 10:17:30 +08:00
										 |  |  |   } else { | 
					
						
							|  |  |  |     return text | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-14 22:43:48 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Log instance data as a plain JS object | 
					
						
							|  |  |  |  * so that it is easier to inspect in console. | 
					
						
							|  |  |  |  * This method assumes console is available. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @param {String} [key] | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | exports.$log = function (key) { | 
					
						
							|  |  |  |   var data = this[key || '$data'] | 
					
						
							|  |  |  |   console.log(JSON.parse(JSON.stringify(data))) | 
					
						
							| 
									
										
										
										
											2014-07-09 03:57:47 +08:00
										 |  |  | } |