File: /var/www/html/wp-content/plugins/advanced-ads-slider/src/js/jquery.event.move.js
// DOM.event.move
//
// 2.0.0
//
// Stephen Band
//
// Triggers 'movestart', 'move' and 'moveend' events after
// mousemoves following a mousedown cross a distance threshold,
// similar to the native 'dragstart', 'drag' and 'dragend' events.
// Move events are throttled to animation frames. Move event objects
// have the properties:
//
// pageX:
// pageY: Page coordinates of pointer.
// startX:
// startY: Page coordinates of pointer at movestart.
// distX:
// distY: Distance the pointer has moved since movestart.
// deltaX:
// deltaY: Distance the finger has moved since last event.
// velocityX:
// velocityY: Average velocity over last few events.
( function ( fn ) {
if ( typeof define === 'function' && define.amd ) {
define( [], fn );
} else if (
typeof module !== 'undefined' &&
module !== null &&
module.exports
) {
module.exports = fn;
} else {
fn();
}
} )( function () {
var assign = Object.assign || ( window.jQuery && jQuery.extend );
// Number of pixels a pressed pointer travels before movestart
// event is fired.
var threshold = 8;
// Shim for requestAnimationFrame, falling back to timer. See:
// see http://paulirish.com/2011/requestanimationframe-for-smart-animating/
var requestFrame = ( function () {
return (
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function ( fn, element ) {
return window.setTimeout( function () {
fn();
}, 25 );
}
);
} )();
var ignoreTags = {
textarea: true,
input: true,
select: true,
button: true,
};
var mouseevents = {
move: 'mousemove',
cancel: 'mouseup dragstart',
end: 'mouseup',
};
var touchevents = {
move: 'touchmove',
cancel: 'touchend',
end: 'touchend',
};
var rspaces = /\s+/;
// DOM Events
var eventOptions = { bubbles: true, cancelable: true };
var eventsSymbol = Symbol( 'events' );
function createEvent( type ) {
return new CustomEvent( type, eventOptions );
}
function getEvents( node ) {
return node[ eventsSymbol ] || ( node[ eventsSymbol ] = {} );
}
function on( node, types, fn, data, selector ) {
types = types.split( rspaces );
var events = getEvents( node );
var i = types.length;
var handlers, type;
function handler( e ) {
fn( e, data );
}
while ( i-- ) {
type = types[ i ];
handlers = events[ type ] || ( events[ type ] = [] );
handlers.push( [ fn, handler ] );
node.addEventListener( type, handler );
}
}
function off( node, types, fn, selector ) {
types = types.split( rspaces );
var events = getEvents( node );
var i = types.length;
var type, handlers, k;
if ( ! events ) {
return;
}
while ( i-- ) {
type = types[ i ];
handlers = events[ type ];
if ( ! handlers ) {
continue;
}
k = handlers.length;
while ( k-- ) {
if ( handlers[ k ][ 0 ] === fn ) {
node.removeEventListener( type, handlers[ k ][ 1 ] );
handlers.splice( k, 1 );
}
}
}
}
function trigger( node, type, properties ) {
// Don't cache events. It prevents you from triggering an event of a
// given type from inside the handler of another event of that type.
var event = createEvent( type );
if ( properties ) {
assign( event, properties );
}
node.dispatchEvent( event );
}
// Constructors
function Timer( fn ) {
var callback = fn,
active = false,
running = false;
function trigger( time ) {
if ( active ) {
callback();
requestFrame( trigger );
running = true;
active = false;
} else {
running = false;
}
}
this.kick = function ( fn ) {
active = true;
if ( ! running ) {
trigger();
}
};
this.end = function ( fn ) {
var cb = callback;
if ( ! fn ) {
return;
}
// If the timer is not running, simply call the end callback.
if ( ! running ) {
fn();
}
// If the timer is running, and has been kicked lately, then
// queue up the current callback and the end callback, otherwise
// just the end callback.
else {
callback = active
? function () {
cb();
fn();
}
: fn;
active = true;
}
};
}
// Functions
function noop() {}
function preventDefault( e ) {
e.preventDefault();
}
function isIgnoreTag( e ) {
return !! ignoreTags[ e.target.tagName.toLowerCase() ];
}
function isPrimaryButton( e ) {
// Ignore mousedowns on any button other than the left (or primary)
// mouse button, or when a modifier key is pressed.
return e.which === 1 && ! e.ctrlKey && ! e.altKey;
}
function identifiedTouch( touchList, id ) {
var i, l;
if ( touchList.identifiedTouch ) {
return touchList.identifiedTouch( id );
}
// touchList.identifiedTouch() does not exist in
// webkit yet… we must do the search ourselves...
i = -1;
l = touchList.length;
while ( ++i < l ) {
if ( touchList[ i ].identifier === id ) {
return touchList[ i ];
}
}
}
function changedTouch( e, data ) {
var touch = identifiedTouch( e.changedTouches, data.identifier );
// This isn't the touch you're looking for.
if ( ! touch ) {
return;
}
// Chrome Android (at least) includes touches that have not
// changed in e.changedTouches. That's a bit annoying. Check
// that this touch has changed.
if ( touch.pageX === data.pageX && touch.pageY === data.pageY ) {
return;
}
return touch;
}
// Handlers that decide when the first movestart is triggered
function mousedown( e ) {
// Ignore non-primary buttons
if ( ! isPrimaryButton( e ) ) {
return;
}
// Ignore form and interactive elements
if ( isIgnoreTag( e ) ) {
return;
}
on( document, mouseevents.move, mousemove, e );
on( document, mouseevents.cancel, mouseend, e );
}
function mousemove( e, data ) {
checkThreshold( e, data, e, removeMouse );
}
function mouseend( e, data ) {
removeMouse();
}
function removeMouse() {
off( document, mouseevents.move, mousemove );
off( document, mouseevents.cancel, mouseend );
}
function touchstart( e ) {
// Don't get in the way of interaction with form elements
if ( ignoreTags[ e.target.tagName.toLowerCase() ] ) {
return;
}
var touch = e.changedTouches[ 0 ];
// iOS live updates the touch objects whereas Android gives us copies.
// That means we can't trust the touchstart object to stay the same,
// so we must copy the data. This object acts as a template for
// movestart, move and moveend event objects.
var data = {
target: touch.target,
pageX: touch.pageX,
pageY: touch.pageY,
identifier: touch.identifier,
// The only way to make handlers individually unbindable is by
// making them unique.
touchmove: function ( e, data ) {
touchmove( e, data );
},
touchend: function ( e, data ) {
touchend( e, data );
},
};
on( document, touchevents.move, data.touchmove, data );
on( document, touchevents.cancel, data.touchend, data );
}
function touchmove( e, data ) {
var touch = changedTouch( e, data );
if ( ! touch ) {
return;
}
checkThreshold( e, data, touch, removeTouch );
}
function touchend( e, data ) {
var touch = identifiedTouch( e.changedTouches, data.identifier );
if ( ! touch ) {
return;
}
removeTouch( data );
}
function removeTouch( data ) {
off( document, touchevents.move, data.touchmove );
off( document, touchevents.cancel, data.touchend );
}
function checkThreshold( e, data, touch, fn ) {
var distX = touch.pageX - data.pageX;
var distY = touch.pageY - data.pageY;
// Do nothing if the threshold has not been crossed.
if ( distX * distX + distY * distY < threshold * threshold ) {
return;
}
triggerStart( e, data, touch, distX, distY, fn );
}
function triggerStart( e, data, touch, distX, distY, fn ) {
var touches = e.targetTouches;
var time = e.timeStamp - data.timeStamp;
// Create a movestart object with some special properties that
// are passed only to the movestart handlers.
var template = {
altKey: e.altKey,
ctrlKey: e.ctrlKey,
shiftKey: e.shiftKey,
startX: data.pageX,
startY: data.pageY,
distX: distX,
distY: distY,
deltaX: distX,
deltaY: distY,
pageX: touch.pageX,
pageY: touch.pageY,
velocityX: distX / time,
velocityY: distY / time,
identifier: data.identifier,
targetTouches: touches,
finger: touches ? touches.length : 1,
enableMove: function () {
this.moveEnabled = true;
this.enableMove = noop;
e.preventDefault();
},
};
// Trigger the movestart event.
trigger( data.target, 'movestart', template );
// Unbind handlers that tracked the touch or mouse up till now.
fn( data );
}
// Handlers that control what happens following a movestart
function activeMousemove( e, data ) {
var timer = data.timer;
data.touch = e;
data.timeStamp = e.timeStamp;
timer.kick();
}
function activeMouseend( e, data ) {
var target = data.target;
var event = data.event;
var timer = data.timer;
removeActiveMouse();
endEvent( target, event, timer, function () {
// Unbind the click suppressor, waiting until after mouseup
// has been handled.
setTimeout( function () {
off( target, 'click', preventDefault );
}, 0 );
} );
}
function removeActiveMouse() {
off( document, mouseevents.move, activeMousemove );
off( document, mouseevents.end, activeMouseend );
}
function activeTouchmove( e, data ) {
var event = data.event;
var timer = data.timer;
var touch = changedTouch( e, event );
if ( ! touch ) {
return;
}
// Stop the interface from gesturing
e.preventDefault();
event.targetTouches = e.targetTouches;
data.touch = touch;
data.timeStamp = e.timeStamp;
timer.kick();
}
function activeTouchend( e, data ) {
var target = data.target;
var event = data.event;
var timer = data.timer;
var touch = identifiedTouch( e.changedTouches, event.identifier );
// This isn't the touch you're looking for.
if ( ! touch ) {
return;
}
removeActiveTouch( data );
endEvent( target, event, timer );
}
function removeActiveTouch( data ) {
off( document, touchevents.move, data.activeTouchmove );
off( document, touchevents.end, data.activeTouchend );
}
// Logic for triggering move and moveend events
function updateEvent( event, touch, timeStamp ) {
var time = timeStamp - event.timeStamp;
event.distX = touch.pageX - event.startX;
event.distY = touch.pageY - event.startY;
event.deltaX = touch.pageX - event.pageX;
event.deltaY = touch.pageY - event.pageY;
// Average the velocity of the last few events using a decay
// curve to even out spurious jumps in values.
event.velocityX = 0.3 * event.velocityX + ( 0.7 * event.deltaX ) / time;
event.velocityY = 0.3 * event.velocityY + ( 0.7 * event.deltaY ) / time;
event.pageX = touch.pageX;
event.pageY = touch.pageY;
}
function endEvent( target, event, timer, fn ) {
timer.end( function () {
trigger( target, 'moveend', event );
return fn && fn();
} );
}
// Set up the DOM
function movestart( e ) {
if ( e.defaultPrevented ) {
return;
}
if ( ! e.moveEnabled ) {
return;
}
var event = {
startX: e.startX,
startY: e.startY,
pageX: e.pageX,
pageY: e.pageY,
distX: e.distX,
distY: e.distY,
deltaX: e.deltaX,
deltaY: e.deltaY,
velocityX: e.velocityX,
velocityY: e.velocityY,
identifier: e.identifier,
targetTouches: e.targetTouches,
finger: e.finger,
};
var data = {
target: e.target,
event: event,
timer: new Timer( update ),
touch: undefined,
timeStamp: e.timeStamp,
};
function update( time ) {
updateEvent( event, data.touch, data.timeStamp );
trigger( data.target, 'move', event );
}
if ( e.identifier === undefined ) {
// We're dealing with a mouse event.
// Stop clicks from propagating during a move
on( e.target, 'click', preventDefault );
on( document, mouseevents.move, activeMousemove, data );
on( document, mouseevents.end, activeMouseend, data );
} else {
// In order to unbind correct handlers they have to be unique
data.activeTouchmove = function ( e, data ) {
activeTouchmove( e, data );
};
data.activeTouchend = function ( e, data ) {
activeTouchend( e, data );
};
// We're dealing with a touch.
on( document, touchevents.move, data.activeTouchmove, data );
on( document, touchevents.end, data.activeTouchend, data );
}
}
on( document, 'mousedown', mousedown );
on( document, 'touchstart', touchstart );
on( document, 'movestart', movestart );
// jQuery special events
//
// jQuery event objects are copies of DOM event objects. They need
// a little help copying the move properties across.
if ( ! window.jQuery ) {
return;
}
var properties =
'startX startY pageX pageY distX distY deltaX deltaY velocityX velocityY'.split(
' '
);
function enableMove1( e ) {
e.enableMove();
}
function enableMove2( e ) {
e.enableMove();
}
function enableMove3( e ) {
e.enableMove();
}
function add( handleObj ) {
var handler = handleObj.handler;
handleObj.handler = function ( e ) {
// Copy move properties across from originalEvent
var i = properties.length;
var property;
while ( i-- ) {
property = properties[ i ];
e[ property ] = e.originalEvent[ property ];
}
handler.apply( this, arguments );
};
}
jQuery.event.special.movestart = {
setup: function () {
// Movestart must be enabled to allow other move events
on( this, 'movestart', enableMove1 );
// Do listen to DOM events
return false;
},
teardown: function () {
off( this, 'movestart', enableMove1 );
return false;
},
add: add,
};
jQuery.event.special.move = {
setup: function () {
on( this, 'movestart', enableMove2 );
return false;
},
teardown: function () {
off( this, 'movestart', enableMove2 );
return false;
},
add: add,
};
jQuery.event.special.moveend = {
setup: function () {
on( this, 'movestart', enableMove3 );
return false;
},
teardown: function () {
off( this, 'movestart', enableMove3 );
return false;
},
add: add,
};
} );