| 
									
										
										
										
											2015-12-26 23:21:14 +03:00
										 |  |  | /********************************************************************** | 
					
						
							|  |  |  | *  | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | **********************************************************************/ | 
					
						
							| 
									
										
										
										
											2016-08-21 02:19:24 +03:00
										 |  |  | ((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define) | 
					
						
							|  |  |  | (function(require){ var module={} // make module AMD/node compatible...
 | 
					
						
							| 
									
										
										
										
											2016-08-20 22:49:36 +03:00
										 |  |  | /*********************************************************************/ | 
					
						
							| 
									
										
										
										
											2015-12-26 23:21:14 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-19 19:55:11 +03:00
										 |  |  | if(typeof(window) == 'undefined'){ | 
					
						
							|  |  |  | 	return | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-26 23:21:14 +03:00
										 |  |  | //var DEBUG = DEBUG != null ? DEBUG : true
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var object = require('lib/object') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // convert a transform string to an object...
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Format:
 | 
					
						
							|  |  |  | // 	{
 | 
					
						
							|  |  |  | // 		<func>: [<arg>, ...],
 | 
					
						
							|  |  |  | // 		...
 | 
					
						
							|  |  |  | // 	}
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // NOTE: this does not care about the semantics of the format, just the 
 | 
					
						
							|  |  |  | // 		general structure...
 | 
					
						
							|  |  |  | var transform2obj = function(str){ | 
					
						
							|  |  |  | 	var res = {} | 
					
						
							|  |  |  | 	str = str || '' | 
					
						
							|  |  |  | 	// parse the string...
 | 
					
						
							|  |  |  | 	str | 
					
						
							|  |  |  | 		// split functions...
 | 
					
						
							|  |  |  | 		.split(/(\w+\([^\)]*)\)/) | 
					
						
							|  |  |  | 		// remove empty strings...
 | 
					
						
							|  |  |  | 		.filter(function(e){ return e.trim().length > 0}) | 
					
						
							|  |  |  | 		// split each function...
 | 
					
						
							|  |  |  | 		.map(function(e){ return e | 
					
						
							|  |  |  | 			// split args...
 | 
					
						
							|  |  |  | 			.split(/\s*[\(,\s]\s*/) | 
					
						
							|  |  |  | 			// cleanup...
 | 
					
						
							|  |  |  | 			.filter(function(e){ return e.trim().length > 0 }) }) | 
					
						
							|  |  |  | 		// build the structure...
 | 
					
						
							|  |  |  | 		.forEach(function(data){ | 
					
						
							|  |  |  | 			var func = data.shift()  | 
					
						
							|  |  |  | 			var args = data | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			res[func] = data | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	return res | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Convert the object similar in structure to the produced by 
 | 
					
						
							|  |  |  | // transform2obj(..) to a transform string...
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // NOTE: this does not care about the actual semantics of the format, 
 | 
					
						
							|  |  |  | // 		e.g. argument units or function names...
 | 
					
						
							|  |  |  | var obj2transform = function(obj, filter){ | 
					
						
							|  |  |  | 	// build the filters...
 | 
					
						
							|  |  |  | 	filter = filter || [] | 
					
						
							|  |  |  | 	var keep = filter | 
					
						
							|  |  |  | 		.filter(function(f){ return f[0] != '-' })  | 
					
						
							|  |  |  | 	var remove = filter | 
					
						
							|  |  |  | 		.filter(function(f){ return f[0] == '-' }) | 
					
						
							|  |  |  | 		.map(function(f){ return f.slice(1) }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return Object.keys(obj) | 
					
						
							|  |  |  | 		// keep...
 | 
					
						
							|  |  |  | 		.filter(function(func){  | 
					
						
							|  |  |  | 			return keep.length == 0 || keep.indexOf(func) >= 0 }) | 
					
						
							|  |  |  | 		// remove...
 | 
					
						
							|  |  |  | 		.filter(function(func){  | 
					
						
							|  |  |  | 			return remove.indexOf(func) < 0 }) | 
					
						
							|  |  |  | 		.map(function(func){ | 
					
						
							|  |  |  | 			return func +'('+ obj[func].join(', ') + ')' | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 		.join(' ') | 
					
						
							|  |  |  | }  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // XXX BUG: passing '' to an alias will clear ALL the aliased functions...
 | 
					
						
							|  |  |  | // 		...should clear only full matches...
 | 
					
						
							|  |  |  | // XXX BUG: passing '' to a multi-arg function will clear the args but 
 | 
					
						
							|  |  |  | // 		still keep the function...
 | 
					
						
							|  |  |  | // XXX BUG: setting a single arg alias will return string results...
 | 
					
						
							|  |  |  | // 			.x(123)		-> ['123px']	-> must be [123]
 | 
					
						
							|  |  |  | // 			.x()		-> [123]
 | 
					
						
							|  |  |  | // 			.translate3d(1,2,3)
 | 
					
						
							|  |  |  | // 						-> [1, 2, 3]
 | 
					
						
							|  |  |  | // 		NOTE: both set data correctly...
 | 
					
						
							| 
									
										
										
										
											2015-12-28 07:09:06 +03:00
										 |  |  | // XXX add argument in place operations...
 | 
					
						
							|  |  |  | // 		+=
 | 
					
						
							|  |  |  | // 		-=
 | 
					
						
							|  |  |  | // 		*=
 | 
					
						
							|  |  |  | // 		/=
 | 
					
						
							| 
									
										
										
										
											2015-12-26 23:21:14 +03:00
										 |  |  | // XXX move the grammar out of this...
 | 
					
						
							|  |  |  | // XXX need:
 | 
					
						
							|  |  |  | // 		- a way to minimize this, i.e. get only full and minimal functions...
 | 
					
						
							|  |  |  | // 		- a way to get what was defined as-is...
 | 
					
						
							|  |  |  | // XXX STUB: .simplify(..) should be rewritten and be configurable...
 | 
					
						
							|  |  |  | // 		...preferable work on write -- set the alias that already esists
 | 
					
						
							|  |  |  | // 		and ignore the rest...
 | 
					
						
							|  |  |  | // XXX make aliases collect and merge data, e.g. asking for scale with 
 | 
					
						
							|  |  |  | // 		scaleX and scaleY set should return the combination of the two 
 | 
					
						
							|  |  |  | // 		results...
 | 
					
						
							|  |  |  | // XXX not critical yet but will need to support for completeness...
 | 
					
						
							|  |  |  | //		- transformStyle 
 | 
					
						
							|  |  |  | //		- prespective 
 | 
					
						
							|  |  |  | //		- prespectiveOrigin 
 | 
					
						
							|  |  |  | //		- backfaceVisibility
 | 
					
						
							|  |  |  | // XXX add transitions...
 | 
					
						
							|  |  |  | // XXX add support for vendor tags...
 | 
					
						
							|  |  |  | var transformEditor = function(){ | 
					
						
							|  |  |  | 	var editor = { | 
					
						
							|  |  |  | 		// data set...
 | 
					
						
							|  |  |  | 		data: {}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// function that directly edit the data...
 | 
					
						
							|  |  |  | 		__direct: {}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// methods...
 | 
					
						
							|  |  |  | 		// XXX generate this...
 | 
					
						
							|  |  |  | 		simplify: function(filter){ | 
					
						
							| 
									
										
										
										
											2015-12-28 07:09:06 +03:00
										 |  |  | 			var data = this.data | 
					
						
							| 
									
										
										
										
											2015-12-26 23:21:14 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// scale...
 | 
					
						
							|  |  |  | 			if(data.scale  | 
					
						
							|  |  |  | 					&& data.scale[0] == 1  | 
					
						
							|  |  |  | 					&& data.scale[1] == 1){ delete data.scale } | 
					
						
							|  |  |  | 			if((data.scaleX||[1])[0] == 1){ delete data.scaleX } | 
					
						
							|  |  |  | 			if((data.scaleY||[1])[0] == 1){ delete data.scaleY } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// translate...
 | 
					
						
							|  |  |  | 			if(data.translate  | 
					
						
							|  |  |  | 					&& data.translate.len == 2  | 
					
						
							|  |  |  | 					&& parseFloat(data.translate[0]) == 0  | 
					
						
							|  |  |  | 					&& parseFloat(data.translate[1]) == 0){ delete data.translate } | 
					
						
							|  |  |  | 			if(data.translate3d | 
					
						
							|  |  |  | 					&& data.translate3d.len == 3  | 
					
						
							|  |  |  | 					&& parseFloat(data.translate3d[0]) == 0  | 
					
						
							|  |  |  | 					&& parseFloat(data.translate3d[1]) == 1 | 
					
						
							|  |  |  | 					&& parseFloat(data.translate3d[2]) == 1){ delete data.translate3d } | 
					
						
							|  |  |  | 			if(parseFloat((data.translateX||[1])[0]) == 0){ delete data.translateX } | 
					
						
							|  |  |  | 			if(parseFloat((data.translateY||[1])[0]) == 0){ delete data.translateY } | 
					
						
							|  |  |  | 			if(parseFloat((data.translateZ||[1])[0]) == 0){ delete data.translateZ } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// XXX rotate...
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// XXX skew...
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return this.data | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		toString: function(){  | 
					
						
							|  |  |  | 			//return obj2transform(this.data, args2array(arguments)) 
 | 
					
						
							|  |  |  | 			var args = args2array(arguments) | 
					
						
							|  |  |  | 			return obj2transform(this.simplify(args), args)  | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// NOTE: this will not build the alias data...
 | 
					
						
							|  |  |  | 		fromString: function(str){  | 
					
						
							|  |  |  | 			this.data = transform2obj(str)  | 
					
						
							|  |  |  | 			return this | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// XXX use vendor prefix...
 | 
					
						
							|  |  |  | 		toElem: function(elem){ | 
					
						
							|  |  |  | 			var origin = this.data.origin || '' | 
					
						
							|  |  |  | 			var transform = this.toString('-origin') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			elem = elem instanceof jQuery ? elem.toArray()  | 
					
						
							|  |  |  | 				: elem instanceof Array ? elem | 
					
						
							|  |  |  | 				: [elem] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-13 02:45:54 +03:00
										 |  |  | 			var e | 
					
						
							|  |  |  | 			for(var i = 0; i < elem.length; i++){ | 
					
						
							|  |  |  | 				e = elem[i] | 
					
						
							|  |  |  | 				e.style.transformOrigin = origin.join ? origin.join(' ') : origin | 
					
						
							|  |  |  | 				e.style.transform = transform | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			/* | 
					
						
							| 
									
										
										
										
											2015-12-26 23:21:14 +03:00
										 |  |  | 			elem.forEach(function(e){ | 
					
						
							|  |  |  | 				e.style.transformOrigin = origin.join ? origin.join(' ') : origin | 
					
						
							|  |  |  | 				e.style.transform = transform | 
					
						
							|  |  |  | 			}) | 
					
						
							| 
									
										
										
										
											2016-05-13 02:45:54 +03:00
										 |  |  | 			*/ | 
					
						
							| 
									
										
										
										
											2015-12-26 23:21:14 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			return this | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// get data by attr names...
 | 
					
						
							|  |  |  | 		get: function(){ | 
					
						
							|  |  |  | 			var that = this | 
					
						
							|  |  |  | 			var attrs = arguments[0] instanceof Array ? | 
					
						
							|  |  |  | 				arguments[0]  | 
					
						
							|  |  |  | 				: args2array(arguments) | 
					
						
							|  |  |  | 			var res = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			attrs.forEach(function(a){ | 
					
						
							|  |  |  | 				if(!(a in that)){ | 
					
						
							|  |  |  | 					return | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				var v = that[a]() | 
					
						
							|  |  |  | 				v = v.length == 1 ? v.pop()  | 
					
						
							|  |  |  | 					: v.length == 0 ? undefined | 
					
						
							|  |  |  | 					: v | 
					
						
							|  |  |  | 				res[a] = v | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(attrs.length == 1){ | 
					
						
							|  |  |  | 				return res[attrs[0]] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return res | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// XXX use vendor prefix...
 | 
					
						
							|  |  |  | 		__init__: function(str){ | 
					
						
							|  |  |  | 			this.data = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(str != null){ | 
					
						
							|  |  |  | 				if(str instanceof jQuery){ | 
					
						
							|  |  |  | 					str = str[0] | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if(str instanceof HTMLElement){ | 
					
						
							|  |  |  | 					var origin = str.style.transformOrigin | 
					
						
							|  |  |  | 					origin = origin.length > 0 ? ' origin('+ origin +')' : '' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					str = str.style.transform + origin | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				this.fromString(str) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var func = function(name, args, neutral){ | 
					
						
							|  |  |  | 		args = args || [] | 
					
						
							|  |  |  | 		editor.__direct[name] = function(val){ | 
					
						
							|  |  |  | 			var that = this | 
					
						
							|  |  |  | 			// set...
 | 
					
						
							|  |  |  | 			if(val != null && val != ''){ | 
					
						
							|  |  |  | 				val = val instanceof Array ? val : [val] | 
					
						
							|  |  |  | 				var data = this.data[name] = this.data[name] || [] | 
					
						
							|  |  |  | 				var res = [] | 
					
						
							|  |  |  | 				// add units and general processing...
 | 
					
						
							|  |  |  | 				val.map(function(arg, i){ | 
					
						
							|  |  |  | 					// special case, if an arg is undefined do not change it...
 | 
					
						
							|  |  |  | 					if(arg === undefined){ | 
					
						
							|  |  |  | 						return  | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					var unit = args[i] || '' | 
					
						
							|  |  |  | 					data[i] = typeof(arg) == typeof(123)  | 
					
						
							|  |  |  | 							|| (typeof(arg) == typeof('str')  | 
					
						
							|  |  |  | 								&& /^[0-9\.]+$/.test(arg)) ? arg + unit | 
					
						
							|  |  |  | 						: arg == '' ? neutral + unit | 
					
						
							|  |  |  | 						: arg | 
					
						
							|  |  |  | 					res[i] = arg | 
					
						
							|  |  |  | 				}) | 
					
						
							|  |  |  | 				return res | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// delete...
 | 
					
						
							|  |  |  | 			} else if(val == ''){ | 
					
						
							|  |  |  | 				delete this.data[name] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// get...
 | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				var res = (this.data[name] || []) | 
					
						
							|  |  |  | 					// remove default unit...
 | 
					
						
							|  |  |  | 					.map(function(arg, i){ | 
					
						
							|  |  |  | 						var unit = args[i] || '' | 
					
						
							|  |  |  | 						return arg.slice(-unit.length) == unit  | 
					
						
							|  |  |  | 								|| /^[0-9\.]+$/.test(arg)? | 
					
						
							|  |  |  | 							parseFloat(arg) | 
					
						
							|  |  |  | 							: arg | 
					
						
							|  |  |  | 					}) | 
					
						
							|  |  |  | 				return res | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	var alias = function(spec, reduce, mode){ | 
					
						
							|  |  |  | 		reduce = reduce || 'last' | 
					
						
							|  |  |  | 		// can be:
 | 
					
						
							|  |  |  | 		// 	'first'
 | 
					
						
							|  |  |  | 		// 	'last'
 | 
					
						
							|  |  |  | 		// 	'all'
 | 
					
						
							|  |  |  | 		mode = mode || 'first' | 
					
						
							|  |  |  | 		// alias runner...
 | 
					
						
							|  |  |  | 		var handler = function(alias, args){ | 
					
						
							|  |  |  | 			var that = this | 
					
						
							|  |  |  | 			// we only care for the source argument and only it will get
 | 
					
						
							|  |  |  | 			// passed next...
 | 
					
						
							|  |  |  | 			// NOTE: this is the name of the called alias...
 | 
					
						
							|  |  |  | 			var arg = args[spec[alias]] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var aliases = Object.keys(spec) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var r = reduce == 'sum' ? function(a, b){ return a + b } | 
					
						
							|  |  |  | 				: reduce == 'mul' ? function(a, b){ return a * b } | 
					
						
							|  |  |  | 				: reduce == 'last' ? function(a, b){ return b != null ? b : a } | 
					
						
							|  |  |  | 				: reduce | 
					
						
							|  |  |  | 			var n = reduce == 'sum' ? 0 | 
					
						
							|  |  |  | 				: reduce == 'mul' ? 1 | 
					
						
							|  |  |  | 				: 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return aliases.map(function(k, j){ | 
					
						
							|  |  |  | 					var i = spec[k] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					// get state...
 | 
					
						
							|  |  |  | 					if(args.length == 0){ | 
					
						
							|  |  |  | 						var res = k in that.__direct ?  | 
					
						
							|  |  |  | 							that.__direct[k].call(that)  | 
					
						
							|  |  |  | 							: null | 
					
						
							|  |  |  | 						return res != null ? res[i] : res | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					// prepare arguments...
 | 
					
						
							|  |  |  | 					var a = [] | 
					
						
							|  |  |  | 					a[i] = mode == 'first' && j == 0 ? arg | 
					
						
							|  |  |  | 						: mode == 'last' && j == aliases.length - 1 ? arg | 
					
						
							|  |  |  | 						: reduce == 'sum' ? 0 | 
					
						
							|  |  |  | 						: reduce == 'mul' ? 1 | 
					
						
							|  |  |  | 						: arg | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					// do the call...
 | 
					
						
							|  |  |  | 					var res = k in that.__direct ? | 
					
						
							|  |  |  | 						that.__direct[k].call(that, a)  | 
					
						
							|  |  |  | 						: null | 
					
						
							|  |  |  | 					return res != null ? res[i] : res | 
					
						
							|  |  |  | 				}) | 
					
						
							|  |  |  | 				.filter(function(e){ return e != null }) | 
					
						
							|  |  |  | 				.reduce(r, n) | 
					
						
							|  |  |  | 				// XXX for some magical reason this breaks if...
 | 
					
						
							|  |  |  | 				// 		t = transformEditor($('.ribbon-set'))
 | 
					
						
							|  |  |  | 				// 		t.x()	// works ok
 | 
					
						
							|  |  |  | 				// 		var x = t.data
 | 
					
						
							|  |  |  | 				// 		t.x()	// now this breaks because reduce is 0...
 | 
					
						
							|  |  |  | 				 /* | 
					
						
							|  |  |  | 				.reduce(reduce == 'sum' ? function(a, b){ return a + b } | 
					
						
							|  |  |  | 						: reduce == 'mul' ? function(a, b){ return a * b } | 
					
						
							|  |  |  | 						: reduce == 'last' ? function(a, b){ return b != null ? b : a } | 
					
						
							|  |  |  | 						: reduce, | 
					
						
							|  |  |  | 					reduce == 'mul' ? 1 | 
					
						
							|  |  |  | 						: reduce = 'sum'? 0 | 
					
						
							|  |  |  | 						: 0) | 
					
						
							|  |  |  | 				 */ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// setup the aliases...
 | 
					
						
							|  |  |  | 		var aliases = Object.keys(spec) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		mode == 'last' && aliases.reverse() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		aliases.forEach(function(k){ | 
					
						
							|  |  |  | 			var i = spec[k] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var func = i instanceof Function ? i : handler | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// NOTE: we will pass the called alias name to the handler 
 | 
					
						
							|  |  |  | 			// 		via 'this'...
 | 
					
						
							|  |  |  | 			var f = editor[k] | 
					
						
							|  |  |  | 			var alias = editor[k] = f ?  | 
					
						
							|  |  |  | 				// wrap the original alias...
 | 
					
						
							|  |  |  | 				// NOTE: this will iterate the overloaded aliases... 
 | 
					
						
							|  |  |  | 				// 		i.e. this will iterate the arguments (width) while 
 | 
					
						
							|  |  |  | 				// 		the handler(..) will iterate the aliases...
 | 
					
						
							|  |  |  | 				function(){ | 
					
						
							|  |  |  | 					var args = args2array(arguments) | 
					
						
							|  |  |  | 					// XXX do a full search through the alias values and merge results...
 | 
					
						
							|  |  |  | 					if(args.length == 0 && k in this.__direct){ | 
					
						
							|  |  |  | 						return this.__direct[k].call(this) | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					var a = f.apply(this, args) | 
					
						
							|  |  |  | 					var b = func.call(this, k, args) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if(k in this.__direct){ | 
					
						
							|  |  |  | 						return this.__direct[k].call(this) | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					return b | 
					
						
							|  |  |  | 				}  | 
					
						
							|  |  |  | 				: function(){  | 
					
						
							|  |  |  | 					var args = args2array(arguments) | 
					
						
							|  |  |  | 					return func.call(this, k, args)  | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			alias.isAlias = true | 
					
						
							|  |  |  | 			alias.reduce = reduce | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// XXX get these from grammar...
 | 
					
						
							| 
									
										
										
										
											2015-12-28 07:09:06 +03:00
										 |  |  | 	// The Grammar...
 | 
					
						
							| 
									
										
										
										
											2015-12-26 23:21:14 +03:00
										 |  |  | 	func('translate', ['px', 'px'], 0) | 
					
						
							|  |  |  | 	func('translate3d', ['px', 'px', 'px'], 0) | 
					
						
							|  |  |  | 	func('translateX', ['px'], 0) | 
					
						
							|  |  |  | 	func('translateY', ['px'], 0) | 
					
						
							|  |  |  | 	func('translateZ', ['px'], 0) | 
					
						
							|  |  |  | 	alias({ translate3d: 0, translate: 0, translateX: 0, x: 0 }, 'sum') | 
					
						
							|  |  |  | 	alias({ translate3d: 1, translate: 1, translateY: 0, y: 0, }, 'sum') | 
					
						
							|  |  |  | 	alias({ translate3d: 2, translateZ: 0, z: 0, }, 'sum')  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	func('scale', ['', ''], 1) | 
					
						
							|  |  |  | 	//func('scale3d', ['', '', ''])
 | 
					
						
							|  |  |  | 	func('scaleX', [''], 1) | 
					
						
							|  |  |  | 	func('scaleY', [''], 1) | 
					
						
							|  |  |  | 	//func('scaleZ')
 | 
					
						
							|  |  |  | 	alias({ scale: 0, /*scale3d: 0,*/ scaleX: 0, }, 'mul') | 
					
						
							|  |  |  | 	alias({ scale: 1, /*scale3d: 1,*/ scaleY: 0, }, 'mul') | 
					
						
							|  |  |  | 	//alias({ scale3d: 2, scaleZ: 0, }, 'mul')
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// special case: single arg scale: scale(n) -> scale(n, n)
 | 
					
						
							|  |  |  | 	editor._scale = editor.scale | 
					
						
							|  |  |  | 	editor.scale = function(){ | 
					
						
							|  |  |  | 		if(arguments.length == 1  | 
					
						
							|  |  |  | 				&& arguments[0] != ''  | 
					
						
							|  |  |  | 				&& arguments[0] != '='){ | 
					
						
							|  |  |  | 			return this._scale.call(this, arguments[0], arguments[0]) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		var res = this._scale.apply(this, arguments) | 
					
						
							|  |  |  | 		// is this correct here???
 | 
					
						
							|  |  |  | 		return res.length == 2 && res[0] == res[1] ? res[0] : res | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	func('rotate', ['deg'], 0) | 
					
						
							|  |  |  | 	func('rotate3d', ['px', 'px', 'px', 'deg'], 0) | 
					
						
							|  |  |  | 	func('rotateX', ['deg'], 0) | 
					
						
							|  |  |  | 	func('rotateY', ['deg'], 0) | 
					
						
							|  |  |  | 	func('rotateZ', ['deg'], 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	func('matrix') // XXX ???
 | 
					
						
							|  |  |  | 	func('matrix3d', [ | 
					
						
							|  |  |  | 		'', '', '', '', | 
					
						
							|  |  |  | 		'', '', '', '', | 
					
						
							|  |  |  | 		'', '', '', '', | 
					
						
							|  |  |  | 		'', '', '', '', | 
					
						
							|  |  |  | 	]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	func('skew', ['', ''], 0) | 
					
						
							|  |  |  | 	func('skewX', [''], 0) | 
					
						
							|  |  |  | 	func('skewY', [''], 0) | 
					
						
							|  |  |  | 	alias({skewX: 0, skew: 0}, 'sum') | 
					
						
							|  |  |  | 	alias({skewY: 0, skew: 1}, 'sum') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	func('perspective') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// non-transform functions...
 | 
					
						
							|  |  |  | 	func('origin', ['px', 'px', 'px'], 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// proxy the undefined in aliases functions...
 | 
					
						
							|  |  |  | 	Object.keys(editor.__direct).forEach(function(k){ | 
					
						
							|  |  |  | 		if(!(k in editor)){ | 
					
						
							|  |  |  | 			editor[k] = function(){  | 
					
						
							|  |  |  | 				var args = args2array(arguments) | 
					
						
							|  |  |  | 				editor.__direct[k].apply(this, args.length > 0 ? [args]: []) | 
					
						
							|  |  |  | 				return editor.__direct[k].call(this) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return editor | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var TransformEditor =  | 
					
						
							|  |  |  | module.TransformEditor = | 
					
						
							|  |  |  | object.makeConstructor('TransformEditor', transformEditor()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // XXX STUB: for testing only...
 | 
					
						
							|  |  |  | window.transformEditor = TransformEditor | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // jQuery API for the TransformEditor...
 | 
					
						
							|  |  |  | jQuery.fn.transform = function(){ | 
					
						
							| 
									
										
										
										
											2016-05-13 02:45:54 +03:00
										 |  |  | 	var e = $(this) | 
					
						
							|  |  |  | 	var elem = e[0] | 
					
						
							| 
									
										
										
										
											2015-12-26 23:21:14 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	var args = args2array(arguments) | 
					
						
							|  |  |  | 	// normalize...
 | 
					
						
							|  |  |  | 	args = args.length == 0  | 
					
						
							|  |  |  | 			|| typeof(args[0]) == typeof('str') ? args | 
					
						
							|  |  |  | 		: args[0].constructor === Array  | 
					
						
							|  |  |  | 			|| args.length == 1 ? args[0] | 
					
						
							|  |  |  | 		: args | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// load the current state...
 | 
					
						
							|  |  |  | 	var transform = TransformEditor(elem) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// get state...
 | 
					
						
							|  |  |  | 	if(args.constructor === Array){ | 
					
						
							|  |  |  | 		if(args.length == 0){ | 
					
						
							|  |  |  | 			// XXX get all attrs...
 | 
					
						
							|  |  |  | 			// XXX
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// get requested attrs...
 | 
					
						
							|  |  |  | 		return transform.get(args) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// set state...
 | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2016-05-13 02:45:54 +03:00
										 |  |  | 		var v | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-26 23:21:14 +03:00
										 |  |  | 		// load user inputs...
 | 
					
						
							| 
									
										
										
										
											2016-05-13 02:45:54 +03:00
										 |  |  | 		for(var k in args){ | 
					
						
							| 
									
										
										
										
											2015-12-26 23:21:14 +03:00
										 |  |  | 			if(!(k in transform)){ | 
					
						
							| 
									
										
										
										
											2016-05-13 02:45:54 +03:00
										 |  |  | 				continue | 
					
						
							| 
									
										
										
										
											2015-12-26 23:21:14 +03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-05-13 02:45:54 +03:00
										 |  |  | 			v = args[k] | 
					
						
							| 
									
										
										
										
											2015-12-26 23:21:14 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-13 02:45:54 +03:00
										 |  |  | 			transform[k].apply(transform, v instanceof Array ? v : [v]) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-12-26 23:21:14 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		transform.toElem(this) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-13 02:45:54 +03:00
										 |  |  | 	return e | 
					
						
							| 
									
										
										
										
											2015-12-26 23:21:14 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // shorthands...
 | 
					
						
							|  |  |  | jQuery.fn.scale = function(value){ | 
					
						
							|  |  |  | 	if(arguments.length > 0){ | 
					
						
							|  |  |  | 		return $(this).transform({scale: args2array(arguments)}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		return $(this).transform('scale') | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | // get element scale... 
 | 
					
						
							|  |  |  | jQuery.fn.rscale = function(){ | 
					
						
							|  |  |  | 	var res = 1 | 
					
						
							|  |  |  | 	$(this).parents().toArray().forEach(function(e){ | 
					
						
							|  |  |  | 		res *= $(e).scale() || 1 | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	return res | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | jQuery.fn.origin = function(a, b, c){ | 
					
						
							|  |  |  | 	if(a != null && b != null){ | 
					
						
							|  |  |  | 		return $(this).transform({origin: [a, b, c == null ? 0 : c]}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else if(a == '' || a instanceof Array){ | 
					
						
							|  |  |  | 		return $(this).transform({origin: a}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		return $(this).transform('origin') | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /********************************************************************** | 
					
						
							| 
									
										
										
										
											2016-08-20 22:49:36 +03:00
										 |  |  | * vim:set ts=4 sw=4 :                               */ return module }) |