2012-01-26 16:14:57 +00:00
|
|
|
/*
|
|
|
|
* jQuery UI Interaction @VERSION
|
|
|
|
*
|
|
|
|
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
|
|
|
* Dual licensed under the MIT or GPL Version 2 licenses.
|
|
|
|
* http://jquery.org/license
|
|
|
|
*
|
|
|
|
* http://docs.jquery.com/UI/Interaction
|
|
|
|
*
|
|
|
|
* Depends:
|
|
|
|
* jquery.ui.widget.js
|
|
|
|
*/
|
2011-11-23 17:03:09 +00:00
|
|
|
(function( $, undefined ) {
|
|
|
|
|
2012-05-25 15:12:06 +00:00
|
|
|
var interaction, touchHook, pointerHook;
|
2011-11-23 17:03:09 +00:00
|
|
|
|
|
|
|
$.widget( "ui.interaction", {
|
|
|
|
version: "@VERSION",
|
|
|
|
_create: function() {
|
2012-01-28 01:57:17 +00:00
|
|
|
// force the context so we can pass these methods to the hooks
|
|
|
|
this._interactionMove = $.proxy( this, "_interactionMove" );
|
|
|
|
this._interactionStop = $.proxy( this, "_interactionStop" );
|
|
|
|
|
|
|
|
// initialize all hooks for this widget
|
2011-11-23 17:03:09 +00:00
|
|
|
for ( var hook in interaction.hooks ) {
|
|
|
|
interaction.hooks[ hook ].setup( this, this._startProxy( hook ) );
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2012-01-28 15:16:36 +00:00
|
|
|
/** abstract methods **/
|
|
|
|
|
|
|
|
// _start: function( event, pointerPosition )
|
|
|
|
// _move: function( event, pointerPosition )
|
|
|
|
// _stop: function( event, pointerPosition )
|
|
|
|
|
|
|
|
/** protected **/
|
|
|
|
|
|
|
|
_isValidTarget: function( target ) {
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
|
|
|
|
/** internal **/
|
|
|
|
|
2012-01-28 01:57:17 +00:00
|
|
|
// a pass through to _interactionStart() which tracks the hook that was used
|
2011-11-23 17:03:09 +00:00
|
|
|
_startProxy: function( hook ) {
|
|
|
|
var that = this;
|
2012-01-15 17:57:39 +00:00
|
|
|
return function( event, target, pointerPosition ) {
|
|
|
|
return that._interactionStart( event, target, pointerPosition, hook );
|
2012-05-25 15:12:06 +00:00
|
|
|
};
|
2011-11-23 17:03:09 +00:00
|
|
|
},
|
|
|
|
|
2012-01-15 17:57:39 +00:00
|
|
|
_interactionStart: function( event, target, pointerPosition, hook ) {
|
2012-01-14 21:14:39 +00:00
|
|
|
var started;
|
|
|
|
|
2012-01-12 03:04:41 +00:00
|
|
|
// only one interaction can happen at a time
|
|
|
|
if ( interaction.started ) {
|
2012-01-14 21:14:39 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-01-28 01:57:17 +00:00
|
|
|
// check if the event occurred on a valid target
|
2012-01-14 21:14:39 +00:00
|
|
|
if ( false === this._isValidTarget( $( target ) ) ) {
|
|
|
|
return false;
|
2012-01-12 03:04:41 +00:00
|
|
|
}
|
|
|
|
|
2012-01-28 01:57:17 +00:00
|
|
|
// check if the widget wants the event to start an interaction
|
2012-01-26 16:02:54 +00:00
|
|
|
started = ( this._start( event, pointerPosition ) !== false );
|
2012-01-14 21:14:39 +00:00
|
|
|
if ( started ) {
|
2011-11-23 17:03:09 +00:00
|
|
|
interaction.started = true;
|
2012-01-28 01:57:17 +00:00
|
|
|
interaction.hooks[ hook ].handle( this,
|
|
|
|
this._interactionMove, this._interactionStop );
|
2011-11-23 17:03:09 +00:00
|
|
|
}
|
2012-01-14 21:14:39 +00:00
|
|
|
|
2012-01-28 01:57:17 +00:00
|
|
|
// let the hook know if the interaction was started
|
2012-01-14 21:14:39 +00:00
|
|
|
return started;
|
2011-11-23 17:03:09 +00:00
|
|
|
},
|
|
|
|
|
2012-01-15 17:57:39 +00:00
|
|
|
_interactionMove: function( event, pointerPosition ) {
|
|
|
|
this._move( event, pointerPosition );
|
2011-11-23 17:03:09 +00:00
|
|
|
},
|
|
|
|
|
2012-01-15 17:57:39 +00:00
|
|
|
_interactionStop: function( event, pointerPosition ) {
|
|
|
|
this._stop( event, pointerPosition );
|
2011-11-23 17:03:09 +00:00
|
|
|
interaction.started = false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
interaction = $.ui.interaction;
|
|
|
|
$.extend( interaction, {
|
|
|
|
started: false,
|
|
|
|
hooks: {}
|
|
|
|
});
|
|
|
|
|
|
|
|
interaction.hooks.mouse = {
|
|
|
|
setup: function( widget, start ) {
|
2012-05-25 15:10:16 +00:00
|
|
|
widget._bind( widget.widget(), {
|
2011-11-23 17:03:09 +00:00
|
|
|
"mousedown": function( event ) {
|
2012-01-28 15:16:36 +00:00
|
|
|
// only react to the primary button
|
2011-11-23 17:03:09 +00:00
|
|
|
if ( event.which === 1 ) {
|
2012-01-14 21:14:39 +00:00
|
|
|
var started = start( event, event.target, {
|
2012-01-15 17:57:39 +00:00
|
|
|
x: event.pageX,
|
|
|
|
y: event.pageY
|
2012-01-09 02:48:53 +00:00
|
|
|
});
|
2012-01-14 21:14:39 +00:00
|
|
|
|
|
|
|
if ( started ) {
|
2012-01-28 15:16:36 +00:00
|
|
|
// prevent selection
|
2012-01-14 21:14:39 +00:00
|
|
|
event.preventDefault();
|
|
|
|
}
|
2011-11-23 17:03:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2012-01-28 01:57:17 +00:00
|
|
|
handle: function( widget, move, stop ) {
|
2012-01-08 01:49:49 +00:00
|
|
|
function mousemove( event ) {
|
|
|
|
event.preventDefault();
|
2012-01-28 01:57:17 +00:00
|
|
|
move( event, {
|
2012-01-15 17:57:39 +00:00
|
|
|
x: event.pageX,
|
|
|
|
y: event.pageY
|
2012-01-09 02:48:53 +00:00
|
|
|
});
|
2012-01-08 01:49:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function mouseup( event ) {
|
2012-01-28 01:57:17 +00:00
|
|
|
stop( event, {
|
2012-01-15 17:57:39 +00:00
|
|
|
x: event.pageX,
|
|
|
|
y: event.pageY
|
2012-01-09 02:48:53 +00:00
|
|
|
});
|
2012-01-08 01:49:49 +00:00
|
|
|
widget.document
|
|
|
|
.unbind( "mousemove", mousemove )
|
|
|
|
.unbind( "mouseup", mouseup );
|
|
|
|
}
|
|
|
|
|
2011-11-23 17:03:09 +00:00
|
|
|
widget._bind( widget.document, {
|
2012-01-08 01:49:49 +00:00
|
|
|
"mousemove": mousemove,
|
|
|
|
"mouseup": mouseup
|
2011-11-23 17:03:09 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-01-09 03:01:29 +00:00
|
|
|
// WebKit doesn't support TouchList.identifiedTouch()
|
|
|
|
function getTouch( event ) {
|
|
|
|
var touch,
|
|
|
|
touches = event.originalEvent.changedTouches,
|
|
|
|
i = 0, length = touches.length;
|
|
|
|
|
|
|
|
for ( ; i < length; i++ ) {
|
|
|
|
if ( touches[ i ].identifier === touchHook.id ) {
|
|
|
|
return touches[ i ];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-25 15:12:06 +00:00
|
|
|
touchHook = interaction.hooks.touch = {
|
2012-01-09 03:01:29 +00:00
|
|
|
setup: function( widget, start ) {
|
2012-05-25 15:10:16 +00:00
|
|
|
widget._bind( widget.widget(), {
|
2012-01-09 03:01:29 +00:00
|
|
|
"touchstart": function( event ) {
|
2012-01-14 21:14:39 +00:00
|
|
|
var touch, started;
|
2012-01-09 03:01:29 +00:00
|
|
|
|
|
|
|
if ( touchHook.id ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
touch = event.originalEvent.changedTouches.item( 0 );
|
2012-01-14 21:14:39 +00:00
|
|
|
started = start( event, touch.target, {
|
2012-01-15 17:57:39 +00:00
|
|
|
x: touch.pageX,
|
|
|
|
y: touch.pageY
|
2012-01-09 03:01:29 +00:00
|
|
|
});
|
2012-01-14 21:14:39 +00:00
|
|
|
|
|
|
|
if ( started ) {
|
|
|
|
// track which finger is performing the interaction
|
|
|
|
touchHook.id = touch.identifier;
|
|
|
|
// prevent panning/zooming
|
|
|
|
event.preventDefault();
|
|
|
|
}
|
2012-01-09 03:01:29 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2012-01-28 01:57:17 +00:00
|
|
|
handle: function( widget, move, stop ) {
|
|
|
|
function moveHandler( event ) {
|
2012-01-09 03:17:19 +00:00
|
|
|
// TODO: test non-Apple WebKits to see if they allow
|
|
|
|
// zooming/scrolling if we don't preventDefault()
|
2012-01-09 03:01:29 +00:00
|
|
|
var touch = getTouch( event );
|
|
|
|
if ( !touch ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
event.preventDefault();
|
2012-01-28 01:57:17 +00:00
|
|
|
move( event, {
|
2012-01-15 17:57:39 +00:00
|
|
|
x: touch.pageX,
|
|
|
|
y: touch.pageY
|
2012-01-09 03:01:29 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2012-01-28 01:57:17 +00:00
|
|
|
function stopHandler( event ) {
|
2012-01-09 03:01:29 +00:00
|
|
|
var touch = getTouch( event );
|
|
|
|
if ( !touch ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-01-28 01:57:17 +00:00
|
|
|
stop( event, {
|
2012-01-15 17:57:39 +00:00
|
|
|
x: touch.pageX,
|
|
|
|
y: touch.pageY
|
2012-01-09 03:01:29 +00:00
|
|
|
});
|
|
|
|
touchHook.id = null;
|
|
|
|
widget.document
|
2012-01-28 01:57:17 +00:00
|
|
|
.unbind( "touchmove", moveHandler )
|
|
|
|
.unbind( "touchend", stopHandler );
|
2012-01-09 03:01:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
widget._bind( widget.document, {
|
2012-01-28 01:57:17 +00:00
|
|
|
"touchmove": moveHandler,
|
|
|
|
"touchend": stopHandler
|
2012-01-09 03:01:29 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-05-25 15:12:06 +00:00
|
|
|
pointerHook = interaction.hooks.msPointer = {
|
2012-01-09 03:17:19 +00:00
|
|
|
setup: function( widget, start ) {
|
2012-05-25 15:10:16 +00:00
|
|
|
widget._bind( widget.widget(), {
|
2012-01-12 03:04:41 +00:00
|
|
|
"MSPointerDown": function( _event ) {
|
2012-01-14 21:14:39 +00:00
|
|
|
var started,
|
|
|
|
event = _event.originalEvent;
|
2012-01-12 03:04:41 +00:00
|
|
|
|
2012-01-09 03:17:19 +00:00
|
|
|
if ( pointerHook.id ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-01-13 02:25:19 +00:00
|
|
|
// TODO: how can we detect a "right click" with a pen?
|
|
|
|
// TODO: get full details about which and button from MS
|
|
|
|
// touch and pen = 1
|
|
|
|
// primary mouse button = 2
|
|
|
|
if ( event.which > 2 ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-01-14 21:14:39 +00:00
|
|
|
started = start( event, event.target, {
|
2012-01-15 17:57:39 +00:00
|
|
|
x: event.pageX,
|
|
|
|
y: event.pageY
|
2012-01-09 03:17:19 +00:00
|
|
|
});
|
2012-01-14 21:14:39 +00:00
|
|
|
|
|
|
|
if ( started ) {
|
|
|
|
// track which pointer is performing the interaction
|
|
|
|
pointerHook.id = event.pointerId;
|
|
|
|
// prevent panning/zooming
|
|
|
|
event.preventManipulation();
|
|
|
|
// prevent promoting pointer events to mouse events
|
|
|
|
event.preventMouseEvent();
|
|
|
|
}
|
2012-01-09 03:17:19 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2012-01-28 01:57:17 +00:00
|
|
|
handle: function( widget, move, stop ) {
|
|
|
|
function moveHandler( _event ) {
|
2012-01-12 03:31:39 +00:00
|
|
|
var event = _event.originalEvent,
|
|
|
|
pageX = event.pageX,
|
|
|
|
pageY = event.pageY;
|
2012-01-12 03:04:41 +00:00
|
|
|
|
|
|
|
// always prevent manipulation to avoid panning/zooming
|
|
|
|
event.preventManipulation();
|
2012-01-09 03:17:19 +00:00
|
|
|
|
2012-01-12 03:04:41 +00:00
|
|
|
if ( event.pointerId !== pointerHook.id ) {
|
2012-01-09 03:17:19 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-01-12 03:31:39 +00:00
|
|
|
// MS streams events constantly, even if there is no movement
|
|
|
|
// so we optimize by ignoring repeat events
|
|
|
|
if ( pointerHook.x === pageX && pointerHook.y === pageY ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
pointerHook.x = pageX;
|
|
|
|
pointerHook.y = pageY;
|
2012-01-28 01:57:17 +00:00
|
|
|
move( event, {
|
2012-01-15 17:57:39 +00:00
|
|
|
x: pageX,
|
|
|
|
y: pageY
|
2012-01-09 03:17:19 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2012-01-28 01:57:17 +00:00
|
|
|
function stopHandler( _event ) {
|
2012-01-12 03:04:41 +00:00
|
|
|
var event = _event.originalEvent;
|
|
|
|
|
|
|
|
if ( event.pointerId !== pointerHook.id ) {
|
2012-01-09 03:17:19 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-01-28 01:57:17 +00:00
|
|
|
stop( event, {
|
2012-01-15 17:57:39 +00:00
|
|
|
x: event.pageX,
|
|
|
|
y: event.pageY
|
2012-01-09 03:17:19 +00:00
|
|
|
});
|
2012-01-12 03:34:46 +00:00
|
|
|
pointerHook.id = pointerHook.x = pointerHook.y = undefined;
|
2012-01-09 03:17:19 +00:00
|
|
|
widget.document
|
2012-01-28 01:57:17 +00:00
|
|
|
.unbind( "MSPointerMove", moveHandler )
|
|
|
|
.unbind( "MSPointerUp", stopHandler )
|
|
|
|
.unbind( "MSPointerCancel", stopHandler );
|
2012-01-09 03:17:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
widget._bind( widget.document, {
|
2012-01-28 01:57:17 +00:00
|
|
|
"MSPointerMove": moveHandler,
|
|
|
|
"MSPointerUp": stopHandler,
|
|
|
|
"MSPointerCancel": stopHandler
|
2012-01-09 03:17:19 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-11-23 17:03:09 +00:00
|
|
|
})( jQuery );
|