Skip to content

Commit

Permalink
jquery__events_type_pointernative: pointerdown event works incorrectl…
Browse files Browse the repository at this point in the history
…y in IE Edge

Use native `PointerEvent` if supported.
fix #1066

Optimise PointerMap class: use native Map class if supported (port
of jquery-archive/PEP#190).
  • Loading branch information
Vladimir Varankin committed Jul 7, 2015
1 parent 22c45c0 commit f6e2b60
Showing 1 changed file with 53 additions and 68 deletions.
121 changes: 53 additions & 68 deletions common.blocks/jquery/__event/_type/jquery__event_type_pointernative.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
/*!
* Basic pointer events polyfill
*/
;(function(global, factory) {

if(typeof modules === 'object' && modules.isDefined('jquery')) {
Expand All @@ -14,25 +11,29 @@ if(typeof modules === 'object' && modules.isDefined('jquery')) {

}(this, function(window, $) {

// include "jquery-pointerevents.js"
var jqEvent = $.event;

// NOTE: Remove jQuery special fixes for pointerevents – we fix them ourself
delete jqEvent.special.pointerenter;
delete jqEvent.special.pointerleave;

if(window.PointerEvent) {
// Have native PointerEvent support, nothing to do than
return;
}

/*!
* Most of source code is taken from PointerEvents Polyfill
* written by Polymer Team (https://github.com/Polymer/PointerEvents)
* and licensed under the BSD License.
*/

var doc = document,
USE_NATIVE_MAP = window.Map && window.Map.prototype.forEach,
HAS_BITMAP_TYPE = window.MSPointerEvent && typeof window.MSPointerEvent.MSPOINTER_TYPE_MOUSE === 'number',
POINTERS_FN = function() { return this.size },
jqEvent = $.event;

// NOTE: Remove jQuery special fixes for pointerevents – we fix them ourself
delete jqEvent.special.pointerenter;
delete jqEvent.special.pointerleave;
undef;

/*!
* Returns a snapshot of inEvent, with writable properties.
* Returns a snapshot of the event, with writable properties.
*
* @param {Event} event An event that contains properties to copy.
* @returns {Object} An object containing shallow copies of `inEvent`'s
Expand Down Expand Up @@ -130,69 +131,53 @@ function PointerEvent(type, params) {
return e;
}

/*!
* Implements a map of pointer states
* @returns {PointerMap}
* @constructor
*/
function PointerMap() {
if(USE_NATIVE_MAP) {
var m = new Map();
m.pointers = POINTERS_FN;
return m;
}

this.keys = [];
this.values = [];
function SparseArrayMap() {
this.array = [];
this.size = 0;
}

PointerMap.prototype = {
set : function(id, event) {
var i = this.keys.indexOf(id);
if(i > -1) {
this.values[i] = event;
} else {
this.keys.push(id);
this.values.push(event);
SparseArrayMap.prototype = {
set : function(k, v) {
if(v === undef) {
return this.delete(k);
}
if(!this.has(k)) {
this.size++;
}
this.array[k] = v;
},

has : function(id) {
return this.keys.indexOf(id) > -1;
has : function(k) {
return this.array[k] !== undef;
},

'delete' : function(id) {
var i = this.keys.indexOf(id);
if(i > -1) {
this.keys.splice(i, 1);
this.values.splice(i, 1);
delete : function(k) {
if(this.has(k)){
delete this.array[k];
this.size--;
}
},

get : function(id) {
var i = this.keys.indexOf(id);
return this.values[i];
get : function(k) {
return this.array[k];
},

clear : function() {
this.keys.length = 0;
this.values.length = 0;
this.array.length = 0;
this.size = 0;
},

// return value, key, map
forEach : function(callback, ctx) {
var keys = this.keys;
this.values.forEach(function(v, i) {
callback.call(ctx, v, keys[i], this);
return this.array.forEach(function(v, k) {
callback.call(ctx, v, k, this);
}, this);
},

pointers : function() {
return this.keys.length;
}
};

// jscs:disable requireMultipleVarDecl
var pointermap = new PointerMap();
var PointerMap = window.Map && window.Map.prototype.forEach? Map : SparseArrayMap,
pointerMap = new PointerMap();

var dispatcher = {
eventMap : {},
Expand Down Expand Up @@ -436,12 +421,12 @@ var mouseEvents = {

mousedown : function(event) {
if(!this.isEventSimulatedFromTouch(event)) {
if(pointermap.has(MOUSE_POINTER_ID)) {
if(pointerMap.has(MOUSE_POINTER_ID)) {
// http://crbug/149091
this.cancel(event);
}

pointermap.set(MOUSE_POINTER_ID, event);
pointerMap.set(MOUSE_POINTER_ID, event);

var e = this.prepareEvent(event);
dispatcher.down(e);
Expand All @@ -457,7 +442,7 @@ var mouseEvents = {

mouseup : function(event) {
if(!this.isEventSimulatedFromTouch(event)) {
var p = pointermap.get(MOUSE_POINTER_ID);
var p = pointerMap.get(MOUSE_POINTER_ID);
if(p && p.button === event.button) {
var e = this.prepareEvent(event);
dispatcher.up(e);
Expand Down Expand Up @@ -487,7 +472,7 @@ var mouseEvents = {
},

cleanupMouse : function() {
pointermap['delete'](MOUSE_POINTER_ID);
pointerMap['delete'](MOUSE_POINTER_ID);
}
};

Expand Down Expand Up @@ -520,8 +505,8 @@ var touchEvents = {
* Sets primary touch if there no pointers, or the only pointer is the mouse
*/
setPrimaryTouch : function(touch) {
if(pointermap.pointers() === 0 ||
(pointermap.pointers() === 1 && pointermap.has(MOUSE_POINTER_ID))) {
if(pointerMap.size === 0 ||
(pointerMap.size === 1 && pointerMap.has(MOUSE_POINTER_ID))) {
this.firstTouch = touch.identifier;
this.firstXY = { X : touch.clientX, Y : touch.clientY };
this.scrolling = null;
Expand Down Expand Up @@ -625,12 +610,12 @@ var touchEvents = {
*/
vacuumTouches : function(touchEvent) {
var touches = touchEvent.touches;
// pointermap.pointers() should be less than length of touches here, as the touchstart has not
// `pointermap.size` should be less than length of touches here, as the touchstart has not
// been processed yet.
if(pointermap.pointers() >= touches.length) {
if(pointerMap.size >= touches.length) {
var d = [];

pointermap.forEach(function(pointer, pointerId) {
pointerMap.forEach(function(pointer, pointerId) {
// Never remove pointerId == 1, which is mouse.
// Touch identifiers are 2 smaller than their pointerId, which is the
// index in pointermap.
Expand Down Expand Up @@ -710,7 +695,7 @@ var touchEvents = {

overDown : function(pEvent) {
var target = pEvent.target;
pointermap.set(pEvent.pointerId, {
pointerMap.set(pEvent.pointerId, {
target : target,
outTarget : target,
outEvent : pEvent
Expand All @@ -721,7 +706,7 @@ var touchEvents = {
},

moveOverOut : function(pEvent) {
var pointer = pointermap.get(pEvent.pointerId);
var pointer = pointerMap.get(pEvent.pointerId);

// a finger drifted off the screen, ignore it
if(!pointer) {
Expand Down Expand Up @@ -770,7 +755,7 @@ var touchEvents = {
},

cleanUpPointer : function(pEvent) {
pointermap['delete'](pEvent.pointerId);
pointerMap['delete'](pEvent.pointerId);
this.removePrimaryPointer(pEvent);
}
};
Expand Down Expand Up @@ -808,7 +793,7 @@ var msEvents = {
},

MSPointerDown : function(event) {
pointermap.set(event.pointerId, event);
pointerMap.set(event.pointerId, event);
var e = this.prepareEvent(event);
dispatcher.down(e);
},
Expand Down Expand Up @@ -841,7 +826,7 @@ var msEvents = {
},

cleanup : function(id) {
pointermap['delete'](id);
pointerMap['delete'](id);
}
};

Expand Down

0 comments on commit f6e2b60

Please sign in to comment.