diff --git a/README.md b/README.md index b822d78..157b6b8 100644 --- a/README.md +++ b/README.md @@ -8,18 +8,6 @@ Now with more information and less opinion! What Input adds data attributes to the `window` based on the type of input being used. It also exposes a simple API that can be used for scripting interactions. -### Changes from v4 - -* __Added:__ A the ability to add and remove custom callback function when the input or intent changes with `whatInput.registerOnChange` and `whatInput.unRegisterOnChange`. -* __Added:__ A `data-whatelement` attribute exposes any currently focused DOM element (i.e. `data-whatelement="a"` or `data-whatelement="input"`). -* __Added:__ A `data-whatclasses` attribute exposes any currently focused element's classes as a comma-separated list (i.e. `data-whatclasses="class1,class2"`). -* __Added:__ An API option to provide a custom array of keycodes that will be ignored. -* __Changed:__ Typing in form fields is no longer filtered out. The `data-whatinput` attribute immediately reflects the current input. The `data-whatintent` attribute now takes on the role of remembering mouse input prior to typing in or clicking on a form field. -* __Changed:__ If you use the Tab key to move from one input to another one - the `data-whatinput` attribute reflects the current input (switches to "keyboard"). -* __Removed:__ `whatInput.types()` API option. -* __Removed:__ Bower support. -* __Fixed:__ Using mouse modifier keys (`shift`, `control`, `alt`, `cmd`) no longer toggles back to keyboard. - ## How it works What Input uses event bubbling on the `window` to watch for mouse, keyboard and touch events (via `mousedown`, `keydown` and `touchstart`). It then sets or updates a `data-whatinput` attribute. @@ -205,6 +193,24 @@ Add your own, or grab the bundle included here. ``` +## Changelog + +### v5.0.3 + +* __Fixed:__ Event buffer for touch was not working correctly. + +### Changes from v4 + +* __Added:__ A the ability to add and remove custom callback function when the input or intent changes with `whatInput.registerOnChange` and `whatInput.unRegisterOnChange`. +* __Added:__ A `data-whatelement` attribute exposes any currently focused DOM element (i.e. `data-whatelement="a"` or `data-whatelement="input"`). +* __Added:__ A `data-whatclasses` attribute exposes any currently focused element's classes as a comma-separated list (i.e. `data-whatclasses="class1,class2"`). +* __Added:__ An API option to provide a custom array of keycodes that will be ignored. +* __Changed:__ Typing in form fields is no longer filtered out. The `data-whatinput` attribute immediately reflects the current input. The `data-whatintent` attribute now takes on the role of remembering mouse input prior to typing in or clicking on a form field. +* __Changed:__ If you use the Tab key to move from one input to another one - the `data-whatinput` attribute reflects the current input (switches to "keyboard"). +* __Removed:__ `whatInput.types()` API option. +* __Removed:__ Bower support. +* __Fixed:__ Using mouse modifier keys (`shift`, `control`, `alt`, `cmd`) no longer toggles back to keyboard. + ## Acknowledgments Special thanks to [Viget](http://viget.com/) for their encouragement and commitment to open source projects. Visit [code.viget.com](http://code.viget.com/) to see more projects from [Viget](http://viget.com). diff --git a/dist/what-input.js b/dist/what-input.js index 3c315b9..14bd5c5 100644 --- a/dist/what-input.js +++ b/dist/what-input.js @@ -79,6 +79,9 @@ return /******/ (function(modules) { // webpackBootstrap // last used input intent var currentIntent = currentInput; + // event buffer timer + var eventTimer = null; + // form input types var formInputs = ['input', 'select', 'textarea']; @@ -161,20 +164,20 @@ return /******/ (function(modules) { // webpackBootstrap // pointer events (mouse, pen, touch) if (window.PointerEvent) { - window.addEventListener('pointerdown', updateInput); + window.addEventListener('pointerdown', setInput); window.addEventListener('pointermove', setIntent); } else if (window.MSPointerEvent) { - window.addEventListener('MSPointerDown', updateInput); + window.addEventListener('MSPointerDown', setInput); window.addEventListener('MSPointerMove', setIntent); } else { // mouse events - window.addEventListener('mousedown', updateInput); + window.addEventListener('mousedown', setInput); window.addEventListener('mousemove', setIntent); // touch events if ('ontouchstart' in window) { - window.addEventListener('touchstart', touchBuffer, options); - window.addEventListener('touchend', touchBuffer); + window.addEventListener('touchstart', eventBuffer, options); + window.addEventListener('touchend', setInput); } } @@ -182,8 +185,8 @@ return /******/ (function(modules) { // webpackBootstrap window.addEventListener(detectWheel(), setIntent, options); // keyboard events - window.addEventListener('keydown', updateInput); - window.addEventListener('keyup', updateInput); + window.addEventListener('keydown', eventBuffer); + window.addEventListener('keyup', eventBuffer); // focus events window.addEventListener('focusin', setElement); @@ -191,8 +194,8 @@ return /******/ (function(modules) { // webpackBootstrap }; // checks conditions before updating new input - var updateInput = function updateInput(event) { - // only execute if the touch buffer timer isn't running + var setInput = function setInput(event) { + // only execute if the event buffer timer isn't running if (!isBuffering) { var eventKey = event.which; var value = inputMap[event.type]; @@ -233,7 +236,7 @@ return /******/ (function(modules) { // webpackBootstrap // test to see if `mousemove` happened relative to the screen to detect scrolling versus mousemove detectScrolling(event); - // only execute if the touch buffer timer isn't running + // only execute if the event buffer timer isn't running // or scrolling isn't happening if (!isBuffering && !isScrolling) { var value = inputMap[event.type]; @@ -264,16 +267,22 @@ return /******/ (function(modules) { // webpackBootstrap docElem.removeAttribute('data-whatclasses'); }; - // buffers touch events because they frequently also fire mouse events - var touchBuffer = function touchBuffer(event) { - if (event.type === 'touchstart') { - isBuffering = false; + // buffers events that frequently also fire mouse events + var eventBuffer = function eventBuffer(event) { + // set the current input + setInput(event); - // set the current input - updateInput(event); - } else { - isBuffering = true; - } + // clear the timer if it happens to be running + window.clearTimeout(eventTimer); + + // set the isBuffering to `true` + isBuffering = true; + + // run the timer + eventTimer = window.setTimeout(function () { + // if the timer runs out, set isBuffering back to `false` + isBuffering = false; + }, 100); }; /* diff --git a/dist/what-input.min.js b/dist/what-input.min.js index 0568c22..a1ad66e 100644 --- a/dist/what-input.min.js +++ b/dist/what-input.min.js @@ -4,4 +4,4 @@ * @link https://github.com/ten1seven/what-input * @license MIT */ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("whatInput",[],t):"object"==typeof exports?exports.whatInput=t():e.whatInput=t()}(this,function(){return function(e){function t(o){if(n[o])return n[o].exports;var i=n[o]={exports:{},id:o,loaded:!1};return e[o].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t){"use strict";e.exports=function(){var e=document.documentElement,t=null,n="initial",o=n,i=["input","select","textarea"],r=[],u=[16,17,18,91,93],d={keydown:"keyboard",keyup:"keyboard",mousedown:"mouse",mousemove:"mouse",MSPointerDown:"pointer",MSPointerMove:"pointer",pointerdown:"pointer",pointermove:"pointer",touchstart:"touch"},a=!1,s=!1,c={x:null,y:null},p={2:"touch",3:"touch",4:"mouse"},w=!1;try{var f=Object.defineProperty({},"passive",{get:function(){w=!0}});window.addEventListener("test",null,f)}catch(e){}var v=function(){var e=!!w&&{passive:!0};window.PointerEvent?(window.addEventListener("pointerdown",l),window.addEventListener("pointermove",h)):window.MSPointerEvent?(window.addEventListener("MSPointerDown",l),window.addEventListener("MSPointerMove",h)):(window.addEventListener("mousedown",l),window.addEventListener("mousemove",h),"ontouchstart"in window&&(window.addEventListener("touchstart",L,e),window.addEventListener("touchend",L))),window.addEventListener(g(),h,e),window.addEventListener("keydown",l),window.addEventListener("keyup",l),window.addEventListener("focusin",y),window.addEventListener("focusout",E)},l=function(e){if(!a){var t=e.which,r=d[e.type];"pointer"===r&&(r=x(e));var s="keyboard"===r&&t&&-1===u.indexOf(t)||"mouse"===r||"touch"===r;if(n!==r&&s&&(n=r,m("input")),o!==r&&s){var c=document.activeElement;c&&c.nodeName&&-1===i.indexOf(c.nodeName.toLowerCase())&&(o=r,m("intent"))}}},m=function(t){e.setAttribute("data-what"+t,"input"===t?n:o),b(t)},h=function(e){if(k(e),!a&&!s){var t=d[e.type];"pointer"===t&&(t=x(e)),o!==t&&(o=t,m("intent"))}},y=function(n){t=n.target.nodeName.toLowerCase(),e.setAttribute("data-whatelement",t),n.target.classList&&n.target.classList.length&&e.setAttribute("data-whatclasses",n.target.classList.toString().replace(" ",","))},E=function(){t=null,e.removeAttribute("data-whatelement"),e.removeAttribute("data-whatclasses")},L=function(e){"touchstart"===e.type?(a=!1,l(e)):a=!0},x=function(e){return"number"==typeof e.pointerType?p[e.pointerType]:"pen"===e.pointerType?"touch":e.pointerType},g=function(){return"onwheel"in document.createElement("div")?"wheel":void 0!==document.onmousewheel?"mousewheel":"DOMMouseScroll"},b=function(e){for(var t=0,i=r.length;t", "license": "MIT", "bugs": { diff --git a/src/scripts/what-input.js b/src/scripts/what-input.js index 3bc7bbe..fb97659 100644 --- a/src/scripts/what-input.js +++ b/src/scripts/what-input.js @@ -15,6 +15,9 @@ module.exports = (() => { // last used input intent let currentIntent = currentInput + // event buffer timer + let eventTimer = null + // form input types const formInputs = ['input', 'select', 'textarea'] @@ -101,20 +104,20 @@ module.exports = (() => { // pointer events (mouse, pen, touch) if (window.PointerEvent) { - window.addEventListener('pointerdown', updateInput) + window.addEventListener('pointerdown', setInput) window.addEventListener('pointermove', setIntent) } else if (window.MSPointerEvent) { - window.addEventListener('MSPointerDown', updateInput) + window.addEventListener('MSPointerDown', setInput) window.addEventListener('MSPointerMove', setIntent) } else { // mouse events - window.addEventListener('mousedown', updateInput) + window.addEventListener('mousedown', setInput) window.addEventListener('mousemove', setIntent) // touch events if ('ontouchstart' in window) { - window.addEventListener('touchstart', touchBuffer, options) - window.addEventListener('touchend', touchBuffer) + window.addEventListener('touchstart', eventBuffer, options) + window.addEventListener('touchend', setInput) } } @@ -122,8 +125,8 @@ module.exports = (() => { window.addEventListener(detectWheel(), setIntent, options) // keyboard events - window.addEventListener('keydown', updateInput) - window.addEventListener('keyup', updateInput) + window.addEventListener('keydown', eventBuffer) + window.addEventListener('keyup', eventBuffer) // focus events window.addEventListener('focusin', setElement) @@ -131,8 +134,8 @@ module.exports = (() => { } // checks conditions before updating new input - const updateInput = event => { - // only execute if the touch buffer timer isn't running + const setInput = event => { + // only execute if the event buffer timer isn't running if (!isBuffering) { let eventKey = event.which let value = inputMap[event.type] @@ -184,7 +187,7 @@ module.exports = (() => { // test to see if `mousemove` happened relative to the screen to detect scrolling versus mousemove detectScrolling(event) - // only execute if the touch buffer timer isn't running + // only execute if the event buffer timer isn't running // or scrolling isn't happening if (!isBuffering && !isScrolling) { let value = inputMap[event.type] @@ -218,16 +221,22 @@ module.exports = (() => { docElem.removeAttribute('data-whatclasses') } - // buffers touch events because they frequently also fire mouse events - const touchBuffer = event => { - if (event.type === 'touchstart') { - isBuffering = false + // buffers events that frequently also fire mouse events + const eventBuffer = event => { + // set the current input + setInput(event) - // set the current input - updateInput(event) - } else { - isBuffering = true - } + // clear the timer if it happens to be running + window.clearTimeout(eventTimer) + + // set the isBuffering to `true` + isBuffering = true + + // run the timer + eventTimer = window.setTimeout(() => { + // if the timer runs out, set isBuffering back to `false` + isBuffering = false + }, 100) } /*