mouse.js 5.5 KB

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