This commit is contained in:
3
node_modules/teeny-tap/.npmignore
generated
vendored
Normal file
3
node_modules/teeny-tap/.npmignore
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
*.log
|
||||
demo/demo-bundle.js
|
||||
9
node_modules/teeny-tap/CHANGELOG.md
generated
vendored
Normal file
9
node_modules/teeny-tap/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
## 0.2.0
|
||||
|
||||
- Add `useCapture` argument to `createTapListener`.
|
||||
|
||||
## 0.1.0
|
||||
|
||||
- Initial release.
|
||||
21
node_modules/teeny-tap/LICENSE
generated
vendored
Normal file
21
node_modules/teeny-tap/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 David Clark
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
102
node_modules/teeny-tap/README.md
generated
vendored
Normal file
102
node_modules/teeny-tap/README.md
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
# teeny-tap
|
||||
|
||||
**Status: Experimental, Under Active Development**
|
||||
|
||||
Listen for both clicks and click-like touches (not scrolls or drags).
|
||||
|
||||
This library is very small and simple and focused, without any dependencies.
|
||||
It is not a touch gesture library or a complete fastclick-style solution.
|
||||
Plenty of similar libraries exist, but none of them seemed exactly right for
|
||||
my simple needs. For more about the purpose of the library, read ["Why?"](#why).
|
||||
|
||||
This library is heavily inspired by [tap.js](https://github.com/alexgibson/tap.js),
|
||||
which is no longer maintained.
|
||||
|
||||
**[Check out the demo](http://davidtheclark.github.io/teeny-tap/demo/).**
|
||||
|
||||
(If the demo works on your phone, would you mind tweeting me your specs,
|
||||
`@davidtheclark`? That way I can list the devices where we know it works.
|
||||
And of course let me know if you find any bugs!)
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
npm install teeny-tap
|
||||
```
|
||||
|
||||
You will need to be compiling CommonJS modules (browserify or webpack).
|
||||
|
||||
### Browser Support
|
||||
|
||||
IE9+ and everything help, I hope. Testing underway.
|
||||
(If you can help out by trying the demo on your mobile device, please do!)
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var createTapListener = require('teeny-tap');
|
||||
|
||||
var docTapListener = createTapListener(document.documentElement, function(e) {
|
||||
console.log('A tap happened!');
|
||||
});
|
||||
|
||||
// ...
|
||||
docTapListener.remove();
|
||||
```
|
||||
|
||||
That's it. Very simple. You create and remove listeners.
|
||||
|
||||
### API
|
||||
|
||||
#### `var tapListenerInstance = createTapListener(element, callback[, useCapture])`
|
||||
|
||||
Adds a tap listener on `element`, using `addEventListener()`.
|
||||
When there's a tap, `callback` is invoked with
|
||||
the relevant `event` as its argument (either a `click` or `touchend` event).
|
||||
|
||||
**Returns an object with a `remove` function, for removing the listener.**
|
||||
|
||||
#### `tapListenerInstance.remove()`
|
||||
|
||||
Remove the listener that you added when you created `tapListenerInstance`.
|
||||
|
||||
## Why?
|
||||
|
||||
For
|
||||
[react-aria-menubutton](https://github.com/davidtheclark/react-aria-menubutton),
|
||||
I need to close an open menu when the user taps/clicks outside of it.
|
||||
|
||||
The click event wasn't reliable: mobile Safari screws it up.
|
||||
So I needed to **distinguish, on touch devices, between *touches
|
||||
that are scrolling or dragging* and *touches that are clicking*,
|
||||
in situations where the regular `click` event doesn't work**.
|
||||
Existing solutions that I found weren't satisfactory for a few reasons:
|
||||
|
||||
- jQuery or other dependencies I didn't want or need.
|
||||
|
||||
- Many just threw in a `touchstart` or `touchend`
|
||||
listener, in addition to the click; but that alone won't distinguish
|
||||
between tapping and scrolling/dragging, so it's insufficient.
|
||||
The menu might close when you, say, scroll down in order to see more of it.
|
||||
Egad!
|
||||
|
||||
- One solution to the detect-clicks-outside-an-element problem is to add an
|
||||
underlay that covers the page, beneath the element, and listen for clicks on that.
|
||||
However, this prevents the click from getting through and actually
|
||||
*doing* something; so if I click a link outside the open menu,
|
||||
that click only closes the menu, and I have to click *again* to
|
||||
go where I wanted to go. Non-optimal.
|
||||
|
||||
- A number of solutions just use `click` events, which won't
|
||||
work on most browsers on most iPhones and iPads, due to
|
||||
mobile Safari's unique and unpleasant handling of click events.
|
||||
|
||||
- Some went the other way, and had more fine-tuning than I want or need.
|
||||
|
||||
[tap.js](https://github.com/alexgibson/tap.js) pretty much provided exactly what I needed,
|
||||
but that library is no longer maintained so I made this one to carry the torch,
|
||||
to fill the need.
|
||||
|
||||
But know that *I do not like that this exists, do not want it to need to exist*.
|
||||
If you know of a way to accomplish the same goal without this library,
|
||||
please let me know!
|
||||
22
node_modules/teeny-tap/demo/demo.js
generated
vendored
Normal file
22
node_modules/teeny-tap/demo/demo.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
var tapListener = require('..');
|
||||
var count = 0;
|
||||
var docTapListener;
|
||||
|
||||
document.getElementById('init').addEventListener('click', function(e) {
|
||||
e.stopPropagation();
|
||||
if (docTapListener) return;
|
||||
docTapListener = true;
|
||||
docTapListener = tapListener(document.documentElement, registerTap);
|
||||
});
|
||||
|
||||
document.getElementById('remove').addEventListener('click', function(e) {
|
||||
e.stopPropagation();
|
||||
if (docTapListener) docTapListener.remove();
|
||||
docTapListener = null;
|
||||
});
|
||||
|
||||
function registerTap(e) {
|
||||
console.log(e.type);
|
||||
count++;
|
||||
document.getElementById('count').innerHTML = count;
|
||||
}
|
||||
83
node_modules/teeny-tap/demo/index.html
generated
vendored
Normal file
83
node_modules/teeny-tap/demo/index.html
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>tap-listener demo</title>
|
||||
<meta name="description" content="A demo of tap-listener">
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
.counterContainer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #eee;
|
||||
padding: 0 1em;
|
||||
}
|
||||
.counter {
|
||||
font-size: 3em;
|
||||
font-weight: bold;
|
||||
}
|
||||
.scrollArea {
|
||||
background: pink;
|
||||
height: 1000px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>tap-listener demo</h1>
|
||||
|
||||
<p>
|
||||
This library's purpose is to distinguish on touch devices between
|
||||
taps and non-taps (e.g. scrolls and drags) in situations where
|
||||
the "click" event will not work.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>If you find anything wrong in this demo, please file a bugs
|
||||
<a href="https://github.com/davidtheclark/tap-listener">back in the repo</a>.</strong>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Click this button to initiate the tap listener:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<button id="init">
|
||||
Go!
|
||||
</button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Every time you tap (or click), the number at the bottom of the screen should increment.
|
||||
When you touch-scroll or -drag, it should not.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Also, try clicking this button to remove the tap listener:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<button id="remove">
|
||||
Stop!
|
||||
</button>
|
||||
</p>
|
||||
|
||||
<p class="scrollArea">
|
||||
And here is a lot of space to try scrolling in.
|
||||
(Scrolls should not cause tap events.)
|
||||
</p>
|
||||
|
||||
<div class="counterContainer">
|
||||
tap count:
|
||||
<span id="count" class="counter">
|
||||
0
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<script src="demo-bundle.js"></script>
|
||||
</body>
|
||||
76
node_modules/teeny-tap/index.js
generated
vendored
Normal file
76
node_modules/teeny-tap/index.js
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
module.exports = function createTapListener(el, callback, useCapture) {
|
||||
var startX = 0;
|
||||
var startY = 0;
|
||||
var touchStarted = false;
|
||||
var touchMoved = false;
|
||||
// Assume that if a touchstart event initiates, the user is
|
||||
// using touch and click events should be ignored.
|
||||
// If this isn't done, touch-clicks will fire the callback
|
||||
// twice: once on touchend, once on the subsequent "click".
|
||||
var usingTouch = false;
|
||||
|
||||
el.addEventListener('click', handleClick, useCapture);
|
||||
el.addEventListener('touchstart', handleTouchstart, useCapture);
|
||||
|
||||
function handleClick(e) {
|
||||
if (usingTouch) return;
|
||||
callback(e);
|
||||
}
|
||||
|
||||
function handleTouchstart(e) {
|
||||
usingTouch = true;
|
||||
|
||||
if (touchStarted) return;
|
||||
touchStarted = true;
|
||||
|
||||
el.addEventListener('touchmove', handleTouchmove, useCapture);
|
||||
el.addEventListener('touchend', handleTouchend, useCapture);
|
||||
el.addEventListener('touchcancel', handleTouchcancel, useCapture);
|
||||
|
||||
touchMoved = false;
|
||||
startX = e.touches[0].clientX;
|
||||
startY = e.touches[0].clientY;
|
||||
}
|
||||
|
||||
function handleTouchmove(e) {
|
||||
if (touchMoved) return;
|
||||
|
||||
if (
|
||||
Math.abs(e.touches[0].clientX - startX) <= 10
|
||||
&& Math.abs(e.touches[0].clientY - startY) <= 10
|
||||
) return;
|
||||
|
||||
touchMoved = true;
|
||||
}
|
||||
|
||||
function handleTouchend(e) {
|
||||
touchStarted = false;
|
||||
removeSecondaryTouchListeners();
|
||||
if (!touchMoved) {
|
||||
callback(e);
|
||||
}
|
||||
}
|
||||
|
||||
function handleTouchcancel() {
|
||||
touchStarted = false;
|
||||
touchMoved = false;
|
||||
startX = 0;
|
||||
startY = 0;
|
||||
}
|
||||
|
||||
function removeSecondaryTouchListeners() {
|
||||
el.removeEventListener('touchmove', handleTouchmove, useCapture);
|
||||
el.removeEventListener('touchend', handleTouchend, useCapture);
|
||||
el.removeEventListener('touchcancel', handleTouchcancel, useCapture);
|
||||
}
|
||||
|
||||
function removeTapListener() {
|
||||
el.removeEventListener('click', handleClick, useCapture);
|
||||
el.removeEventListener('touchstart', handleTouchstart, useCapture);
|
||||
removeSecondaryTouchListeners();
|
||||
}
|
||||
|
||||
return {
|
||||
remove: removeTapListener,
|
||||
};
|
||||
};
|
||||
34
node_modules/teeny-tap/package.json
generated
vendored
Normal file
34
node_modules/teeny-tap/package.json
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "teeny-tap",
|
||||
"version": "0.2.0",
|
||||
"description": "Listen for both clicks and click-like touches (not scrolls or drags)",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"demo-dev": "watchify demo/demo.js -o demo/demo-bundle.js -v & http-server demo",
|
||||
"demo-bundle": "browserify demo/demo.js > demo/demo-bundle.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/davidtheclark/teeny-tap.git"
|
||||
},
|
||||
"keywords": [
|
||||
"tap",
|
||||
"click",
|
||||
"mobile",
|
||||
"touch",
|
||||
"event",
|
||||
"listener"
|
||||
],
|
||||
"author": "David Clark",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/davidtheclark/teeny-tap/issues"
|
||||
},
|
||||
"homepage": "https://github.com/davidtheclark/teeny-tap#readme",
|
||||
"devDependencies": {
|
||||
"browserify": "13.0.0",
|
||||
"http-server": "0.8.5",
|
||||
"watchify": "3.7.0"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user