| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  | var Watcher = require('../watcher') | 
					
						
							| 
									
										
										
										
											2014-11-25 06:23:42 +08:00
										 |  |  | var Path = require('../parsers/path') | 
					
						
							|  |  |  | var textParser = require('../parsers/text') | 
					
						
							|  |  |  | var dirParser = require('../parsers/directive') | 
					
						
							|  |  |  | var expParser = require('../parsers/expression') | 
					
						
							| 
									
										
										
										
											2014-08-11 10:17:30 +08:00
										 |  |  | var filterRE = /[^|]\|[^|]/ | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Get the value from an expression on this vm. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @param {String} exp | 
					
						
							| 
									
										
										
										
											2015-09-15 23:09:19 +08:00
										 |  |  |  * @param {Boolean} [asStatement] | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  |  * @return {*} | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-15 23:09:19 +08:00
										 |  |  | exports.$get = function (exp, asStatement) { | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  |   var res = expParser.parse(exp) | 
					
						
							|  |  |  |   if (res) { | 
					
						
							| 
									
										
										
										
											2015-09-15 23:09:19 +08:00
										 |  |  |     if (asStatement && !expParser.isSimplePath(exp)) { | 
					
						
							|  |  |  |       var self = this | 
					
						
							|  |  |  |       return function statementHandler () { | 
					
						
							|  |  |  |         res.get.call(self, self) | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         return res.get.call(this, this) | 
					
						
							|  |  |  |       } catch (e) {} | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2014-08-25 11:47:36 +08:00
										 |  |  |     res.set.call(this, this, val) | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-09 03:57:47 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2014-08-11 02:12:22 +08:00
										 |  |  |  * Delete a property on the VM | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * @param {String} key | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | exports.$delete = function (key) { | 
					
						
							| 
									
										
										
										
											2014-09-17 08:50:17 +08:00
										 |  |  |   this._data.$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 | 
					
						
							| 
									
										
										
										
											2014-08-29 07:02:32 +08:00
										 |  |  |  * value changes. | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2015-09-24 10:50:33 +08:00
										 |  |  |  * @param {String|Function} expOrFn | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  |  * @param {Function} cb | 
					
						
							| 
									
										
										
										
											2015-06-11 16:25:41 +08:00
										 |  |  |  * @param {Object} [options] | 
					
						
							|  |  |  |  *                 - {Boolean} deep | 
					
						
							|  |  |  |  *                 - {Boolean} immediate | 
					
						
							| 
									
										
										
										
											2014-08-29 09:55:32 +08:00
										 |  |  |  * @return {Function} - unwatchFn | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-24 10:50:33 +08:00
										 |  |  | exports.$watch = function (expOrFn, cb, options) { | 
					
						
							| 
									
										
										
										
											2014-08-29 09:55:32 +08:00
										 |  |  |   var vm = this | 
					
						
							| 
									
										
										
										
											2015-09-24 10:50:33 +08:00
										 |  |  |   var parsed | 
					
						
							|  |  |  |   if (typeof expOrFn === 'string') { | 
					
						
							|  |  |  |     parsed = dirParser.parse(expOrFn) | 
					
						
							|  |  |  |     expOrFn = parsed.expression | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   var watcher = new Watcher(vm, expOrFn, cb, { | 
					
						
							| 
									
										
										
										
											2015-06-11 16:25:41 +08:00
										 |  |  |     deep: options && options.deep, | 
					
						
							| 
									
										
										
										
											2015-09-24 10:50:33 +08:00
										 |  |  |     filters: parsed && parsed.filters | 
					
						
							| 
									
										
										
										
											2015-05-27 08:55:27 +08:00
										 |  |  |   }) | 
					
						
							| 
									
										
										
										
											2015-06-11 16:25:41 +08:00
										 |  |  |   if (options && options.immediate) { | 
					
						
							| 
									
										
										
										
											2015-08-17 06:06:24 +08:00
										 |  |  |     cb.call(vm, watcher.value) | 
					
						
							| 
									
										
										
										
											2014-08-18 02:13:52 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-08-29 09:55:32 +08:00
										 |  |  |   return function unwatchFn () { | 
					
						
							| 
									
										
										
										
											2015-05-27 08:55:27 +08:00
										 |  |  |     watcher.teardown() | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2015-09-15 23:09:19 +08:00
										 |  |  |  * @param {Boolean} [asStatement] | 
					
						
							| 
									
										
										
										
											2014-08-11 10:17:30 +08:00
										 |  |  |  * @return {String} | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-15 23:09:19 +08:00
										 |  |  | exports.$eval = function (text, asStatement) { | 
					
						
							| 
									
										
										
										
											2014-08-11 10:17:30 +08:00
										 |  |  |   // check for filters.
 | 
					
						
							|  |  |  |   if (filterRE.test(text)) { | 
					
						
							| 
									
										
										
										
											2015-09-03 04:43:18 +08:00
										 |  |  |     var dir = dirParser.parse(text) | 
					
						
							| 
									
										
										
										
											2014-08-11 10:17:30 +08:00
										 |  |  |     // the filter regex check might give false positive
 | 
					
						
							|  |  |  |     // for pipes inside strings, so it's possible that
 | 
					
						
							|  |  |  |     // we don't get any filters here
 | 
					
						
							| 
									
										
										
										
											2015-09-15 23:09:19 +08:00
										 |  |  |     var val = this.$get(dir.expression, asStatement) | 
					
						
							| 
									
										
										
										
											2014-08-11 10:17:30 +08:00
										 |  |  |     return dir.filters | 
					
						
							| 
									
										
										
										
											2015-05-29 03:13:35 +08:00
										 |  |  |       ? this._applyFilters(val, null, dir.filters) | 
					
						
							|  |  |  |       : val | 
					
						
							| 
									
										
										
										
											2014-08-11 10:17:30 +08:00
										 |  |  |   } else { | 
					
						
							|  |  |  |     // no filter
 | 
					
						
							| 
									
										
										
										
											2015-09-15 23:09:19 +08:00
										 |  |  |     return this.$get(text, asStatement) | 
					
						
							| 
									
										
										
										
											2014-08-11 10:17:30 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2015-09-24 03:32:27 +08:00
										 |  |  |     if (tokens.length === 1) { | 
					
						
							| 
									
										
										
										
											2015-09-24 03:38:38 +08:00
										 |  |  |       return vm.$eval(tokens[0].value) + '' | 
					
						
							| 
									
										
										
										
											2015-09-24 03:32:27 +08:00
										 |  |  |     } else { | 
					
						
							|  |  |  |       return 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. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2014-11-06 12:29:50 +08:00
										 |  |  |  * @param {String} [path] | 
					
						
							| 
									
										
										
										
											2014-08-11 01:32:54 +08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-06 12:29:50 +08:00
										 |  |  | exports.$log = function (path) { | 
					
						
							|  |  |  |   var data = path | 
					
						
							| 
									
										
										
										
											2014-12-01 03:22:46 +08:00
										 |  |  |     ? Path.get(this._data, path) | 
					
						
							| 
									
										
										
										
											2014-11-06 12:29:50 +08:00
										 |  |  |     : this._data | 
					
						
							| 
									
										
										
										
											2014-12-01 03:22:46 +08:00
										 |  |  |   if (data) { | 
					
						
							| 
									
										
										
										
											2015-09-06 04:52:08 +08:00
										 |  |  |     data = clean(data) | 
					
						
							| 
									
										
										
										
											2014-12-01 03:22:46 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-06 04:35:21 +08:00
										 |  |  |   // include computed fields
 | 
					
						
							|  |  |  |   if (!path) { | 
					
						
							|  |  |  |     for (var key in this.$options.computed) { | 
					
						
							| 
									
										
										
										
											2015-09-06 04:52:08 +08:00
										 |  |  |       data[key] = clean(this[key]) | 
					
						
							| 
									
										
										
										
											2015-09-06 04:35:21 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-12-01 03:22:46 +08:00
										 |  |  |   console.log(data) | 
					
						
							| 
									
										
										
										
											2015-06-11 16:25:41 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-09-06 04:52:08 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * "clean" a getter/setter converted object into a plain | 
					
						
							|  |  |  |  * object copy. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * @param {Object} - obj | 
					
						
							|  |  |  |  * @return {Object} | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function clean (obj) { | 
					
						
							|  |  |  |   return JSON.parse(JSON.stringify(obj)) | 
					
						
							|  |  |  | } |