| 
									
										
										
										
											2015-12-17 03:34:20 +03:00
										 |  |  | /********************************************************************** | 
					
						
							|  |  |  | *  | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | **********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | define(function(require){ var module = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //var DEBUG = DEBUG != null ? DEBUG : true
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-19 09:34:22 +03:00
										 |  |  | // convert JS arguments to Array...
 | 
					
						
							|  |  |  | var args2array = | 
					
						
							|  |  |  | module.args2array = | 
					
						
							|  |  |  | function(args){ | 
					
						
							|  |  |  | 	//return Array.apply(null, args)
 | 
					
						
							|  |  |  | 	return [].slice.call(args) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-17 09:14:59 +03:00
										 |  |  | // Quote a string and convert to RegExp to match self literally.
 | 
					
						
							|  |  |  | var quoteRegExp = | 
					
						
							|  |  |  | module.quoteRegExp = | 
					
						
							|  |  |  | function(str){ | 
					
						
							|  |  |  | 	return str.replace(/([\.\\\/\(\)\[\]\$\*\+\-\{\}\@\^\&\?\<\>])/g, '\\$1') | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // XXX do we need to quote anything else???
 | 
					
						
							|  |  |  | var path2url = | 
					
						
							|  |  |  | module.path2url = | 
					
						
							|  |  |  | function(path){ | 
					
						
							|  |  |  | 	// test if we have a schema, and if yes return as-is...
 | 
					
						
							|  |  |  | 	if(/^(http|https|file|[\w-]*):[\\\/]{2}/.test(path)){ | 
					
						
							|  |  |  | 		return path | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// skip encoding windows drives...
 | 
					
						
							|  |  |  | 	var drive = path.split(/^([a-z]:[\\\/])/i) | 
					
						
							|  |  |  | 	path = drive.pop() | 
					
						
							|  |  |  | 	drive = drive.pop() || '' | 
					
						
							|  |  |  | 	return drive + (path | 
					
						
							|  |  |  | 		.split(/[\\\/]/g) | 
					
						
							|  |  |  | 		// XXX these are too aggressive...
 | 
					
						
							|  |  |  | 		//.map(encodeURI)
 | 
					
						
							|  |  |  | 		//.map(encodeURIComponent)
 | 
					
						
							|  |  |  | 		.join('/') | 
					
						
							|  |  |  | 		// NOTE: keep '%' the first...
 | 
					
						
							| 
									
										
										
										
											2015-12-18 07:55:14 +03:00
										 |  |  | 		//.replace(/%/g, '%25')
 | 
					
						
							| 
									
										
										
										
											2015-12-17 09:14:59 +03:00
										 |  |  | 		.replace(/#/g, '%23') | 
					
						
							|  |  |  | 		.replace(/&/g, '%26')) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-17 03:34:20 +03:00
										 |  |  | // NOTE: we are not using node's path module as we need this to work in
 | 
					
						
							|  |  |  | // 		all contexts, not only node... (???)
 | 
					
						
							|  |  |  | var normalizePath =  | 
					
						
							|  |  |  | module.normalizePath = | 
					
						
							|  |  |  | function(path){ | 
					
						
							|  |  |  | 	return typeof(path) == typeof('str') ? path | 
					
						
							|  |  |  | 			// normalize the slashes...
 | 
					
						
							|  |  |  | 			.replace(/(\/)/g, '/') | 
					
						
							|  |  |  | 			// remove duplicate '/'
 | 
					
						
							|  |  |  | 			.replace(/(\/)\1+/g, '/') | 
					
						
							|  |  |  | 			// remove trailing '/'
 | 
					
						
							|  |  |  | 			.replace(/\/+$/, '') | 
					
						
							|  |  |  | 			// take care of .
 | 
					
						
							|  |  |  | 			.replace(/\/\.\//g, '/') | 
					
						
							|  |  |  | 			.replace(/\/\.$/, '') | 
					
						
							|  |  |  | 			// take care of ..
 | 
					
						
							|  |  |  | 			.replace(/\/[^\/]+\/\.\.\//g, '/') | 
					
						
							|  |  |  | 			.replace(/\/[^\/]+\/\.\.$/, '') | 
					
						
							|  |  |  | 		: path | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-19 09:34:22 +03:00
										 |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var _transform_parse = { | 
					
						
							|  |  |  | 	// 2d transforms:
 | 
					
						
							|  |  |  | 	//martix: [],
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	translate: ['left|0', 'top|0'], | 
					
						
							|  |  |  | 	translateX: ['left'], | 
					
						
							|  |  |  | 	translateY: ['top'], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	scale: [ | 
					
						
							|  |  |  | 		['scale'], | 
					
						
							|  |  |  | 		['scaleX|scale', 'scaleY|scale'], | 
					
						
							|  |  |  | 	], | 
					
						
							|  |  |  | 	scaleX: ['scaleX'], | 
					
						
							|  |  |  | 	scaleY: ['scaleY'], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rotate: ['rotate'], | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	skew: ['skewX', 'skewY'], | 
					
						
							|  |  |  | 	skewX: ['skewX'], | 
					
						
							|  |  |  | 	skewY: ['skewY'], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// 3d transforms:
 | 
					
						
							|  |  |  | 	//martix3d: [],
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	translate3d: ['x|0', 'y|0', 'z|0'], | 
					
						
							|  |  |  | 	translateZ: ['z'], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	scale3d: ['scaleX', 'scaleY', 'scaleZ'], | 
					
						
							|  |  |  | 	scaleZ: ['scaleZ'], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// XXX
 | 
					
						
							|  |  |  | 	//rotate3d: [x, y, z, angle],
 | 
					
						
							|  |  |  | 	// 	rotateX
 | 
					
						
							|  |  |  | 	// 	rotateY
 | 
					
						
							|  |  |  | 	// 	rotateZ
 | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	perspective: ['perspective'], | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | var _transform_parse_rev = {} | 
					
						
							|  |  |  | Object.keys(_transform_parse).forEach(function(func){ | 
					
						
							|  |  |  | 	var args = _transform_parse[func] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// we got multiple signatures == merge...
 | 
					
						
							|  |  |  | 	if(!(args[0] instanceof Array)){ | 
					
						
							|  |  |  | 		args = [args] | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	args | 
					
						
							|  |  |  | 		// merge lists of args...
 | 
					
						
							|  |  |  | 		.reduce(function(a, b){ return [].concat.call(a, b) }) | 
					
						
							|  |  |  | 		.unique() | 
					
						
							|  |  |  | 		// split alternatives...
 | 
					
						
							|  |  |  | 		.map(function(a){ return a.split(/\|/g) }) | 
					
						
							|  |  |  | 		.forEach(function(a){ | 
					
						
							|  |  |  | 			var arg = a[0] | 
					
						
							|  |  |  | 			var alt = a.slice(1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var e = _transform_parse_rev[arg] = _transform_parse_rev[arg] || {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			e.funcs = e.funcs || [] | 
					
						
							|  |  |  | 			e.funcs.indexOf(func) < 0 && e.funcs.push(func) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			e.alt = e.alt || [] | 
					
						
							|  |  |  | 			// XXX we explicitly support only one alternative now...
 | 
					
						
							|  |  |  | 			e.alt = e.alt.concat(alt).unique() | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // XXX get vendor...
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 
 | 
					
						
							|  |  |  | // 	Set element transform...
 | 
					
						
							|  |  |  | // 	.transform({..})
 | 
					
						
							|  |  |  | // 		-> element
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // 	Get element transform...
 | 
					
						
							|  |  |  | // 	.transform()
 | 
					
						
							|  |  |  | // 	.transform(<attr>[, ...])
 | 
					
						
							|  |  |  | // 	.transform([<attr>, ...])
 | 
					
						
							|  |  |  | // 		-> data
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Supported transformations:
 | 
					
						
							|  |  |  | // 	x/y
 | 
					
						
							|  |  |  | // 	scale
 | 
					
						
							|  |  |  | // 	scaleX/scaleY
 | 
					
						
							|  |  |  | // 	origin
 | 
					
						
							|  |  |  | // 	originX/originY
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // NOTE: pixel values are converted to numbers and back by default...
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // XXX this will get/set values only on the first element, is this correct???
 | 
					
						
							|  |  |  | // XXX how do we combine translate(..) and translate3d(..)???
 | 
					
						
							|  |  |  | jQuery.fn.transform = function(){ | 
					
						
							|  |  |  | 	var that = this | 
					
						
							|  |  |  | 	var args = args2array(arguments) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// XXX get the browser prefix...
 | 
					
						
							|  |  |  | 	var prefix = '' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// normalize...
 | 
					
						
							|  |  |  | 	args = args.length == 0  | 
					
						
							|  |  |  | 			|| typeof(args[0]) == typeof('str') ? args | 
					
						
							|  |  |  | 		: args[0].constructor === Array  | 
					
						
							|  |  |  | 			|| args.length == 1 ? args[0] | 
					
						
							|  |  |  | 		: args | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var elem = $(this)[0] | 
					
						
							|  |  |  | 	var origin_str = elem.style[prefix + 'transformOrigin'] | 
					
						
							|  |  |  | 	var transform_str = elem.style[prefix + 'transform'] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// build the current state...
 | 
					
						
							|  |  |  | 	// NOTE: we'll need this for both fetching (parsing) and writing 
 | 
					
						
							|  |  |  | 	// 		(checking)...
 | 
					
						
							|  |  |  | 	var transform = {} | 
					
						
							|  |  |  | 	var functions = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// origin...
 | 
					
						
							|  |  |  | 	var origin = origin_str | 
					
						
							|  |  |  | 		.split(/\s+/) | 
					
						
							|  |  |  | 		// XXX add this to transform...
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// transform...
 | 
					
						
							|  |  |  | 	transform_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 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// XXX do we care about function vendor tags here???
 | 
					
						
							|  |  |  | 			var spec = _transform_parse[func] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			functions[func] = args | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// we do not know this function...
 | 
					
						
							|  |  |  | 			if(spec == null){ | 
					
						
							|  |  |  | 				transform[func] = args | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				spec = spec[0] instanceof Array ? spec : [spec] | 
					
						
							|  |  |  | 				spec.forEach(function(s){  | 
					
						
							|  |  |  | 					// skip non-matching signatures...
 | 
					
						
							|  |  |  | 					// XXX is this correct???
 | 
					
						
							|  |  |  | 					if(s.length != args.length){ | 
					
						
							|  |  |  | 						return | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					s.forEach(function(e, i){  | 
					
						
							|  |  |  | 						// this is for things that have optional arguments
 | 
					
						
							|  |  |  | 						// like scale(..)
 | 
					
						
							|  |  |  | 						// XXX should we treat this in some special way???
 | 
					
						
							|  |  |  | 						if(args[i] == null){ | 
					
						
							|  |  |  | 							return | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						var alternatives = e.split(/\|/g) | 
					
						
							|  |  |  | 						var k = alternatives.shift().trim() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						transform[k] = args[i].slice(-2) == 'px'  | 
					
						
							|  |  |  | 								|| /[0-9\.]+/.test(args[i]) ? | 
					
						
							|  |  |  | 							parseFloat(args[i])  | 
					
						
							|  |  |  | 							: args[i]  | 
					
						
							|  |  |  | 					}) | 
					
						
							|  |  |  | 				}) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// get data...
 | 
					
						
							|  |  |  | 	if(args.constructor === Array){ | 
					
						
							|  |  |  | 		var res = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// return the full transform...
 | 
					
						
							|  |  |  | 		if(args.length == 0){ | 
					
						
							|  |  |  | 			return transform | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		args.forEach(function(arg){ | 
					
						
							|  |  |  | 			// direct match in shorthand data...
 | 
					
						
							|  |  |  | 			if(arg in transform){ | 
					
						
							|  |  |  | 				res[arg] = transform[arg] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// try and find an alias...
 | 
					
						
							|  |  |  | 			} else if(arg in _transform_parse_rev){ | 
					
						
							|  |  |  | 				var funcs = _transform_parse_rev[arg].funcs | 
					
						
							|  |  |  | 				var alt = _transform_parse_rev[arg].alt[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// no alternatives...
 | 
					
						
							|  |  |  | 				if(!alt){ | 
					
						
							|  |  |  | 					res[arg] = '' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// explicit number value...
 | 
					
						
							|  |  |  | 				} else if(/^[0-9\.]+$/.test(alt)){ | 
					
						
							|  |  |  | 					res[arg] = parseFloat(alt) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// explicit string value...
 | 
					
						
							|  |  |  | 				} else if(/^(['"]).*\1$/.test(alt)){ | 
					
						
							|  |  |  | 					res[arg] = alt.slice(1, -1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					var v = $(that).transform(alt) | 
					
						
							|  |  |  | 					res[arg] = v == '' ? alt : v | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// collect from function...
 | 
					
						
							|  |  |  | 			} else if(arg in _transform_parse){ | 
					
						
							|  |  |  | 				var v = res[arg] = {} | 
					
						
							|  |  |  | 				_transform_parse[arg].forEach(function(e){ | 
					
						
							|  |  |  | 					var alternatives = e.split(/\|/g) | 
					
						
							|  |  |  | 					var k = alternatives.shift().trim() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					v[k] = transform[k] != null ? transform[k] : '' | 
					
						
							|  |  |  | 				}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// don't know about this attr...
 | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				res[arg] = '' | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// special case: we asked for a single value...
 | 
					
						
							|  |  |  | 		if(args.length == 1){ | 
					
						
							|  |  |  | 			return res[args[0]] | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return res | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	// set data...
 | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		transform = Object.create(transform) | 
					
						
							|  |  |  | 		Object.keys(args).forEach(function(key){ | 
					
						
							|  |  |  | 			// the changing value already exists...
 | 
					
						
							|  |  |  | 			if(key in transform | 
					
						
							|  |  |  | 					// get one of the shorthand keys...
 | 
					
						
							|  |  |  | 					// NOTE: we might need to pack or re-pack the date but we 
 | 
					
						
							|  |  |  | 					// 		can't decide here...
 | 
					
						
							|  |  |  | 					|| key in _transform_parse_rev | 
					
						
							|  |  |  | 					// got one of the standard keys...
 | 
					
						
							|  |  |  | 					|| key in _transform_parse){ | 
					
						
							|  |  |  | 				transform[key] = args[key] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// key undefined...
 | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				console.warn('Ignoring key "%s".', key) | 
					
						
							|  |  |  | 				transform[key] = args[key] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		console.log('>>>>', transform) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// XXX set new values and resolve new functions...
 | 
					
						
							|  |  |  | 		// XXX
 | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// build the value string...
 | 
					
						
							|  |  |  | 		var transform_str = '' | 
					
						
							|  |  |  | 		for(var f in functions){ | 
					
						
							|  |  |  | 			transform_str += f +'(' | 
					
						
							|  |  |  | 				+(functions[f] | 
					
						
							|  |  |  | 					// XXX test if px value...
 | 
					
						
							|  |  |  | 					.map(function(e){ return typeof(e) == typeof(123) ? e + 'px' : e }) | 
					
						
							|  |  |  | 					.join(', '))+') ' | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		console.log(transform_str) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// XXX STUB
 | 
					
						
							|  |  |  | 		return functions | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// set the values...
 | 
					
						
							|  |  |  | 		elem.style.transform = transform_str | 
					
						
							|  |  |  | 		elem.style.transformOrigin = origin_str | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return $(this) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // shorthands...
 | 
					
						
							|  |  |  | jQuery.fn.scale = function(value){ | 
					
						
							|  |  |  | 	if(value){ | 
					
						
							|  |  |  | 		return $(this).transform({scale: value}) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		return $(this).transform('scale') | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | jQuery.fn.origin = function(value){ | 
					
						
							|  |  |  | 	if(value){ | 
					
						
							|  |  |  | 		return $(this).transform({origin: value}) | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		return $(this).transform('origin') | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-17 03:34:20 +03:00
										 |  |  | /********************************************************************** | 
					
						
							|  |  |  | * vim:set ts=4 sw=4 :                                                */ | 
					
						
							|  |  |  | return module }) |