Last active
December 10, 2021 23:03
-
-
Save moos/22ee1584833de27f041c to your computer and use it in GitHub Desktop.
Number sequence handler for Mousetrap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Mousetrap numbers plugin -- add support for 'number' and 'numbers' keywords | |
* | |
* Usage: | |
* | |
* Mousetrap.bind('number', callback) - handle any single number | |
* | |
* Mousetrap.bind('numbers', callback) - handle a sequence of 1+ numbers | |
* | |
* // pre sequence | |
* Mousetrap.bind('a b numbers', callback) - handle a sequence of 'a b' followed by any numbers | |
* | |
* // post sequence | |
* Mousetrap.bind('numbers a b', callback) - handle a sequence of numbers followed by 'a b' | |
* | |
* callback receives (event, combo, numbers). | |
* | |
* Note: the array form of bind() is NOT supported for numbers, ie, | |
* Mousetrap.bind(['numbers'], callback) - NO! | |
* | |
* To use multiple number sequences -- instantiate new Mousetraps (as of v1.5): | |
* | |
* (new Mousetrap()).bind('numbers g', gotoPage) | |
* (new Mousetrap()).bind('numbers f', gotoForm) | |
* | |
* | |
* Created by github.com/moos on 4/4/15. | |
* | |
* MIT License | |
*/ | |
!(function(Mousetrap) { | |
var NUMBERS = '0,1,2,3,4,5,6,7,8,9'; | |
var SEQ_TIMEOUT = 1000; | |
var origBind = Mousetrap.prototype.bind; | |
Mousetrap.prototype.bind = function(keys, callback, action) { | |
// don't handle arrays | |
if (keys instanceof Array) { | |
return origBind.apply(this, arguments); | |
} | |
var key = keys, | |
combo = key; | |
// special key | |
if (key === 'number') { | |
this._bindMultiple.call(this, NUMBERS.split(','), callback, action); | |
return this; | |
} | |
// numbers sequence! | |
if (/numbers/.test(key)) { | |
// remove numbers | |
key = key.replace(/\s*numbers\s*/,''); | |
// make sure multiple spaces in a row become a single space | |
key = key.replace(/\s+/g, ' '); | |
var trapNumbers = new TrapNumbers(callback, combo, !key); | |
// bind post/pre sequence if any | |
if (key) this._bindMultiple.call(this, [key], bind(trapNumbers.onSeqComplete, trapNumbers), action); | |
// bind numbers | |
this.bind('number', bind(trapNumbers.onNumber, trapNumbers), action); | |
return this; | |
} | |
// normal case | |
return origBind.apply(this, arguments); | |
}; | |
var bind = function(fn, context){ | |
return function() { | |
fn.apply(context, arguments); | |
}; | |
}; | |
function TrapNumbers(callback, combo, seqOK){ | |
this.numbers = []; | |
this.combo = combo; | |
this.keyTimer = null; | |
this.callback = callback; | |
this.executeOnLast = /numbers$/.test(combo); | |
this.seqOK = seqOK; | |
} | |
TrapNumbers.prototype = { | |
onNumber: function(e, key) { | |
this.numbers.push(key); | |
this.keyPing(); | |
this.lastEvent = e; | |
}, | |
keyPing: function(){ | |
var self = this; | |
if (this.keyTimer) { | |
clearTimeout(this.keyTimer); | |
} | |
// clear the numbers after a while | |
this.keyTimer = setTimeout(function(){ | |
if (self.executeOnLast) self.execute(); | |
self.reset(); | |
}, SEQ_TIMEOUT); | |
}, | |
reset: function(){ | |
this.numbers = []; | |
this.seqOK = false; | |
}, | |
execute: function(){ | |
if (this.seqOK && this.numbers.length) { | |
this.callback( this.lastEvent, this.combo, this.getNumber()); | |
this.reset(); | |
return true; | |
} | |
return false; | |
}, | |
getNumber: function(){ | |
return Number(this.numbers.join('')); | |
}, | |
/** | |
* sequence complete handler - seq. can be either before or after numbers. | |
*/ | |
onSeqComplete: function() { | |
this.seqOK = true; | |
if (!this.executeOnLast && this.execute()) return; | |
// must be before -- remember seq OK and ping timer | |
// also: reset any previously entered numbers | |
this.reset(); | |
this.seqOK = true; | |
this.keyPing(); | |
} | |
}; | |
}) (Mousetrap); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment