syn-rails 3.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +7 -0
- data/Rakefile +1 -0
- data/lib/syn-rails.rb +11 -0
- data/lib/syn-rails/version.rb +5 -0
- data/syn-rails.gemspec +21 -0
- data/vendor/assets/javascripts/syn.js +2491 -0
- data/vendor/assets/javascripts/syn/browsers.js +321 -0
- data/vendor/assets/javascripts/syn/drag.js +321 -0
- data/vendor/assets/javascripts/syn/key.js +1055 -0
- data/vendor/assets/javascripts/syn/mouse.js +284 -0
- data/vendor/assets/javascripts/syn/synthetic.js +830 -0
- metadata +58 -0
| @@ -0,0 +1,321 @@ | |
| 1 | 
            +
            (function() {
         | 
| 2 | 
            +
            	
         | 
| 3 | 
            +
            	// check if elementFromPageExists
         | 
| 4 | 
            +
            	(function() {
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            		// document body has to exists for this test
         | 
| 7 | 
            +
            		if (!document.body ) {
         | 
| 8 | 
            +
            			setTimeout(arguments.callee, 1)
         | 
| 9 | 
            +
            			return;
         | 
| 10 | 
            +
            		}
         | 
| 11 | 
            +
            		var div = document.createElement('div')
         | 
| 12 | 
            +
            		document.body.appendChild(div);
         | 
| 13 | 
            +
            		Syn.helpers.extend(div.style, {
         | 
| 14 | 
            +
            			width: "100px",
         | 
| 15 | 
            +
            			height: "10000px",
         | 
| 16 | 
            +
            			backgroundColor: "blue",
         | 
| 17 | 
            +
            			position: "absolute",
         | 
| 18 | 
            +
            			top: "10px",
         | 
| 19 | 
            +
            			left: "0px",
         | 
| 20 | 
            +
            			zIndex: 19999
         | 
| 21 | 
            +
            		});
         | 
| 22 | 
            +
            		document.body.scrollTop = 11;
         | 
| 23 | 
            +
            		if (!document.elementFromPoint ) {
         | 
| 24 | 
            +
            			return;
         | 
| 25 | 
            +
            		}
         | 
| 26 | 
            +
            		var el = document.elementFromPoint(3, 1)
         | 
| 27 | 
            +
            		if ( el == div ) {
         | 
| 28 | 
            +
            			Syn.support.elementFromClient = true;
         | 
| 29 | 
            +
            		}
         | 
| 30 | 
            +
            		else {
         | 
| 31 | 
            +
            			Syn.support.elementFromPage = true;
         | 
| 32 | 
            +
            		}
         | 
| 33 | 
            +
            		document.body.removeChild(div);
         | 
| 34 | 
            +
            		document.body.scrollTop = 0;
         | 
| 35 | 
            +
            	})();
         | 
| 36 | 
            +
             | 
| 37 | 
            +
             | 
| 38 | 
            +
            	//gets an element from a point
         | 
| 39 | 
            +
            	var elementFromPoint = function( point, element ) {
         | 
| 40 | 
            +
            		var clientX = point.clientX,
         | 
| 41 | 
            +
            			clientY = point.clientY,
         | 
| 42 | 
            +
            			win = Syn.helpers.getWindow(element),
         | 
| 43 | 
            +
            			el;
         | 
| 44 | 
            +
             | 
| 45 | 
            +
             | 
| 46 | 
            +
             | 
| 47 | 
            +
            		if ( Syn.support.elementFromPage ) {
         | 
| 48 | 
            +
            			var off = Syn.helpers.scrollOffset(win);
         | 
| 49 | 
            +
            			clientX = clientX + off.left; //convert to pageX
         | 
| 50 | 
            +
            			clientY = clientY + off.top; //convert to pageY
         | 
| 51 | 
            +
            		}
         | 
| 52 | 
            +
            		el = win.document.elementFromPoint ? win.document.elementFromPoint(clientX, clientY) : element;
         | 
| 53 | 
            +
            		if ( el === win.document.documentElement && (point.clientY < 0 || point.clientX < 0) ) {
         | 
| 54 | 
            +
            			return element;
         | 
| 55 | 
            +
            		} else {
         | 
| 56 | 
            +
            			return el;
         | 
| 57 | 
            +
            		}
         | 
| 58 | 
            +
            	},
         | 
| 59 | 
            +
            		//creates an event at a certain point
         | 
| 60 | 
            +
            		createEventAtPoint = function( event, point, element ) {
         | 
| 61 | 
            +
            			var el = elementFromPoint(point, element)
         | 
| 62 | 
            +
            			Syn.trigger(event, point, el || element)
         | 
| 63 | 
            +
            			return el;
         | 
| 64 | 
            +
            		},
         | 
| 65 | 
            +
            		// creates a mousemove event, but first triggering mouseout / mouseover if appropriate
         | 
| 66 | 
            +
            		mouseMove = function( point, element, last ) {
         | 
| 67 | 
            +
            			var el = elementFromPoint(point, element)
         | 
| 68 | 
            +
            			if ( last != el && el && last ) {
         | 
| 69 | 
            +
            				var options = Syn.helpers.extend({}, point);
         | 
| 70 | 
            +
            				options.relatedTarget = el;
         | 
| 71 | 
            +
            				Syn.trigger("mouseout", options, last);
         | 
| 72 | 
            +
            				options.relatedTarget = last;
         | 
| 73 | 
            +
            				Syn.trigger("mouseover", options, el);
         | 
| 74 | 
            +
            			}
         | 
| 75 | 
            +
             | 
| 76 | 
            +
            			Syn.trigger("mousemove", point, el || element)
         | 
| 77 | 
            +
            			return el;
         | 
| 78 | 
            +
            		},
         | 
| 79 | 
            +
            		// start and end are in clientX, clientY
         | 
| 80 | 
            +
            		startMove = function( start, end, duration, element, callback ) {
         | 
| 81 | 
            +
            			var startTime = new Date(),
         | 
| 82 | 
            +
            				distX = end.clientX - start.clientX,
         | 
| 83 | 
            +
            				distY = end.clientY - start.clientY,
         | 
| 84 | 
            +
            				win = Syn.helpers.getWindow(element),
         | 
| 85 | 
            +
            				current = elementFromPoint(start, element),
         | 
| 86 | 
            +
            				cursor = win.document.createElement('div'),
         | 
| 87 | 
            +
            				calls = 0;
         | 
| 88 | 
            +
            			move = function() {
         | 
| 89 | 
            +
            				//get what fraction we are at
         | 
| 90 | 
            +
            				var now = new Date(),
         | 
| 91 | 
            +
            					scrollOffset = Syn.helpers.scrollOffset(win),
         | 
| 92 | 
            +
            					fraction = (calls == 0 ? 0 : now - startTime) / duration,
         | 
| 93 | 
            +
            					options = {
         | 
| 94 | 
            +
            						clientX: distX * fraction + start.clientX,
         | 
| 95 | 
            +
            						clientY: distY * fraction + start.clientY
         | 
| 96 | 
            +
            					};
         | 
| 97 | 
            +
            				calls++;
         | 
| 98 | 
            +
            				if ( fraction < 1 ) {
         | 
| 99 | 
            +
            					Syn.helpers.extend(cursor.style, {
         | 
| 100 | 
            +
            						left: (options.clientX + scrollOffset.left + 2) + "px",
         | 
| 101 | 
            +
            						top: (options.clientY + scrollOffset.top + 2) + "px"
         | 
| 102 | 
            +
            					})
         | 
| 103 | 
            +
            					current = mouseMove(options, element, current)
         | 
| 104 | 
            +
            					setTimeout(arguments.callee, 15)
         | 
| 105 | 
            +
            				}
         | 
| 106 | 
            +
            				else {
         | 
| 107 | 
            +
            					current = mouseMove(end, element, current);
         | 
| 108 | 
            +
            					win.document.body.removeChild(cursor)
         | 
| 109 | 
            +
            					callback();
         | 
| 110 | 
            +
            				}
         | 
| 111 | 
            +
            			}
         | 
| 112 | 
            +
            			Syn.helpers.extend(cursor.style, {
         | 
| 113 | 
            +
            				height: "5px",
         | 
| 114 | 
            +
            				width: "5px",
         | 
| 115 | 
            +
            				backgroundColor: "red",
         | 
| 116 | 
            +
            				position: "absolute",
         | 
| 117 | 
            +
            				zIndex: 19999,
         | 
| 118 | 
            +
            				fontSize: "1px"
         | 
| 119 | 
            +
            			})
         | 
| 120 | 
            +
            			win.document.body.appendChild(cursor)
         | 
| 121 | 
            +
            			move();
         | 
| 122 | 
            +
            		},
         | 
| 123 | 
            +
            		startDrag = function( start, end, duration, element, callback ) {
         | 
| 124 | 
            +
            			createEventAtPoint("mousedown", start, element);
         | 
| 125 | 
            +
            			startMove(start, end, duration, element, function() {
         | 
| 126 | 
            +
            				createEventAtPoint("mouseup", end, element);
         | 
| 127 | 
            +
            				callback();
         | 
| 128 | 
            +
            			})
         | 
| 129 | 
            +
            		},
         | 
| 130 | 
            +
            		center = function( el ) {
         | 
| 131 | 
            +
            			var j = Syn.jquery()(el),
         | 
| 132 | 
            +
            				o = j.offset();
         | 
| 133 | 
            +
            			return {
         | 
| 134 | 
            +
            				pageX: o.left + (j.width() / 2),
         | 
| 135 | 
            +
            				pageY: o.top + (j.height() / 2)
         | 
| 136 | 
            +
            			}
         | 
| 137 | 
            +
            		},
         | 
| 138 | 
            +
            		convertOption = function( option, win, from ) {
         | 
| 139 | 
            +
            			var page = /(\d+)[x ](\d+)/,
         | 
| 140 | 
            +
            				client = /(\d+)X(\d+)/,
         | 
| 141 | 
            +
            				relative = /([+-]\d+)[xX ]([+-]\d+)/
         | 
| 142 | 
            +
            				//check relative "+22x-44"
         | 
| 143 | 
            +
            				if ( typeof option == 'string' && relative.test(option) && from ) {
         | 
| 144 | 
            +
            					var cent = center(from),
         | 
| 145 | 
            +
            						parts = option.match(relative);
         | 
| 146 | 
            +
            					option = {
         | 
| 147 | 
            +
            						pageX: cent.pageX + parseInt(parts[1]),
         | 
| 148 | 
            +
            						pageY: cent.pageY + parseInt(parts[2])
         | 
| 149 | 
            +
            					}
         | 
| 150 | 
            +
            				}
         | 
| 151 | 
            +
            				if ( typeof option == 'string' && page.test(option) ) {
         | 
| 152 | 
            +
            					var parts = option.match(page)
         | 
| 153 | 
            +
            					option = {
         | 
| 154 | 
            +
            						pageX: parseInt(parts[1]),
         | 
| 155 | 
            +
            						pageY: parseInt(parts[2])
         | 
| 156 | 
            +
            					}
         | 
| 157 | 
            +
            				}
         | 
| 158 | 
            +
            				if ( typeof option == 'string' && client.test(option) ) {
         | 
| 159 | 
            +
            					var parts = option.match(client)
         | 
| 160 | 
            +
            					option = {
         | 
| 161 | 
            +
            						clientX: parseInt(parts[1]),
         | 
| 162 | 
            +
            						clientY: parseInt(parts[2])
         | 
| 163 | 
            +
            					}
         | 
| 164 | 
            +
            				}
         | 
| 165 | 
            +
            				if ( typeof option == 'string' ) {
         | 
| 166 | 
            +
            					option = Syn.jquery()(option, win.document)[0];
         | 
| 167 | 
            +
            				}
         | 
| 168 | 
            +
            				if ( option.nodeName ) {
         | 
| 169 | 
            +
            					option = center(option)
         | 
| 170 | 
            +
            				}
         | 
| 171 | 
            +
            				if ( option.pageX ) {
         | 
| 172 | 
            +
            					var off = Syn.helpers.scrollOffset(win);
         | 
| 173 | 
            +
            					option = {
         | 
| 174 | 
            +
            						clientX: option.pageX - off.left,
         | 
| 175 | 
            +
            						clientY: option.pageY - off.top
         | 
| 176 | 
            +
            					}
         | 
| 177 | 
            +
            				}
         | 
| 178 | 
            +
            				return option;
         | 
| 179 | 
            +
            		},
         | 
| 180 | 
            +
            		// if the client chords are not going to be visible ... scroll the page so they will be ...
         | 
| 181 | 
            +
            		adjust = function(from, to, win){
         | 
| 182 | 
            +
            			if(from.clientY < 0){
         | 
| 183 | 
            +
            				var off = Syn.helpers.scrollOffset(win);
         | 
| 184 | 
            +
            				var dimensions = Syn.helpers.scrollDimensions(win),
         | 
| 185 | 
            +
            					top = off.top + (from.clientY) - 100,
         | 
| 186 | 
            +
            					diff = top - off.top
         | 
| 187 | 
            +
            				
         | 
| 188 | 
            +
            				// first, lets see if we can scroll 100 px
         | 
| 189 | 
            +
            				if( top > 0){
         | 
| 190 | 
            +
            					
         | 
| 191 | 
            +
            				} else {
         | 
| 192 | 
            +
            					top =0;
         | 
| 193 | 
            +
            					diff = -off.top;
         | 
| 194 | 
            +
            				}
         | 
| 195 | 
            +
            				from.clientY = from.clientY - diff;
         | 
| 196 | 
            +
            				to.clientY = to.clientY - diff;
         | 
| 197 | 
            +
            				Syn.helpers.scrollOffset(win,{top: top, left: off.left});
         | 
| 198 | 
            +
            				
         | 
| 199 | 
            +
            				//throw "out of bounds!"
         | 
| 200 | 
            +
            			}
         | 
| 201 | 
            +
            		}
         | 
| 202 | 
            +
            		/**
         | 
| 203 | 
            +
            		 * @add Syn prototype
         | 
| 204 | 
            +
            		 */
         | 
| 205 | 
            +
            		Syn.helpers.extend(Syn.init.prototype, {
         | 
| 206 | 
            +
            			/**
         | 
| 207 | 
            +
            			 * @function move
         | 
| 208 | 
            +
            			 * Moves the cursor from one point to another.  
         | 
| 209 | 
            +
            			 * 
         | 
| 210 | 
            +
            			 * ### Quick Example
         | 
| 211 | 
            +
            			 * 
         | 
| 212 | 
            +
            			 * The following moves the cursor from (0,0) in
         | 
| 213 | 
            +
            			 * the window to (100,100) in 1 second.
         | 
| 214 | 
            +
            			 * 
         | 
| 215 | 
            +
            			 *     Syn.move(
         | 
| 216 | 
            +
            			 *          {
         | 
| 217 | 
            +
            			 *            from: {clientX: 0, clientY: 0},
         | 
| 218 | 
            +
            			 *            to: {clientX: 100, clientY: 100},
         | 
| 219 | 
            +
            			 *            duration: 1000
         | 
| 220 | 
            +
            			 *          },
         | 
| 221 | 
            +
            			 *          document.document)
         | 
| 222 | 
            +
            			 * 
         | 
| 223 | 
            +
            			 * ## Options
         | 
| 224 | 
            +
            			 * 
         | 
| 225 | 
            +
            			 * There are many ways to configure the endpoints of the move.
         | 
| 226 | 
            +
            			 * 
         | 
| 227 | 
            +
            			 * ### PageX and PageY
         | 
| 228 | 
            +
            			 * 
         | 
| 229 | 
            +
            			 * If you pass pageX or pageY, these will get converted
         | 
| 230 | 
            +
            			 * to client coordinates.
         | 
| 231 | 
            +
            			 * 
         | 
| 232 | 
            +
            			 *     Syn.move(
         | 
| 233 | 
            +
            			 *          {
         | 
| 234 | 
            +
            			 *            from: {pageX: 0, pageY: 0},
         | 
| 235 | 
            +
            			 *            to: {pageX: 100, pageY: 100}
         | 
| 236 | 
            +
            			 *          },
         | 
| 237 | 
            +
            			 *          document.document)
         | 
| 238 | 
            +
            			 * 
         | 
| 239 | 
            +
            			 * ### String Coordinates
         | 
| 240 | 
            +
            			 * 
         | 
| 241 | 
            +
            			 * You can set the pageX and pageY as strings like:
         | 
| 242 | 
            +
            			 * 
         | 
| 243 | 
            +
            			 *     Syn.move(
         | 
| 244 | 
            +
            			 *          {
         | 
| 245 | 
            +
            			 *            from: "0x0",
         | 
| 246 | 
            +
            			 *            to: "100x100"
         | 
| 247 | 
            +
            			 *          },
         | 
| 248 | 
            +
            			 *          document.document)
         | 
| 249 | 
            +
            			 * 
         | 
| 250 | 
            +
            			 * ### Element Coordinates
         | 
| 251 | 
            +
            			 * 
         | 
| 252 | 
            +
            			 * If jQuery is present, you can pass an element as the from or to option
         | 
| 253 | 
            +
            			 * and the coordinate will be set as the center of the element.
         | 
| 254 | 
            +
            			 
         | 
| 255 | 
            +
            			 *     Syn.move(
         | 
| 256 | 
            +
            			 *          {
         | 
| 257 | 
            +
            			 *            from: $(".recipe")[0],
         | 
| 258 | 
            +
            			 *            to: $("#trash")[0]
         | 
| 259 | 
            +
            			 *          },
         | 
| 260 | 
            +
            			 *          document.document)
         | 
| 261 | 
            +
            			 * 
         | 
| 262 | 
            +
            			 * ### Query Strings
         | 
| 263 | 
            +
            			 * 
         | 
| 264 | 
            +
            			 * If jQuery is present, you can pass a query string as the from or to option.
         | 
| 265 | 
            +
            			 * 
         | 
| 266 | 
            +
            			 * Syn.move(
         | 
| 267 | 
            +
            			 *      {
         | 
| 268 | 
            +
            			 *        from: ".recipe",
         | 
| 269 | 
            +
            			 *        to: "#trash"
         | 
| 270 | 
            +
            			 *      },
         | 
| 271 | 
            +
            			 *      document.document)
         | 
| 272 | 
            +
            			 *    
         | 
| 273 | 
            +
            			 * ### No From
         | 
| 274 | 
            +
            			 * 
         | 
| 275 | 
            +
            			 * If you don't provide a from, the element argument passed to Syn is used.
         | 
| 276 | 
            +
            			 * 
         | 
| 277 | 
            +
            			 *     Syn.move(
         | 
| 278 | 
            +
            			 *          { to: "#trash" },
         | 
| 279 | 
            +
            			 *          'myrecipe')
         | 
| 280 | 
            +
            			 * 
         | 
| 281 | 
            +
            			 * ### Relative
         | 
| 282 | 
            +
            			 * 
         | 
| 283 | 
            +
            			 * You can move the drag relative to the center of the from element.
         | 
| 284 | 
            +
            			 * 
         | 
| 285 | 
            +
            			 *     Syn.move("+20 +30", "myrecipe");
         | 
| 286 | 
            +
            			 * 
         | 
| 287 | 
            +
            			 * @param {Object} options options to configure the drag
         | 
| 288 | 
            +
            			 * @param {HTMLElement} from the element to move
         | 
| 289 | 
            +
            			 * @param {Function} callback a callback that happens after the drag motion has completed
         | 
| 290 | 
            +
            			 */
         | 
| 291 | 
            +
            			_move: function( options, from, callback ) {
         | 
| 292 | 
            +
            				//need to convert if elements
         | 
| 293 | 
            +
            				var win = Syn.helpers.getWindow(from),
         | 
| 294 | 
            +
            					fro = convertOption(options.from || from, win, from),
         | 
| 295 | 
            +
            					to = convertOption(options.to || options, win, from);
         | 
| 296 | 
            +
            				
         | 
| 297 | 
            +
            				options.adjust !== false && adjust(fro, to, win);
         | 
| 298 | 
            +
            				startMove(fro, to, options.duration || 500, from, callback);
         | 
| 299 | 
            +
             | 
| 300 | 
            +
            			},
         | 
| 301 | 
            +
            			/**
         | 
| 302 | 
            +
            			 * @function drag
         | 
| 303 | 
            +
            			 * Creates a mousedown and drags from one point to another.  
         | 
| 304 | 
            +
            			 * Check out [Syn.prototype.move move] for API details.
         | 
| 305 | 
            +
            			 * 
         | 
| 306 | 
            +
            			 * @param {Object} options
         | 
| 307 | 
            +
            			 * @param {Object} from
         | 
| 308 | 
            +
            			 * @param {Object} callback
         | 
| 309 | 
            +
            			 */
         | 
| 310 | 
            +
            			_drag: function( options, from, callback ) {
         | 
| 311 | 
            +
            				//need to convert if elements
         | 
| 312 | 
            +
            				var win = Syn.helpers.getWindow(from),
         | 
| 313 | 
            +
            					fro = convertOption(options.from || from, win, from),
         | 
| 314 | 
            +
            					to = convertOption(options.to || options, win, from);
         | 
| 315 | 
            +
             | 
| 316 | 
            +
            				options.adjust !== false && adjust(fro, to, win);
         | 
| 317 | 
            +
            				startDrag(fro, to, options.duration || 500, from, callback);
         | 
| 318 | 
            +
             | 
| 319 | 
            +
            			}
         | 
| 320 | 
            +
            		})
         | 
| 321 | 
            +
            }());
         | 
| @@ -0,0 +1,321 @@ | |
| 1 | 
            +
            (function() {
         | 
| 2 | 
            +
            	
         | 
| 3 | 
            +
            	// check if elementFromPageExists
         | 
| 4 | 
            +
            	(function() {
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            		// document body has to exists for this test
         | 
| 7 | 
            +
            		if (!document.body ) {
         | 
| 8 | 
            +
            			setTimeout(arguments.callee, 1)
         | 
| 9 | 
            +
            			return;
         | 
| 10 | 
            +
            		}
         | 
| 11 | 
            +
            		var div = document.createElement('div')
         | 
| 12 | 
            +
            		document.body.appendChild(div);
         | 
| 13 | 
            +
            		Syn.helpers.extend(div.style, {
         | 
| 14 | 
            +
            			width: "100px",
         | 
| 15 | 
            +
            			height: "10000px",
         | 
| 16 | 
            +
            			backgroundColor: "blue",
         | 
| 17 | 
            +
            			position: "absolute",
         | 
| 18 | 
            +
            			top: "10px",
         | 
| 19 | 
            +
            			left: "0px",
         | 
| 20 | 
            +
            			zIndex: 19999
         | 
| 21 | 
            +
            		});
         | 
| 22 | 
            +
            		document.body.scrollTop = 11;
         | 
| 23 | 
            +
            		if (!document.elementFromPoint ) {
         | 
| 24 | 
            +
            			return;
         | 
| 25 | 
            +
            		}
         | 
| 26 | 
            +
            		var el = document.elementFromPoint(3, 1)
         | 
| 27 | 
            +
            		if ( el == div ) {
         | 
| 28 | 
            +
            			Syn.support.elementFromClient = true;
         | 
| 29 | 
            +
            		}
         | 
| 30 | 
            +
            		else {
         | 
| 31 | 
            +
            			Syn.support.elementFromPage = true;
         | 
| 32 | 
            +
            		}
         | 
| 33 | 
            +
            		document.body.removeChild(div);
         | 
| 34 | 
            +
            		document.body.scrollTop = 0;
         | 
| 35 | 
            +
            	})();
         | 
| 36 | 
            +
             | 
| 37 | 
            +
             | 
| 38 | 
            +
            	//gets an element from a point
         | 
| 39 | 
            +
            	var elementFromPoint = function( point, element ) {
         | 
| 40 | 
            +
            		var clientX = point.clientX,
         | 
| 41 | 
            +
            			clientY = point.clientY,
         | 
| 42 | 
            +
            			win = Syn.helpers.getWindow(element),
         | 
| 43 | 
            +
            			el;
         | 
| 44 | 
            +
             | 
| 45 | 
            +
             | 
| 46 | 
            +
             | 
| 47 | 
            +
            		if ( Syn.support.elementFromPage ) {
         | 
| 48 | 
            +
            			var off = Syn.helpers.scrollOffset(win);
         | 
| 49 | 
            +
            			clientX = clientX + off.left; //convert to pageX
         | 
| 50 | 
            +
            			clientY = clientY + off.top; //convert to pageY
         | 
| 51 | 
            +
            		}
         | 
| 52 | 
            +
            		el = win.document.elementFromPoint ? win.document.elementFromPoint(clientX, clientY) : element;
         | 
| 53 | 
            +
            		if ( el === win.document.documentElement && (point.clientY < 0 || point.clientX < 0) ) {
         | 
| 54 | 
            +
            			return element;
         | 
| 55 | 
            +
            		} else {
         | 
| 56 | 
            +
            			return el;
         | 
| 57 | 
            +
            		}
         | 
| 58 | 
            +
            	},
         | 
| 59 | 
            +
            		//creates an event at a certain point
         | 
| 60 | 
            +
            		createEventAtPoint = function( event, point, element ) {
         | 
| 61 | 
            +
            			var el = elementFromPoint(point, element)
         | 
| 62 | 
            +
            			Syn.trigger(event, point, el || element)
         | 
| 63 | 
            +
            			return el;
         | 
| 64 | 
            +
            		},
         | 
| 65 | 
            +
            		// creates a mousemove event, but first triggering mouseout / mouseover if appropriate
         | 
| 66 | 
            +
            		mouseMove = function( point, element, last ) {
         | 
| 67 | 
            +
            			var el = elementFromPoint(point, element)
         | 
| 68 | 
            +
            			if ( last != el && el && last ) {
         | 
| 69 | 
            +
            				var options = Syn.helpers.extend({}, point);
         | 
| 70 | 
            +
            				options.relatedTarget = el;
         | 
| 71 | 
            +
            				Syn.trigger("mouseout", options, last);
         | 
| 72 | 
            +
            				options.relatedTarget = last;
         | 
| 73 | 
            +
            				Syn.trigger("mouseover", options, el);
         | 
| 74 | 
            +
            			}
         | 
| 75 | 
            +
             | 
| 76 | 
            +
            			Syn.trigger("mousemove", point, el || element)
         | 
| 77 | 
            +
            			return el;
         | 
| 78 | 
            +
            		},
         | 
| 79 | 
            +
            		// start and end are in clientX, clientY
         | 
| 80 | 
            +
            		startMove = function( start, end, duration, element, callback ) {
         | 
| 81 | 
            +
            			var startTime = new Date(),
         | 
| 82 | 
            +
            				distX = end.clientX - start.clientX,
         | 
| 83 | 
            +
            				distY = end.clientY - start.clientY,
         | 
| 84 | 
            +
            				win = Syn.helpers.getWindow(element),
         | 
| 85 | 
            +
            				current = elementFromPoint(start, element),
         | 
| 86 | 
            +
            				cursor = win.document.createElement('div'),
         | 
| 87 | 
            +
            				calls = 0;
         | 
| 88 | 
            +
            			move = function() {
         | 
| 89 | 
            +
            				//get what fraction we are at
         | 
| 90 | 
            +
            				var now = new Date(),
         | 
| 91 | 
            +
            					scrollOffset = Syn.helpers.scrollOffset(win),
         | 
| 92 | 
            +
            					fraction = (calls == 0 ? 0 : now - startTime) / duration,
         | 
| 93 | 
            +
            					options = {
         | 
| 94 | 
            +
            						clientX: distX * fraction + start.clientX,
         | 
| 95 | 
            +
            						clientY: distY * fraction + start.clientY
         | 
| 96 | 
            +
            					};
         | 
| 97 | 
            +
            				calls++;
         | 
| 98 | 
            +
            				if ( fraction < 1 ) {
         | 
| 99 | 
            +
            					Syn.helpers.extend(cursor.style, {
         | 
| 100 | 
            +
            						left: (options.clientX + scrollOffset.left + 2) + "px",
         | 
| 101 | 
            +
            						top: (options.clientY + scrollOffset.top + 2) + "px"
         | 
| 102 | 
            +
            					})
         | 
| 103 | 
            +
            					current = mouseMove(options, element, current)
         | 
| 104 | 
            +
            					setTimeout(arguments.callee, 15)
         | 
| 105 | 
            +
            				}
         | 
| 106 | 
            +
            				else {
         | 
| 107 | 
            +
            					current = mouseMove(end, element, current);
         | 
| 108 | 
            +
            					win.document.body.removeChild(cursor)
         | 
| 109 | 
            +
            					callback();
         | 
| 110 | 
            +
            				}
         | 
| 111 | 
            +
            			}
         | 
| 112 | 
            +
            			Syn.helpers.extend(cursor.style, {
         | 
| 113 | 
            +
            				height: "5px",
         | 
| 114 | 
            +
            				width: "5px",
         | 
| 115 | 
            +
            				backgroundColor: "red",
         | 
| 116 | 
            +
            				position: "absolute",
         | 
| 117 | 
            +
            				zIndex: 19999,
         | 
| 118 | 
            +
            				fontSize: "1px"
         | 
| 119 | 
            +
            			})
         | 
| 120 | 
            +
            			win.document.body.appendChild(cursor)
         | 
| 121 | 
            +
            			move();
         | 
| 122 | 
            +
            		},
         | 
| 123 | 
            +
            		startDrag = function( start, end, duration, element, callback ) {
         | 
| 124 | 
            +
            			createEventAtPoint("mousedown", start, element);
         | 
| 125 | 
            +
            			startMove(start, end, duration, element, function() {
         | 
| 126 | 
            +
            				createEventAtPoint("mouseup", end, element);
         | 
| 127 | 
            +
            				callback();
         | 
| 128 | 
            +
            			})
         | 
| 129 | 
            +
            		},
         | 
| 130 | 
            +
            		center = function( el ) {
         | 
| 131 | 
            +
            			var j = Syn.jquery()(el),
         | 
| 132 | 
            +
            				o = j.offset();
         | 
| 133 | 
            +
            			return {
         | 
| 134 | 
            +
            				pageX: o.left + (j.width() / 2),
         | 
| 135 | 
            +
            				pageY: o.top + (j.height() / 2)
         | 
| 136 | 
            +
            			}
         | 
| 137 | 
            +
            		},
         | 
| 138 | 
            +
            		convertOption = function( option, win, from ) {
         | 
| 139 | 
            +
            			var page = /(\d+)[x ](\d+)/,
         | 
| 140 | 
            +
            				client = /(\d+)X(\d+)/,
         | 
| 141 | 
            +
            				relative = /([+-]\d+)[xX ]([+-]\d+)/
         | 
| 142 | 
            +
            				//check relative "+22x-44"
         | 
| 143 | 
            +
            				if ( typeof option == 'string' && relative.test(option) && from ) {
         | 
| 144 | 
            +
            					var cent = center(from),
         | 
| 145 | 
            +
            						parts = option.match(relative);
         | 
| 146 | 
            +
            					option = {
         | 
| 147 | 
            +
            						pageX: cent.pageX + parseInt(parts[1]),
         | 
| 148 | 
            +
            						pageY: cent.pageY + parseInt(parts[2])
         | 
| 149 | 
            +
            					}
         | 
| 150 | 
            +
            				}
         | 
| 151 | 
            +
            				if ( typeof option == 'string' && page.test(option) ) {
         | 
| 152 | 
            +
            					var parts = option.match(page)
         | 
| 153 | 
            +
            					option = {
         | 
| 154 | 
            +
            						pageX: parseInt(parts[1]),
         | 
| 155 | 
            +
            						pageY: parseInt(parts[2])
         | 
| 156 | 
            +
            					}
         | 
| 157 | 
            +
            				}
         | 
| 158 | 
            +
            				if ( typeof option == 'string' && client.test(option) ) {
         | 
| 159 | 
            +
            					var parts = option.match(client)
         | 
| 160 | 
            +
            					option = {
         | 
| 161 | 
            +
            						clientX: parseInt(parts[1]),
         | 
| 162 | 
            +
            						clientY: parseInt(parts[2])
         | 
| 163 | 
            +
            					}
         | 
| 164 | 
            +
            				}
         | 
| 165 | 
            +
            				if ( typeof option == 'string' ) {
         | 
| 166 | 
            +
            					option = Syn.jquery()(option, win.document)[0];
         | 
| 167 | 
            +
            				}
         | 
| 168 | 
            +
            				if ( option.nodeName ) {
         | 
| 169 | 
            +
            					option = center(option)
         | 
| 170 | 
            +
            				}
         | 
| 171 | 
            +
            				if ( option.pageX ) {
         | 
| 172 | 
            +
            					var off = Syn.helpers.scrollOffset(win);
         | 
| 173 | 
            +
            					option = {
         | 
| 174 | 
            +
            						clientX: option.pageX - off.left,
         | 
| 175 | 
            +
            						clientY: option.pageY - off.top
         | 
| 176 | 
            +
            					}
         | 
| 177 | 
            +
            				}
         | 
| 178 | 
            +
            				return option;
         | 
| 179 | 
            +
            		},
         | 
| 180 | 
            +
            		// if the client chords are not going to be visible ... scroll the page so they will be ...
         | 
| 181 | 
            +
            		adjust = function(from, to, win){
         | 
| 182 | 
            +
            			if(from.clientY < 0){
         | 
| 183 | 
            +
            				var off = Syn.helpers.scrollOffset(win);
         | 
| 184 | 
            +
            				var dimensions = Syn.helpers.scrollDimensions(win),
         | 
| 185 | 
            +
            					top = off.top + (from.clientY) - 100,
         | 
| 186 | 
            +
            					diff = top - off.top
         | 
| 187 | 
            +
            				
         | 
| 188 | 
            +
            				// first, lets see if we can scroll 100 px
         | 
| 189 | 
            +
            				if( top > 0){
         | 
| 190 | 
            +
            					
         | 
| 191 | 
            +
            				} else {
         | 
| 192 | 
            +
            					top =0;
         | 
| 193 | 
            +
            					diff = -off.top;
         | 
| 194 | 
            +
            				}
         | 
| 195 | 
            +
            				from.clientY = from.clientY - diff;
         | 
| 196 | 
            +
            				to.clientY = to.clientY - diff;
         | 
| 197 | 
            +
            				Syn.helpers.scrollOffset(win,{top: top, left: off.left});
         | 
| 198 | 
            +
            				
         | 
| 199 | 
            +
            				//throw "out of bounds!"
         | 
| 200 | 
            +
            			}
         | 
| 201 | 
            +
            		}
         | 
| 202 | 
            +
            		/**
         | 
| 203 | 
            +
            		 * @add Syn prototype
         | 
| 204 | 
            +
            		 */
         | 
| 205 | 
            +
            		Syn.helpers.extend(Syn.init.prototype, {
         | 
| 206 | 
            +
            			/**
         | 
| 207 | 
            +
            			 * @function move
         | 
| 208 | 
            +
            			 * Moves the cursor from one point to another.  
         | 
| 209 | 
            +
            			 * 
         | 
| 210 | 
            +
            			 * ### Quick Example
         | 
| 211 | 
            +
            			 * 
         | 
| 212 | 
            +
            			 * The following moves the cursor from (0,0) in
         | 
| 213 | 
            +
            			 * the window to (100,100) in 1 second.
         | 
| 214 | 
            +
            			 * 
         | 
| 215 | 
            +
            			 *     Syn.move(
         | 
| 216 | 
            +
            			 *          {
         | 
| 217 | 
            +
            			 *            from: {clientX: 0, clientY: 0},
         | 
| 218 | 
            +
            			 *            to: {clientX: 100, clientY: 100},
         | 
| 219 | 
            +
            			 *            duration: 1000
         | 
| 220 | 
            +
            			 *          },
         | 
| 221 | 
            +
            			 *          document.document)
         | 
| 222 | 
            +
            			 * 
         | 
| 223 | 
            +
            			 * ## Options
         | 
| 224 | 
            +
            			 * 
         | 
| 225 | 
            +
            			 * There are many ways to configure the endpoints of the move.
         | 
| 226 | 
            +
            			 * 
         | 
| 227 | 
            +
            			 * ### PageX and PageY
         | 
| 228 | 
            +
            			 * 
         | 
| 229 | 
            +
            			 * If you pass pageX or pageY, these will get converted
         | 
| 230 | 
            +
            			 * to client coordinates.
         | 
| 231 | 
            +
            			 * 
         | 
| 232 | 
            +
            			 *     Syn.move(
         | 
| 233 | 
            +
            			 *          {
         | 
| 234 | 
            +
            			 *            from: {pageX: 0, pageY: 0},
         | 
| 235 | 
            +
            			 *            to: {pageX: 100, pageY: 100}
         | 
| 236 | 
            +
            			 *          },
         | 
| 237 | 
            +
            			 *          document.document)
         | 
| 238 | 
            +
            			 * 
         | 
| 239 | 
            +
            			 * ### String Coordinates
         | 
| 240 | 
            +
            			 * 
         | 
| 241 | 
            +
            			 * You can set the pageX and pageY as strings like:
         | 
| 242 | 
            +
            			 * 
         | 
| 243 | 
            +
            			 *     Syn.move(
         | 
| 244 | 
            +
            			 *          {
         | 
| 245 | 
            +
            			 *            from: "0x0",
         | 
| 246 | 
            +
            			 *            to: "100x100"
         | 
| 247 | 
            +
            			 *          },
         | 
| 248 | 
            +
            			 *          document.document)
         | 
| 249 | 
            +
            			 * 
         | 
| 250 | 
            +
            			 * ### Element Coordinates
         | 
| 251 | 
            +
            			 * 
         | 
| 252 | 
            +
            			 * If jQuery is present, you can pass an element as the from or to option
         | 
| 253 | 
            +
            			 * and the coordinate will be set as the center of the element.
         | 
| 254 | 
            +
            			 
         | 
| 255 | 
            +
            			 *     Syn.move(
         | 
| 256 | 
            +
            			 *          {
         | 
| 257 | 
            +
            			 *            from: $(".recipe")[0],
         | 
| 258 | 
            +
            			 *            to: $("#trash")[0]
         | 
| 259 | 
            +
            			 *          },
         | 
| 260 | 
            +
            			 *          document.document)
         | 
| 261 | 
            +
            			 * 
         | 
| 262 | 
            +
            			 * ### Query Strings
         | 
| 263 | 
            +
            			 * 
         | 
| 264 | 
            +
            			 * If jQuery is present, you can pass a query string as the from or to option.
         | 
| 265 | 
            +
            			 * 
         | 
| 266 | 
            +
            			 * Syn.move(
         | 
| 267 | 
            +
            			 *      {
         | 
| 268 | 
            +
            			 *        from: ".recipe",
         | 
| 269 | 
            +
            			 *        to: "#trash"
         | 
| 270 | 
            +
            			 *      },
         | 
| 271 | 
            +
            			 *      document.document)
         | 
| 272 | 
            +
            			 *    
         | 
| 273 | 
            +
            			 * ### No From
         | 
| 274 | 
            +
            			 * 
         | 
| 275 | 
            +
            			 * If you don't provide a from, the element argument passed to Syn is used.
         | 
| 276 | 
            +
            			 * 
         | 
| 277 | 
            +
            			 *     Syn.move(
         | 
| 278 | 
            +
            			 *          { to: "#trash" },
         | 
| 279 | 
            +
            			 *          'myrecipe')
         | 
| 280 | 
            +
            			 * 
         | 
| 281 | 
            +
            			 * ### Relative
         | 
| 282 | 
            +
            			 * 
         | 
| 283 | 
            +
            			 * You can move the drag relative to the center of the from element.
         | 
| 284 | 
            +
            			 * 
         | 
| 285 | 
            +
            			 *     Syn.move("+20 +30", "myrecipe");
         | 
| 286 | 
            +
            			 * 
         | 
| 287 | 
            +
            			 * @param {Object} options options to configure the drag
         | 
| 288 | 
            +
            			 * @param {HTMLElement} from the element to move
         | 
| 289 | 
            +
            			 * @param {Function} callback a callback that happens after the drag motion has completed
         | 
| 290 | 
            +
            			 */
         | 
| 291 | 
            +
            			_move: function( options, from, callback ) {
         | 
| 292 | 
            +
            				//need to convert if elements
         | 
| 293 | 
            +
            				var win = Syn.helpers.getWindow(from),
         | 
| 294 | 
            +
            					fro = convertOption(options.from || from, win, from),
         | 
| 295 | 
            +
            					to = convertOption(options.to || options, win, from);
         | 
| 296 | 
            +
            				
         | 
| 297 | 
            +
            				options.adjust !== false && adjust(fro, to, win);
         | 
| 298 | 
            +
            				startMove(fro, to, options.duration || 500, from, callback);
         | 
| 299 | 
            +
             | 
| 300 | 
            +
            			},
         | 
| 301 | 
            +
            			/**
         | 
| 302 | 
            +
            			 * @function drag
         | 
| 303 | 
            +
            			 * Creates a mousedown and drags from one point to another.  
         | 
| 304 | 
            +
            			 * Check out [Syn.prototype.move move] for API details.
         | 
| 305 | 
            +
            			 * 
         | 
| 306 | 
            +
            			 * @param {Object} options
         | 
| 307 | 
            +
            			 * @param {Object} from
         | 
| 308 | 
            +
            			 * @param {Object} callback
         | 
| 309 | 
            +
            			 */
         | 
| 310 | 
            +
            			_drag: function( options, from, callback ) {
         | 
| 311 | 
            +
            				//need to convert if elements
         | 
| 312 | 
            +
            				var win = Syn.helpers.getWindow(from),
         | 
| 313 | 
            +
            					fro = convertOption(options.from || from, win, from),
         | 
| 314 | 
            +
            					to = convertOption(options.to || options, win, from);
         | 
| 315 | 
            +
             | 
| 316 | 
            +
            				options.adjust !== false && adjust(fro, to, win);
         | 
| 317 | 
            +
            				startDrag(fro, to, options.duration || 500, from, callback);
         | 
| 318 | 
            +
             | 
| 319 | 
            +
            			}
         | 
| 320 | 
            +
            		})
         | 
| 321 | 
            +
            }());
         |