diff --git a/mousetrap.js b/mousetrap.js index eea6f61e..e09df023 100644 --- a/mousetrap.js +++ b/mousetrap.js @@ -170,7 +170,7 @@ * * @param {Element|HTMLDocument} object * @param {string} type - * @param {Function} callback + * @param {EventListenerOrEventListenerObject} callback * @returns void */ function _addEvent(object, type, callback) { @@ -181,6 +181,21 @@ object.attachEvent('on' + type, callback); } + /** + * cross browser remove event method + * + * @param {Element|HTMLDocument} object + * @param {string} type + * @param {EventListenerOrEventListenerObject} callback + * @returns void + */ + function _removeEvent (object, type, callback) { + if (object.removeEventListener) { + object.removeEventListener(type, callback, false); + return; + } + object.detachEvent('on' + type, callback); + } /** * takes the event and returns the key character @@ -707,35 +722,6 @@ _ignoreNextKeypress = processedSequenceCallback && e.type == 'keydown'; }; - /** - * handles a keydown event - * - * @param {Event} e - * @returns void - */ - function _handleKeyEvent(e) { - - // normalize e.which for key events - // @see http://stackoverflow.com/questions/4285627/javascript-keycode-vs-charcode-utter-confusion - if (typeof e.which !== 'number') { - e.which = e.keyCode; - } - - var character = _characterFromEvent(e); - - // no character found then stop - if (!character) { - return; - } - - // need to use === for the character check because the character can be 0 - if (e.type == 'keyup' && _ignoreNextKeyup === character) { - _ignoreNextKeyup = false; - return; - } - - self.handleKey(character, _eventModifiers(e), e); - } /** * called to set a 1 second timeout on the specified sequence @@ -885,12 +871,64 @@ } }; + /** + * handles a keydown event + * + * @param {Event} e + * @returns void + */ + self._handleKeyEvent = function (e) { + + // normalize e.which for key events + // @see http://stackoverflow.com/questions/4285627/javascript-keycode-vs-charcode-utter-confusion + if (typeof e.which !== 'number') { + e.which = e.keyCode; + } + + var character = _characterFromEvent(e); + + // no character found then stop + if (!character) { + return; + } + + // need to use === for the character check because the character can be 0 + if (e.type == 'keyup' && _ignoreNextKeyup === character) { + _ignoreNextKeyup = false; + return; + } + + self.handleKey(character, _eventModifiers(e), e); + } + // start! - _addEvent(targetElement, 'keypress', _handleKeyEvent); - _addEvent(targetElement, 'keydown', _handleKeyEvent); - _addEvent(targetElement, 'keyup', _handleKeyEvent); + _addEvent(targetElement, 'keypress', self._handleKeyEvent); + _addEvent(targetElement, 'keydown', self._handleKeyEvent); + _addEvent(targetElement, 'keyup', self._handleKeyEvent); } + /** + * destroy mousetrap object + * + * - call reset on the mousetrap object ( removing all binding ) + * - remove all javascript event listener from target element or document + * - remove all reference to target + * + * @return void + */ + + Mousetrap.prototype.destroy = function () { + var self = this + + self.reset() + + _removeEvent(self.target, 'keypress', self._handleKeyEvent); + _removeEvent(self.target, 'keydown', self._handleKeyEvent); + _removeEvent(self.target, 'keyup', self._handleKeyEvent); + + self.target = undefined + self._handleKeyEvent = undefined + } /** * binds an event to mousetrap * diff --git a/mousetrap.min.js b/mousetrap.min.js index 105ae55b..598dddf4 100644 --- a/mousetrap.min.js +++ b/mousetrap.min.js @@ -1,11 +1 @@ -/* mousetrap v1.6.2 craig.is/killing/mice */ -(function(p,t,h){function u(a,b,d){a.addEventListener?a.addEventListener(b,d,!1):a.attachEvent("on"+b,d)}function y(a){if("keypress"==a.type){var b=String.fromCharCode(a.which);a.shiftKey||(b=b.toLowerCase());return b}return m[a.which]?m[a.which]:q[a.which]?q[a.which]:String.fromCharCode(a.which).toLowerCase()}function E(a){var b=[];a.shiftKey&&b.push("shift");a.altKey&&b.push("alt");a.ctrlKey&&b.push("ctrl");a.metaKey&&b.push("meta");return b}function v(a){return"shift"==a||"ctrl"==a||"alt"==a|| -"meta"==a}function z(a,b){var d,e=[];var c=a;"+"===c?c=["+"]:(c=c.replace(/\+{2}/g,"+plus"),c=c.split("+"));for(d=0;dh||m.hasOwnProperty(h)&&(n[m[h]]=h)}d=n[c]?"keydown":"keypress"}"keypress"==d&&e.length&&(d="keydown");return{key:k,modifiers:e,action:d}}function C(a,b){return null===a||a===t?!1:a===b?!0:C(a.parentNode,b)}function e(a){function b(a){a= -a||{};var b=!1,l;for(l in n)a[l]?b=!0:n[l]=0;b||(w=!1)}function d(a,b,r,g,F,e){var l,D=[],h=r.type;if(!f._callbacks[a])return[];"keyup"==h&&v(a)&&(b=[a]);for(l=0;l":".","?":"/","|":"\\"},A={option:"alt",command:"meta","return":"enter", -escape:"esc",plus:"+",mod:/Mac|iPod|iPhone|iPad/.test(navigator.platform)?"meta":"ctrl"},n;for(h=1;20>h;++h)m[111+h]="f"+h;for(h=0;9>=h;++h)m[h+96]=h.toString();e.prototype.bind=function(a,b,d){a=a instanceof Array?a:[a];this._bindMultiple.call(this,a,b,d);return this};e.prototype.unbind=function(a,b){return this.bind.call(this,a,function(){},b)};e.prototype.trigger=function(a,b){if(this._directMap[a+":"+b])this._directMap[a+":"+b]({},a);return this};e.prototype.reset=function(){this._callbacks={}; -this._directMap={};return this};e.prototype.stopCallback=function(a,b){return-1<(" "+b.className+" ").indexOf(" mousetrap ")||C(b,this.target)?!1:"INPUT"==b.tagName||"SELECT"==b.tagName||"TEXTAREA"==b.tagName||b.isContentEditable};e.prototype.handleKey=function(){return this._handleKey.apply(this,arguments)};e.addKeycodes=function(a){for(var b in a)a.hasOwnProperty(b)&&(m[b]=a[b]);n=null};e.init=function(){var a=e(t),b;for(b in a)"_"!==b.charAt(0)&&(e[b]=function(b){return function(){return a[b].apply(a, -arguments)}}(b))};e.init();p.Mousetrap=e;"undefined"!==typeof module&&module.exports&&(module.exports=e);"function"===typeof define&&define.amd&&define(function(){return e})}})("undefined"!==typeof window?window:null,"undefined"!==typeof window?document:null); +!function(e,r,t){if(e){for(var a,o={8:"backspace",9:"tab",13:"enter",16:"shift",17:"ctrl",18:"alt",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"ins",46:"del",91:"meta",93:"meta",224:"meta"},n={106:"*",107:"+",109:"-",110:".",111:"/",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},c={"~":"`","!":"1","@":"2","#":"3",$:"4","%":"5","^":"6","&":"7","*":"8","(":"9",")":"0",_:"-","+":"=",":":";",'"':"'","<":",",">":".","?":"/","|":"\\"},s={option:"alt",command:"meta",return:"enter",escape:"esc",plus:"+",mod:/Mac|iPod|iPhone|iPad/.test(navigator.platform)?"meta":"ctrl"},i=1;i<20;++i)o[111+i]="f"+i;for(i=0;i<=9;++i)o[i+96]=i.toString();w.prototype.destroy=function(){var e=this;e.reset(),l(e.target,"keypress",e._handleKeyEvent),l(e.target,"keydown",e._handleKeyEvent),l(e.target,"keyup",e._handleKeyEvent),e.target=t,e._handleKeyEvent=t},w.prototype.bind=function(e,t,n){return e=e instanceof Array?e:[e],this._bindMultiple.call(this,e,t,n),this},w.prototype.unbind=function(e,t){return this.bind.call(this,e,function(){},t)},w.prototype.trigger=function(e,t){return this._directMap[e+":"+t]&&this._directMap[e+":"+t]({},e),this},w.prototype.reset=function(){return this._callbacks={},this._directMap={},this},w.prototype.stopCallback=function(e,t){return!(-1<(" "+t.className+" ").indexOf(" mousetrap "))&&(!function e(t,n){return null!==t&&t!==r&&(t===n||e(t.parentNode,n))}(t,this.target)&&("INPUT"==t.tagName||"SELECT"==t.tagName||"TEXTAREA"==t.tagName||t.isContentEditable))},w.prototype.handleKey=function(){return this._handleKey.apply(this,arguments)},w.addKeycodes=function(e){for(var t in e)e.hasOwnProperty(t)&&(o[t]=e[t]);a=null},w.init=function(){var t=w(r);for(var e in t)"_"!==e.charAt(0)&&(w[e]=function(e){return function(){return t[e].apply(t,arguments)}}(e))},w.init(),e.Mousetrap=w,"undefined"!=typeof module&&module.exports&&(module.exports=w),"function"==typeof define&&define.amd&&define(function(){return w})}function k(e,t,n){e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent("on"+t,n)}function l(e,t,n){e.removeEventListener?e.removeEventListener(t,n,!1):e.detachEvent("on"+t,n)}function g(e){if("keypress"==e.type){var t=String.fromCharCode(e.which);return e.shiftKey||(t=t.toLowerCase()),t}return o[e.which]?o[e.which]:n[e.which]?n[e.which]:String.fromCharCode(e.which).toLowerCase()}function b(e){return"shift"==e||"ctrl"==e||"alt"==e||"meta"==e}function u(e,t,n){return n||(n=function(){if(!a)for(var e in a={},o)95