jquery-ui/ui/widgets/mouse.js

227 lines
6.0 KiB
JavaScript
Raw Permalink Normal View History

/*!
* jQuery UI Mouse @VERSION
2012-07-04 13:08:08 +00:00
* http://jqueryui.com
*
* Copyright jQuery Foundation and other contributors
2012-08-09 14:13:24 +00:00
* Released under the MIT license.
* http://jquery.org/license
*/
//>>label: Mouse
//>>group: Widgets
//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
//>>docs: http://api.jqueryui.com/mouse/
2015-08-24 12:59:04 +00:00
( function( factory ) {
if ( typeof define === "function" && define.amd ) {
// AMD. Register as an anonymous module.
2015-08-24 12:59:04 +00:00
define( [
"jquery",
"../ie",
"../version",
"../widget"
], factory );
} else {
// Browser globals
factory( jQuery );
}
2015-08-24 12:59:04 +00:00
}( function( $ ) {
var mouseHandled = false;
$( document ).on( "mouseup", function() {
mouseHandled = false;
2015-08-24 12:59:04 +00:00
} );
2015-08-24 12:59:04 +00:00
return $.widget( "ui.mouse", {
version: "@VERSION",
options: {
cancel: "input, textarea, button, select, option",
distance: 1,
delay: 0
},
_mouseInit: function() {
var that = this;
this.element
2015-08-24 12:59:04 +00:00
.on( "mousedown." + this.widgetName, function( event ) {
return that._mouseDown( event );
} )
.on( "click." + this.widgetName, function( event ) {
if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
$.removeData( event.target, that.widgetName + ".preventClickEvent" );
event.stopImmediatePropagation();
return false;
}
2015-08-24 12:59:04 +00:00
} );
this.started = false;
},
// TODO: make sure destroying one instance of mouse doesn't mess with
// other instances of mouse
_mouseDestroy: function() {
2015-08-24 12:59:04 +00:00
this.element.off( "." + this.widgetName );
if ( this._mouseMoveDelegate ) {
this.document
2015-08-24 12:59:04 +00:00
.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
}
},
2015-08-24 12:59:04 +00:00
_mouseDown: function( event ) {
// don't let more than one widget handle mouseStart
2013-10-16 18:43:09 +00:00
if ( mouseHandled ) {
return;
}
this._mouseMoved = false;
// We may have missed mouseup (out of window)
2015-08-24 12:59:04 +00:00
( this._mouseStarted && this._mouseUp( event ) );
this._mouseDownEvent = event;
var that = this,
2015-08-24 12:59:04 +00:00
btnIsLeft = ( event.which === 1 ),
// event.target.nodeName works around a bug in IE 8 with
// disabled inputs (#7620)
elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
$( event.target ).closest( this.options.cancel ).length : false );
2015-08-24 12:59:04 +00:00
if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
return true;
}
this.mouseDelayMet = !this.options.delay;
2015-08-24 12:59:04 +00:00
if ( !this.mouseDelayMet ) {
this._mouseDelayTimer = setTimeout( function() {
that.mouseDelayMet = true;
2015-08-24 12:59:04 +00:00
}, this.options.delay );
}
2015-08-24 12:59:04 +00:00
if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
this._mouseStarted = ( this._mouseStart( event ) !== false );
if ( !this._mouseStarted ) {
event.preventDefault();
return true;
}
}
// Click event may never have fired (Gecko & Opera)
2015-08-24 12:59:04 +00:00
if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
$.removeData( event.target, this.widgetName + ".preventClickEvent" );
}
// These delegates are required to keep context
2015-08-24 12:59:04 +00:00
this._mouseMoveDelegate = function( event ) {
return that._mouseMove( event );
};
2015-08-24 12:59:04 +00:00
this._mouseUpDelegate = function( event ) {
return that._mouseUp( event );
};
this.document
.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
event.preventDefault();
mouseHandled = true;
return true;
},
2015-08-24 12:59:04 +00:00
_mouseMove: function( event ) {
// Only check for mouseups outside the document if you've moved inside the document
// at least once. This prevents the firing of mouseup in the case of IE<9, which will
// fire a mousemove event if content is placed under the cursor. See #7778
// Support: IE <9
if ( this._mouseMoved ) {
2015-08-24 12:59:04 +00:00
// IE mouseup check - mouseup happened when mouse was out of window
if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
!event.button ) {
2015-08-24 12:59:04 +00:00
return this._mouseUp( event );
// Iframe mouseup check - mouseup occurred in another document
} else if ( !event.which ) {
// Support: Safari <=8 - 9
// Safari sets which to 0 if you press any of the following keys
// during a drag (#14461)
if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
this.ignoreMissingWhich = true;
} else if ( !this.ignoreMissingWhich ) {
return this._mouseUp( event );
}
}
}
2013-10-16 18:43:09 +00:00
if ( event.which || event.button ) {
this._mouseMoved = true;
}
2015-08-24 12:59:04 +00:00
if ( this._mouseStarted ) {
this._mouseDrag( event );
return event.preventDefault();
}
2015-08-24 12:59:04 +00:00
if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
this._mouseStarted =
2015-08-24 12:59:04 +00:00
( this._mouseStart( this._mouseDownEvent, event ) !== false );
( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
}
return !this._mouseStarted;
},
2015-08-24 12:59:04 +00:00
_mouseUp: function( event ) {
this.document
.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
2015-08-24 12:59:04 +00:00
if ( this._mouseStarted ) {
this._mouseStarted = false;
2015-08-24 12:59:04 +00:00
if ( event.target === this._mouseDownEvent.target ) {
$.data( event.target, this.widgetName + ".preventClickEvent", true );
}
2015-08-24 12:59:04 +00:00
this._mouseStop( event );
}
2015-09-11 12:42:02 +00:00
if ( this._mouseDelayTimer ) {
clearTimeout( this._mouseDelayTimer );
delete this._mouseDelayTimer;
}
this.ignoreMissingWhich = false;
mouseHandled = false;
event.preventDefault();
},
2015-08-24 12:59:04 +00:00
_mouseDistanceMet: function( event ) {
return ( Math.max(
Math.abs( this._mouseDownEvent.pageX - event.pageX ),
Math.abs( this._mouseDownEvent.pageY - event.pageY )
) >= this.options.distance
);
},
2015-08-24 12:59:04 +00:00
_mouseDelayMet: function( /* event */ ) {
return this.mouseDelayMet;
},
// These are placeholder methods, to be overriden by extending plugin
2015-08-24 12:59:04 +00:00
_mouseStart: function( /* event */ ) {},
_mouseDrag: function( /* event */ ) {},
_mouseStop: function( /* event */ ) {},
_mouseCapture: function( /* event */ ) { return true; }
} );
2015-08-24 12:59:04 +00:00
} ) );