From 8c6d45399a2ae9e93e590e34a0bf454777e851f7 Mon Sep 17 00:00:00 2001 From: "Stuart P. Bentley" Date: Mon, 18 May 2015 21:57:09 +0000 Subject: [PATCH] Replace PointerMap with potentially-sparse-array-based Map polyfill Closes gh-190 --- src/pointermap.js | 60 +++++++++++++++++----------------------- src/touch.js | 6 ++-- tests/unit/pointermap.js | 24 +++++++--------- 3 files changed, 39 insertions(+), 51 deletions(-) diff --git a/src/pointermap.js b/src/pointermap.js index f4211479..9d14bc44 100644 --- a/src/pointermap.js +++ b/src/pointermap.js @@ -2,55 +2,47 @@ * This module implements an map of pointer states */ var USE_MAP = window.Map && window.Map.prototype.forEach; -var POINTERS_FN = function() { return this.size; }; function PointerMap() { - if (USE_MAP) { - var m = new Map(); - m.pointers = POINTERS_FN; - return m; - } else { - this.keys = []; - this.values = []; - } + return USE_MAP ? new Map() : new SparseArrayMap(); +} + +function SparseArrayMap() { + this.array = []; + this.size = 0; } -PointerMap.prototype = { - set: function(inId, inEvent) { - var i = this.keys.indexOf(inId); - if (i > -1) { - this.values[i] = inEvent; - } else { - this.keys.push(inId); - this.values.push(inEvent); +SparseArrayMap.prototype = { + set: function(k, v) { + if (v === undefined) { + return this.delete(k); } + if (!this.has(k)) { + this.size++; + } + this.array[k] = v; }, - has: function(inId) { - return this.keys.indexOf(inId) > -1; + has: function(k) { + return this.array[k] !== undefined; }, - delete: function(inId) { - var i = this.keys.indexOf(inId); - 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(inId) { - var i = this.keys.indexOf(inId); - 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, thisArg) { - this.values.forEach(function(v, i) { - callback.call(thisArg, v, this.keys[i], this); + return this.array.forEach(function(v, k) { + callback.call(thisArg, v, k, this); }, this); - }, - pointers: function() { - return this.keys.length; } }; diff --git a/src/touch.js b/src/touch.js index c6fb8933..ae925a74 100644 --- a/src/touch.js +++ b/src/touch.js @@ -112,7 +112,7 @@ var touchEvents = { setPrimaryTouch: function(inTouch) { // set primary touch if there no pointers, or the only pointer is the mouse - if (pointermap.pointers() === 0 || (pointermap.pointers() === 1 && pointermap.has(1))) { + if (pointermap.size === 0 || (pointermap.size === 1 && pointermap.has(1))) { this.firstTouch = inTouch.identifier; this.firstXY = { X: inTouch.clientX, Y: inTouch.clientY }; this.scrolling = false; @@ -233,9 +233,9 @@ var touchEvents = { vacuumTouches: function(inEvent) { var tl = inEvent.touches; - // pointermap.pointers() should be < tl.length here, as the touchstart has not + // pointermap.size should be < tl.length here, as the touchstart has not // been processed yet. - if (pointermap.pointers() >= tl.length) { + if (pointermap.size >= tl.length) { var d = []; pointermap.forEach(function(value, key) { diff --git a/tests/unit/pointermap.js b/tests/unit/pointermap.js index a6ce6e18..d1da0d94 100644 --- a/tests/unit/pointermap.js +++ b/tests/unit/pointermap.js @@ -14,7 +14,7 @@ define([ 'get', 'has', 'delete', - 'pointers', + 'size', 'clear', 'forEach' ]; @@ -26,20 +26,16 @@ define([ test('PointerMap .set', function() { var p = new PointerMap(); p.set(1, true); - if (!window.Map || !(p instanceof Map)) { - expect(p.keys).to.have.length(1); - expect(p.values).to.have.length(1); - } - expect(p.pointers()).to.equal(1); + expect(p.size).to.equal(1); }); - test('PointerMap .pointers', function() { + test('PointerMap .size', function() { var p = new PointerMap(); - expect(p.pointers).to.be.a('function'); - expect(p.pointers()).to.equal(0); + expect(p.size).to.be.a('number'); + expect(p.size).to.equal(0); p.set(1, true); - expect(p.pointers()).to.equal(1); + expect(p.size).to.equal(1); p.set(1, false); - expect(p.pointers()).to.equal(1); + expect(p.size).to.equal(1); }); test('PointerMap .has', function() { var p = new PointerMap(); @@ -51,16 +47,16 @@ define([ var p = new PointerMap(); p.set(1, true); p.set(2, false); - expect(p.pointers()).to.equal(2); + expect(p.size).to.equal(2); p.delete(1); - expect(p.pointers()).to.equal(1); + expect(p.size).to.equal(1); expect(p.get(2)).to.equal(false); }); test('PointerMap .clear', function() { var p = new PointerMap(); p.set(1, true); p.clear(); - expect(p.pointers()).to.equal(0); + expect(p.size).to.equal(0); }); test('PointerMap .forEach', function() { var p = new PointerMap();