mouse.js (6123B)
1 /*! 2 * jQuery UI Mouse 1.12.1 3 * http://jqueryui.com 4 * 5 * Copyright jQuery Foundation and other contributors 6 * Released under the MIT license. 7 * http://jquery.org/license 8 */ 9 10 //>>label: Mouse 11 //>>group: Widgets 12 //>>description: Abstracts mouse-based interactions to assist in creating certain widgets. 13 //>>docs: http://api.jqueryui.com/mouse/ 14 15 ( function( factory ) { 16 if ( typeof define === "function" && define.amd ) { 17 18 // AMD. Register as an anonymous module. 19 define( [ 20 "jquery", 21 "./core" 22 ], factory ); 23 } else { 24 25 // Browser globals 26 factory( jQuery ); 27 } 28 }( function( $ ) { 29 30 var mouseHandled = false; 31 $( document ).on( "mouseup", function() { 32 mouseHandled = false; 33 } ); 34 35 return $.widget( "ui.mouse", { 36 version: "1.12.1", 37 options: { 38 cancel: "input, textarea, button, select, option", 39 distance: 1, 40 delay: 0 41 }, 42 _mouseInit: function() { 43 var that = this; 44 45 this.element 46 .on( "mousedown." + this.widgetName, function( event ) { 47 return that._mouseDown( event ); 48 } ) 49 .on( "click." + this.widgetName, function( event ) { 50 if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) { 51 $.removeData( event.target, that.widgetName + ".preventClickEvent" ); 52 event.stopImmediatePropagation(); 53 return false; 54 } 55 } ); 56 57 this.started = false; 58 }, 59 60 // TODO: make sure destroying one instance of mouse doesn't mess with 61 // other instances of mouse 62 _mouseDestroy: function() { 63 this.element.off( "." + this.widgetName ); 64 if ( this._mouseMoveDelegate ) { 65 this.document 66 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 67 .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); 68 } 69 }, 70 71 _mouseDown: function( event ) { 72 73 // don't let more than one widget handle mouseStart 74 if ( mouseHandled ) { 75 return; 76 } 77 78 this._mouseMoved = false; 79 80 // We may have missed mouseup (out of window) 81 ( this._mouseStarted && this._mouseUp( event ) ); 82 83 this._mouseDownEvent = event; 84 85 var that = this, 86 btnIsLeft = ( event.which === 1 ), 87 88 // event.target.nodeName works around a bug in IE 8 with 89 // disabled inputs (#7620) 90 elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ? 91 $( event.target ).closest( this.options.cancel ).length : false ); 92 if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) { 93 return true; 94 } 95 96 this.mouseDelayMet = !this.options.delay; 97 if ( !this.mouseDelayMet ) { 98 this._mouseDelayTimer = setTimeout( function() { 99 that.mouseDelayMet = true; 100 }, this.options.delay ); 101 } 102 103 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { 104 this._mouseStarted = ( this._mouseStart( event ) !== false ); 105 if ( !this._mouseStarted ) { 106 event.preventDefault(); 107 return true; 108 } 109 } 110 111 // Click event may never have fired (Gecko & Opera) 112 if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) { 113 $.removeData( event.target, this.widgetName + ".preventClickEvent" ); 114 } 115 116 // These delegates are required to keep context 117 this._mouseMoveDelegate = function( event ) { 118 return that._mouseMove( event ); 119 }; 120 this._mouseUpDelegate = function( event ) { 121 return that._mouseUp( event ); 122 }; 123 124 this.document 125 .on( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 126 .on( "mouseup." + this.widgetName, this._mouseUpDelegate ); 127 128 event.preventDefault(); 129 130 mouseHandled = true; 131 return true; 132 }, 133 134 _mouseMove: function( event ) { 135 136 // Only check for mouseups outside the document if you've moved inside the document 137 // at least once. This prevents the firing of mouseup in the case of IE<9, which will 138 // fire a mousemove event if content is placed under the cursor. See #7778 139 // Support: IE <9 140 if ( this._mouseMoved ) { 141 142 // IE mouseup check - mouseup happened when mouse was out of window 143 if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && 144 !event.button ) { 145 return this._mouseUp( event ); 146 147 // Iframe mouseup check - mouseup occurred in another document 148 } else if ( !event.which ) { 149 150 // Support: Safari <=8 - 9 151 // Safari sets which to 0 if you press any of the following keys 152 // during a drag (#14461) 153 if ( event.originalEvent.altKey || event.originalEvent.ctrlKey || 154 event.originalEvent.metaKey || event.originalEvent.shiftKey ) { 155 this.ignoreMissingWhich = true; 156 } else if ( !this.ignoreMissingWhich ) { 157 return this._mouseUp( event ); 158 } 159 } 160 } 161 162 if ( event.which || event.button ) { 163 this._mouseMoved = true; 164 } 165 166 if ( this._mouseStarted ) { 167 this._mouseDrag( event ); 168 return event.preventDefault(); 169 } 170 171 if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) { 172 this._mouseStarted = 173 ( this._mouseStart( this._mouseDownEvent, event ) !== false ); 174 ( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) ); 175 } 176 177 return !this._mouseStarted; 178 }, 179 180 _mouseUp: function( event ) { 181 this.document 182 .off( "mousemove." + this.widgetName, this._mouseMoveDelegate ) 183 .off( "mouseup." + this.widgetName, this._mouseUpDelegate ); 184 185 if ( this._mouseStarted ) { 186 this._mouseStarted = false; 187 188 if ( event.target === this._mouseDownEvent.target ) { 189 $.data( event.target, this.widgetName + ".preventClickEvent", true ); 190 } 191 192 this._mouseStop( event ); 193 } 194 195 if ( this._mouseDelayTimer ) { 196 clearTimeout( this._mouseDelayTimer ); 197 delete this._mouseDelayTimer; 198 } 199 200 this.ignoreMissingWhich = false; 201 mouseHandled = false; 202 event.preventDefault(); 203 }, 204 205 _mouseDistanceMet: function( event ) { 206 return ( Math.max( 207 Math.abs( this._mouseDownEvent.pageX - event.pageX ), 208 Math.abs( this._mouseDownEvent.pageY - event.pageY ) 209 ) >= this.options.distance 210 ); 211 }, 212 213 _mouseDelayMet: function( /* event */ ) { 214 return this.mouseDelayMet; 215 }, 216 217 // These are placeholder methods, to be overriden by extending plugin 218 _mouseStart: function( /* event */ ) {}, 219 _mouseDrag: function( /* event */ ) {}, 220 _mouseStop: function( /* event */ ) {}, 221 _mouseCapture: function( /* event */ ) { return true; } 222 } ); 223 224 } ) );