feat: Phase 2.5 - Variant Collections Spreadsheet Editor
Replaces JSON textarea with professional Excel-like spreadsheet interface for managing product variant properties. Features: - Handsontable 14.6.1 spreadsheet component - Property presets (Size, Color, Material, Storage, Custom) - Inline cell editing with Tab/Enter navigation - Context menu for add/remove rows and columns - Keyboard shortcuts (Ctrl+D delete, Ctrl+Enter save, Ctrl+Z undo) - Mobile touch gestures (swipe to delete rows) - Automatic JSON serialization on form submit - Form validation before saving - Comprehensive user guide documentation Files Changed: - LittleShop/package.json: NPM package management setup - LittleShop/wwwroot/js/variant-editor.js: 400-line spreadsheet editor module - LittleShop/wwwroot/lib/handsontable/: Handsontable library (Community Edition) - LittleShop/wwwroot/lib/hammerjs/: Hammer.js touch gesture library - LittleShop/Areas/Admin/Views/VariantCollections/Edit.cshtml: Spreadsheet UI integration - VARIANT_COLLECTIONS_USER_GUIDE.md: Complete user guide (18+ pages) Technical Details: - Excel-like editing experience (no more manual JSON editing) - Mobile-first responsive design - Browser compatibility: Chrome 90+, Firefox 88+, Edge 90+, Safari 14+ - Touch-optimized for mobile administration - Automatic data validation and error handling
This commit is contained in:
3
LittleShop/wwwroot/lib/hammerjs/.bowerrc
Normal file
3
LittleShop/wwwroot/lib/hammerjs/.bowerrc
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"json": "bower.json"
|
||||
}
|
||||
95
LittleShop/wwwroot/lib/hammerjs/.jscsrc
Normal file
95
LittleShop/wwwroot/lib/hammerjs/.jscsrc
Normal file
@@ -0,0 +1,95 @@
|
||||
{
|
||||
"excludeFiles": [
|
||||
"*.js",
|
||||
"tests/**/assets",
|
||||
"node_modules/**"
|
||||
],
|
||||
"requireCurlyBraces": [
|
||||
"if",
|
||||
"else",
|
||||
"for",
|
||||
"while",
|
||||
"do",
|
||||
"try",
|
||||
"catch"
|
||||
],
|
||||
"requireOperatorBeforeLineBreak": true,
|
||||
"requireCamelCaseOrUpperCaseIdentifiers": true,
|
||||
"maximumLineLength": {
|
||||
"value": 120,
|
||||
"allowComments": true,
|
||||
"allowRegex": true
|
||||
},
|
||||
"validateIndentation": 4,
|
||||
"validateQuoteMarks": "'",
|
||||
"disallowMultipleLineStrings": true,
|
||||
"disallowMixedSpacesAndTabs": true,
|
||||
"disallowTrailingWhitespace": true,
|
||||
"disallowSpaceAfterPrefixUnaryOperators": true,
|
||||
"requireSpaceAfterKeywords": [
|
||||
"if",
|
||||
"else",
|
||||
"for",
|
||||
"while",
|
||||
"do",
|
||||
"switch",
|
||||
"return",
|
||||
"try",
|
||||
"catch"
|
||||
],
|
||||
"requireSpaceBeforeBinaryOperators": [
|
||||
"=",
|
||||
"+=",
|
||||
"-=",
|
||||
"*=",
|
||||
"/=",
|
||||
"%=",
|
||||
"<<=",
|
||||
">>=",
|
||||
">>>=",
|
||||
"&=",
|
||||
"|=",
|
||||
"^=",
|
||||
"+=",
|
||||
"+",
|
||||
"-",
|
||||
"*",
|
||||
"/",
|
||||
"%",
|
||||
"<<",
|
||||
">>",
|
||||
">>>",
|
||||
"&",
|
||||
"|",
|
||||
"^",
|
||||
"&&",
|
||||
"||",
|
||||
"===",
|
||||
"==",
|
||||
">=",
|
||||
"<=",
|
||||
"<",
|
||||
">",
|
||||
"!=",
|
||||
"!=="
|
||||
],
|
||||
"requireSpaceAfterBinaryOperators": true,
|
||||
"requireSpacesInConditionalExpression": true,
|
||||
"requireSpaceBeforeBlockStatements": true,
|
||||
"requireLineFeedAtFileEnd": true,
|
||||
"requireSpacesInFunctionExpression": {
|
||||
"beforeOpeningCurlyBrace": true
|
||||
},
|
||||
"disallowSpacesInAnonymousFunctionExpression": {
|
||||
"beforeOpeningRoundBrace": true
|
||||
},
|
||||
"disallowSpacesInsideObjectBrackets": "all",
|
||||
"disallowSpacesInsideArrayBrackets": "all",
|
||||
"disallowSpacesInsideParentheses": true,
|
||||
"validateJSDoc": {
|
||||
"checkParamNames": true,
|
||||
"requireParamTypes": true
|
||||
},
|
||||
"disallowMultipleLineBreaks": true,
|
||||
"disallowNewlineBeforeBlockStatements": true
|
||||
}
|
||||
22
LittleShop/wwwroot/lib/hammerjs/.jshintrc
Normal file
22
LittleShop/wwwroot/lib/hammerjs/.jshintrc
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"browser": true,
|
||||
"curly": true,
|
||||
"eqnull": true,
|
||||
"expr": true,
|
||||
"maxerr": 100,
|
||||
"freeze": true,
|
||||
"newcap": true,
|
||||
"node": true,
|
||||
"quotmark": "single",
|
||||
"strict": true,
|
||||
"sub": true,
|
||||
"trailing": true,
|
||||
"undef": true,
|
||||
"unused": true,
|
||||
"camelcase": true,
|
||||
"indent": 4,
|
||||
"validthis": true,
|
||||
"globals": {
|
||||
"define": false
|
||||
}
|
||||
}
|
||||
21
LittleShop/wwwroot/lib/hammerjs/.npmignore
Normal file
21
LittleShop/wwwroot/lib/hammerjs/.npmignore
Normal file
@@ -0,0 +1,21 @@
|
||||
# ide
|
||||
.idea
|
||||
.iml
|
||||
|
||||
# node
|
||||
lib-cov
|
||||
*.seed
|
||||
*.log
|
||||
*.csv
|
||||
*.dat
|
||||
*.out
|
||||
*.pid
|
||||
*.gz
|
||||
|
||||
pids
|
||||
logs
|
||||
results
|
||||
tests/build.js
|
||||
|
||||
npm-debug.log
|
||||
node_modules
|
||||
11
LittleShop/wwwroot/lib/hammerjs/.travis.yml
Normal file
11
LittleShop/wwwroot/lib/hammerjs/.travis.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
|
||||
sudo: false
|
||||
|
||||
before_script:
|
||||
- npm install -g grunt-cli
|
||||
|
||||
script:
|
||||
- grunt test-travis
|
||||
54
LittleShop/wwwroot/lib/hammerjs/CHANGELOG.md
Normal file
54
LittleShop/wwwroot/lib/hammerjs/CHANGELOG.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# Changelog
|
||||
|
||||
### 2.0.6, 2015-12-23
|
||||
- Add Assign method and deprecate merge and extend ([#895](https://github.com/hammerjs/hammer.js/pull/895)[fc01eae](https://github.com/hammerjs/hammer.js/commit/fc01eaea678acc430c664eb374555fbe3d403bdd))
|
||||
- Expose Hammer on window or self if either is defined to avoid issues when AMD is present but not used. ( [356f795](https://github.com/hammerjs/hammer.js/commit/356f7955b01f3679c29d6c45931679256b45036e))
|
||||
- Add support for PointerEvent instead of MSPointerEvent if supported. ([#754](https://github.com/hammerjs/hammer.js/issues/754), [439c7a6](https://github.com/hammerjs/hammer.js/commit/439c7a6c46978ab387b4b8289399e904d1c49535))
|
||||
- Fixed moz-prefix, prefix should be Moz not moz. ([3ea47f3](https://github.com/hammerjs/hammer.js/commit/3ea47f3aebadc9d3bb6bf52bc8402cad135ef8a9))
|
||||
- Removed non-existant recognizer ([f1c2d3b](https://github.com/hammerjs/hammer.js/commit/f1c2d3bf05f530ae092ecfc2335fceeff0e9eec9))
|
||||
- Fixed config leaking between instances([189098f](https://github.com/hammerjs/hammer.js/commit/189098ff7736f6ed2fce9a3d3e1f5a3afee085ba))
|
||||
- Fixed gaps in gesture configs and update tests to match ([70c2902](https://github.com/hammerjs/hammer.js/commit/70c2902d773a750e92ce8c423f8a4165c07eab97))
|
||||
- Fixed Manager off method ([#768](https://github.com/hammerjs/hammer.js/issues/768), [da49a27](https://github.com/hammerjs/hammer.js/commit/da49a2730779ecc3b4dd147cc418a0df7c70fad9))
|
||||
- Added compatibility with requirejs optimizer namespaces ( [70075f2](https://github.com/hammerjs/hammer.js/commit/70075f2df1b855f7c6d8d3caac49b9276b88c8d6))
|
||||
- Made touchaction test zoomable ( [50264a7](https://github.com/hammerjs/hammer.js/commit/50264a70251ca88bbaf7b666401e527eee616de5))
|
||||
- Fixed preventing default when for `pan-x pan-y` case ( [95eaafa](https://github.com/hammerjs/hammer.js/commit/95eaafadad27bd1b25d20cf976811a451922f1c4))
|
||||
- Fixed incorrect touch action pan direction ( [a81da57](https://github.com/hammerjs/hammer.js/commit/a81da57a82ebf37e695e7c443e4e2715e7f32856))
|
||||
- Fixed combined pan-x pan-y to resolve to none ( [fdae07b](https://github.com/hammerjs/hammer.js/commit/fdae07bc2ba3c90aad28da6791b3d5df627bc612))
|
||||
- Fixed inverted touch-action for pan recognizer ([#728](https://github.com/hammerjs/hammer.js/issues/728), [605bd3b](https://github.com/hammerjs/hammer.js/commit/605bd3beca780be91dd43f9da8b809d155a43d1a))
|
||||
- Fixed dependency on non standard touch list ordering ([#610](https://github.com/hammerjs/hammer.js/issues/610), [#791](https://github.com/hammerjs/hammer.js/issues/791), [287720a](https://github.com/hammerjs/hammer.js/commit/287720a6e5067e7f28be8b8b3b266d22905361c4))
|
||||
- Fixed swipe to not trigger after multitouch gesture ([#640](https://github.com/hammerjs/hammer.js/issues/640), [711d8a1](https://github.com/hammerjs/hammer.js/commit/711d8a1df1aa5057ecb536454a36257e3c0d6d91))
|
||||
- Fixed swipe recognizer to use overall gesture direction and velocity ( [963fe69](https://github.com/hammerjs/hammer.js/commit/963fe697515273fee508414bc29e2656465cea55))
|
||||
- Fixed getDirection returning reversed direction ( [e40dcde](https://github.com/hammerjs/hammer.js/commit/e40dcde43bdac7a74c8ce5c05a4f62121089cd91))
|
||||
- Fixed detection of tap when multi touch gestures are present ( [c46cbba](https://github.com/hammerjs/hammer.js/commit/c46cbba1c2cbbf874b59913416858d9dae297e64))
|
||||
- Fixed incorrect event order ([#824](https://github.com/hammerjs/hammer.js/issues/824), [92f2d76](https://github.com/hammerjs/hammer.js/commit/92f2d76188480d967e738a19cd508d0b94a31329))
|
||||
- Fixed leaking options between recognizer instances ([#813](https://github.com/hammerjs/hammer.js/issues/813), [af32c9b](https://github.com/hammerjs/hammer.js/commit/af32c9bace3f04bb34bee852ff56a33cc8fc27cd))
|
||||
- Fixed detection when element has no style attribute ( [5ca6d8c](https://github.com/hammerjs/hammer.js/commit/5ca6d8cbead02c71929a8073e95ddf98e11c0e06))
|
||||
|
||||
### 2.0.4, 2014-09-28
|
||||
- Fix IE pointer issue. [#665](https://github.com/hammerjs/hammer.js/pull/665)
|
||||
- Fix multi-touch at different elements. [#668](https://github.com/hammerjs/hammer.js/pull/668)
|
||||
- Added experimental [single-user Touch input handler](src/input/singletouch.js). This to improve performance/ux when only a single user has to be supported. Plans are to release 2.1 with this as default, and a settings to enable the multi-user handler.
|
||||
|
||||
### 2.0.3, 2014-09-10
|
||||
- Manager.set improvements.
|
||||
- Fix requireFailure() call in Manager.options.recognizers.
|
||||
- Make DIRECTION_ALL for pan and swipe gestures less blocking.
|
||||
- Fix Swipe recognizer threshold option.
|
||||
- Expose the Input classes.
|
||||
- Added the option `inputClass` to set the used input handler.
|
||||
|
||||
### 2.0.2, 2014-07-26
|
||||
- Improved mouse and pointer-events input, now able to move outside the window.
|
||||
- Added the export name (`Hammer`) as an argument to the wrapper.
|
||||
- Add the option *experimental* `inputTarget` to change the element that receives the events.
|
||||
- Improved performance when only one touch being active.
|
||||
- Fixed the jumping deltaXY bug when going from single to multi-touch.
|
||||
- Improved velocity calculations.
|
||||
|
||||
### 2.0.1, 2014-07-15
|
||||
- Fix issue when no document.body is available
|
||||
- Added pressup event for the press recognizer
|
||||
- Removed alternative for Object.create
|
||||
|
||||
### 2.0.0, 2014-07-11
|
||||
- Full rewrite of the library.
|
||||
41
LittleShop/wwwroot/lib/hammerjs/CONTRIBUTING.md
Normal file
41
LittleShop/wwwroot/lib/hammerjs/CONTRIBUTING.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Contributing to Hammer.js
|
||||
|
||||
Looking to contribute something to Hammer.js? **Here's how you can help.**
|
||||
|
||||
|
||||
## Reporting issues
|
||||
|
||||
We only accept issues that are bug reports or feature requests. Bugs must be
|
||||
isolated and reproducible problems that can be fixed within the Hammer.js.
|
||||
Please read the following guidelines before opening any issue.
|
||||
|
||||
1. [**Read the documentation**](https://hammerjs.github.io)
|
||||
|
||||
2. **Search for existing issues.** We get a lot of duplicate issues, and you'd
|
||||
help us out a lot by first checking if someone else has reported the same issue.
|
||||
Moreover, the issue may have already been resolved with a fix available. Also
|
||||
take a look if your problem is explained at the Wiki.
|
||||
|
||||
3. **Create an isolated and reproducible test case.** Be sure the problem exists
|
||||
in Hammer's code with a reduced test case that should be included in each bug
|
||||
report.
|
||||
|
||||
4. **Include a live example.** Make use of jsFiddle or jsBin to share your
|
||||
isolated test cases. Also, a screen capture would work, with tools like LICEcap.
|
||||
|
||||
5. **Share as much information as possible.** Include operating system and
|
||||
version, browser and version, version of Hammer.js, customized or vanilla build,
|
||||
etc. where appropriate. Also include steps to reproduce the bug.
|
||||
|
||||
## Pull requests
|
||||
|
||||
1. Changes must be done in `/src` files, never just the compiled files. Also, don't
|
||||
commit the compiled files.
|
||||
|
||||
2. Try not to pollute your pull request with unintended changes. Keep them simple
|
||||
and small
|
||||
|
||||
3. Try to share which browsers your code has been tested in before submitting a
|
||||
pull request
|
||||
|
||||
4. Write tests for your code, these can be found in `/tests`.
|
||||
124
LittleShop/wwwroot/lib/hammerjs/Gruntfile.coffee
Normal file
124
LittleShop/wwwroot/lib/hammerjs/Gruntfile.coffee
Normal file
@@ -0,0 +1,124 @@
|
||||
module.exports = (grunt) ->
|
||||
grunt.initConfig
|
||||
pkg: grunt.file.readJSON 'package.json'
|
||||
|
||||
usebanner:
|
||||
taskName:
|
||||
options:
|
||||
position: 'top'
|
||||
banner: '
|
||||
/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n
|
||||
* <%= pkg.homepage %>\n
|
||||
*\n
|
||||
* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;\n
|
||||
* Licensed under the <%= pkg.license %> license */'
|
||||
linebreak: true
|
||||
files:
|
||||
src: ['./hammer.js','./hammer.min.js']
|
||||
|
||||
concat:
|
||||
build:
|
||||
src: [
|
||||
'src/hammer.prefix.js'
|
||||
'src/utils.js'
|
||||
'src/input.js'
|
||||
'src/input/*.js'
|
||||
'src/touchaction.js'
|
||||
'src/recognizer.js'
|
||||
'src/recognizers/*.js'
|
||||
'src/hammer.js'
|
||||
'src/manager.js'
|
||||
'src/expose.js'
|
||||
'src/hammer.suffix.js']
|
||||
dest: 'hammer.js'
|
||||
|
||||
uglify:
|
||||
min:
|
||||
options:
|
||||
report: 'gzip'
|
||||
sourceMap: 'hammer.min.map'
|
||||
files:
|
||||
'hammer.min.js': ['hammer.js']
|
||||
# special test build that exposes everything so it's testable
|
||||
test:
|
||||
options:
|
||||
wrap: "$H"
|
||||
comments: 'all'
|
||||
exportAll: true
|
||||
mangle: false
|
||||
beautify: true
|
||||
compress:
|
||||
global_defs:
|
||||
exportName: 'Hammer'
|
||||
files:
|
||||
'tests/build.js': [
|
||||
'src/utils.js'
|
||||
'src/input.js'
|
||||
'src/input/*.js'
|
||||
'src/touchaction.js'
|
||||
'src/recognizer.js'
|
||||
'src/recognizers/*.js'
|
||||
'src/hammer.js'
|
||||
'src/manager.js'
|
||||
'src/expose.js']
|
||||
|
||||
'string-replace':
|
||||
version:
|
||||
files:
|
||||
'hammer.js': 'hammer.js'
|
||||
options:
|
||||
replacements: [
|
||||
pattern: '{{PKG_VERSION}}'
|
||||
replacement: '<%= pkg.version %>'
|
||||
]
|
||||
|
||||
jshint:
|
||||
options:
|
||||
jshintrc: true
|
||||
build:
|
||||
src: ['hammer.js']
|
||||
|
||||
jscs:
|
||||
src: [
|
||||
'src/**/*.js',
|
||||
'!src/hammer.prefix.js',
|
||||
'!src/hammer.suffix.js'
|
||||
]
|
||||
options:
|
||||
config: "./.jscsrc"
|
||||
force: true
|
||||
|
||||
watch:
|
||||
scripts:
|
||||
files: ['src/**/*.js']
|
||||
tasks: ['concat','string-replace','uglify','jshint','jscs']
|
||||
options:
|
||||
interrupt: true
|
||||
|
||||
connect:
|
||||
server:
|
||||
options:
|
||||
hostname: "0.0.0.0"
|
||||
port: 8000
|
||||
|
||||
qunit:
|
||||
all: ['tests/unit/index.html']
|
||||
|
||||
|
||||
# Load tasks
|
||||
grunt.loadNpmTasks 'grunt-contrib-concat'
|
||||
grunt.loadNpmTasks 'grunt-contrib-uglify'
|
||||
grunt.loadNpmTasks 'grunt-contrib-qunit'
|
||||
grunt.loadNpmTasks 'grunt-contrib-watch'
|
||||
grunt.loadNpmTasks 'grunt-contrib-jshint'
|
||||
grunt.loadNpmTasks 'grunt-contrib-connect'
|
||||
grunt.loadNpmTasks 'grunt-string-replace'
|
||||
grunt.loadNpmTasks 'grunt-banner'
|
||||
grunt.loadNpmTasks 'grunt-jscs'
|
||||
|
||||
# Default task(s)
|
||||
grunt.registerTask 'default', ['connect', 'watch']
|
||||
grunt.registerTask 'default-test', ['connect', 'uglify:test', 'watch']
|
||||
grunt.registerTask 'build', ['concat', 'string-replace', 'uglify:min', 'usebanner', 'test']
|
||||
grunt.registerTask 'test', ['jshint', 'jscs', 'uglify:test', 'qunit']
|
||||
grunt.registerTask 'test-travis', ['build']
|
||||
21
LittleShop/wwwroot/lib/hammerjs/LICENSE.md
Normal file
21
LittleShop/wwwroot/lib/hammerjs/LICENSE.md
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (C) 2011-2014 by Jorik Tangelder (Eight Media)
|
||||
|
||||
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.
|
||||
51
LittleShop/wwwroot/lib/hammerjs/README.md
Normal file
51
LittleShop/wwwroot/lib/hammerjs/README.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Hammer.js 2.0.6
|
||||
|
||||
[](https://travis-ci.org/hammerjs/hammer.js)
|
||||
|
||||
## Support, Questions, and Collaboration
|
||||
|
||||
[](https://hammerjs.herokuapp.com/)
|
||||
|
||||
## Documentation
|
||||
|
||||
Visit [hammerjs.github.io](http://hammerjs.github.io) for detailed documentation.
|
||||
|
||||
```js
|
||||
// get a reference to an element
|
||||
var stage = document.getElementById('stage');
|
||||
|
||||
// create a manager for that element
|
||||
var mc = new Hammer.Manager(stage);
|
||||
|
||||
// create a recognizer
|
||||
var Rotate = new Hammer.Rotate();
|
||||
|
||||
// add the recognizer
|
||||
mc.add(Rotate);
|
||||
|
||||
// subscribe to events
|
||||
mc.on('rotate', function(e) {
|
||||
// do something cool
|
||||
var rotation = Math.round(e.rotation);
|
||||
stage.style.transform = 'rotate('+rotation+'deg)';
|
||||
});
|
||||
```
|
||||
|
||||
An advanced demo is available here: [http://codepen.io/runspired/full/ZQBGWd/](http://codepen.io/runspired/full/ZQBGWd/)
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
Read the [contributing guidelines](./CONTRIBUTING.md).
|
||||
|
||||
For PRs.
|
||||
|
||||
- Use [Angular Style commit messages](https://github.com/angular/angular.js/blob/v1.4.8/CONTRIBUTING.md#commit)
|
||||
- Rebase your PR branch when necessary
|
||||
- If you add a feature or fix a bug, please add or fix any necessary tests.
|
||||
- If a new feature, open a docs PR to go with.
|
||||
|
||||
## Building
|
||||
|
||||
You can get the pre-build versions from the Hammer.js website, or do this by yourself running
|
||||
`npm install -g grunt-cli && npm install && grunt build`
|
||||
16
LittleShop/wwwroot/lib/hammerjs/bower.json
Normal file
16
LittleShop/wwwroot/lib/hammerjs/bower.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "hammerjs",
|
||||
"main": "hammer.js",
|
||||
"ignore": [
|
||||
"tests",
|
||||
"src",
|
||||
".bowerrc",
|
||||
".gitignore",
|
||||
".jscsrc",
|
||||
".jshintrc",
|
||||
".travis.yml",
|
||||
"component.json",
|
||||
"Gruntfile.coffee",
|
||||
"package.json"
|
||||
]
|
||||
}
|
||||
71
LittleShop/wwwroot/lib/hammerjs/changelog.js
Normal file
71
LittleShop/wwwroot/lib/hammerjs/changelog.js
Normal file
@@ -0,0 +1,71 @@
|
||||
var changelog = require( "changelogplease" );
|
||||
var gittags = require( "git-tags" ).get( function( error, tags ) {
|
||||
if ( error ) {
|
||||
throw error
|
||||
}
|
||||
console.log( tags[ 1 ] + ".." + tags[ 0 ] );
|
||||
var exclude = [ "Merge", "Whitespace", "Fixup", "Cleanup", "Formatting", "Ignore" ];
|
||||
changelog( {
|
||||
ticketUrl: "https://github.com/hammerjs/hammer.js/issues/{id}",
|
||||
commitUrl: "https://github.com/hammerjs/hammerjs/commit/{id}",
|
||||
sort: false,
|
||||
repo: "./",
|
||||
committish: tags[ 1 ] + ".." + tags[ 0 ]
|
||||
}, function( error, log ) {
|
||||
if ( error ) {
|
||||
throw error;
|
||||
}
|
||||
log = parseLog( log );
|
||||
console.log( log );
|
||||
} );
|
||||
function parseLog( log ) {
|
||||
var lines = log.split( "\n" );
|
||||
var newLog = [];
|
||||
var log = [];
|
||||
var currentComponent;
|
||||
|
||||
|
||||
lines.shift();
|
||||
lines.forEach( function( line ) {
|
||||
var newLine = parseLine( line );
|
||||
if ( newLine ) {
|
||||
log.push( line );
|
||||
}
|
||||
} );
|
||||
var log = log.join( "\n" );
|
||||
return log.replace( /\*/g, "-" ).replace( /__TICKETREF__,/g, "" );
|
||||
}
|
||||
function parseLine( line ) {
|
||||
var parts = getParts( line );
|
||||
|
||||
if ( exclude.indexOf( parts.component ) > -1 ) {
|
||||
return false;
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
function getParts( line ) {
|
||||
var parts = line.split( ":" );
|
||||
var component = "";
|
||||
var message;
|
||||
var commits = line.match( /\{\{([A-Za-z0-9 ]){0,99}\}\}/ )
|
||||
|
||||
if ( parts.length > 1 && parts[ 0 ].length <= 20 ) {
|
||||
component = parts[ 0 ];
|
||||
parts.shift();
|
||||
message = parts.join( ":" );
|
||||
} else {
|
||||
parts = line.split( " " );
|
||||
component = parts[ 1 ];
|
||||
parts.shift();
|
||||
message = parts.join( " " );
|
||||
}
|
||||
|
||||
if ( component ) {
|
||||
component = component.replace( /\* |,/, "" );
|
||||
}
|
||||
return {
|
||||
component: component,
|
||||
message: message
|
||||
};
|
||||
}
|
||||
} );
|
||||
8
LittleShop/wwwroot/lib/hammerjs/component.json
Normal file
8
LittleShop/wwwroot/lib/hammerjs/component.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "hammerjs",
|
||||
"version": "2.0.6",
|
||||
"main": "hammer.js",
|
||||
"scripts": [
|
||||
"hammer.js"
|
||||
]
|
||||
}
|
||||
2643
LittleShop/wwwroot/lib/hammerjs/hammer.js
Normal file
2643
LittleShop/wwwroot/lib/hammerjs/hammer.js
Normal file
File diff suppressed because it is too large
Load Diff
7
LittleShop/wwwroot/lib/hammerjs/hammer.min.js
vendored
Normal file
7
LittleShop/wwwroot/lib/hammerjs/hammer.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
LittleShop/wwwroot/lib/hammerjs/hammer.min.js.map
Normal file
1
LittleShop/wwwroot/lib/hammerjs/hammer.min.js.map
Normal file
File diff suppressed because one or more lines are too long
1
LittleShop/wwwroot/lib/hammerjs/hammer.min.map
Normal file
1
LittleShop/wwwroot/lib/hammerjs/hammer.min.map
Normal file
File diff suppressed because one or more lines are too long
57
LittleShop/wwwroot/lib/hammerjs/package.json
Normal file
57
LittleShop/wwwroot/lib/hammerjs/package.json
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"name": "hammerjs",
|
||||
"title": "Hammer.JS",
|
||||
"description": "A javascript library for multi-touch gestures",
|
||||
"version": "2.0.8",
|
||||
"homepage": "http://hammerjs.github.io/",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"touch",
|
||||
"gestures"
|
||||
],
|
||||
"author": {
|
||||
"name": "Jorik Tangelder",
|
||||
"email": "j.tangelder@gmail.com"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Alexander Schmitz",
|
||||
"email": "arschmitz@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Chris Thoburn",
|
||||
"email": ""
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/hammerjs/hammer.js.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/hammerjs/hammer.js/issues"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"changelogplease": "^1.2.0",
|
||||
"git-tags": "^0.2.4",
|
||||
"grunt": "0.4.x",
|
||||
"grunt-banner": "^0.2.3",
|
||||
"grunt-contrib-concat": "0.4.x",
|
||||
"grunt-contrib-connect": "0.7.x",
|
||||
"grunt-contrib-jshint": "0.10.x",
|
||||
"grunt-contrib-qunit": "^0.5.1",
|
||||
"grunt-contrib-uglify": "0.7.x",
|
||||
"grunt-contrib-watch": "0.6.x",
|
||||
"grunt-jscs": "^0.8.0",
|
||||
"grunt-string-replace": "^0.2.7",
|
||||
"hammer-simulator": "git://github.com/hammerjs/simulator#master",
|
||||
"jquery-hammerjs": "2.0.x"
|
||||
},
|
||||
"main": "hammer.js",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "grunt test"
|
||||
}
|
||||
}
|
||||
67
LittleShop/wwwroot/lib/hammerjs/src/expose.js
Normal file
67
LittleShop/wwwroot/lib/hammerjs/src/expose.js
Normal file
@@ -0,0 +1,67 @@
|
||||
assign(Hammer, {
|
||||
INPUT_START: INPUT_START,
|
||||
INPUT_MOVE: INPUT_MOVE,
|
||||
INPUT_END: INPUT_END,
|
||||
INPUT_CANCEL: INPUT_CANCEL,
|
||||
|
||||
STATE_POSSIBLE: STATE_POSSIBLE,
|
||||
STATE_BEGAN: STATE_BEGAN,
|
||||
STATE_CHANGED: STATE_CHANGED,
|
||||
STATE_ENDED: STATE_ENDED,
|
||||
STATE_RECOGNIZED: STATE_RECOGNIZED,
|
||||
STATE_CANCELLED: STATE_CANCELLED,
|
||||
STATE_FAILED: STATE_FAILED,
|
||||
|
||||
DIRECTION_NONE: DIRECTION_NONE,
|
||||
DIRECTION_LEFT: DIRECTION_LEFT,
|
||||
DIRECTION_RIGHT: DIRECTION_RIGHT,
|
||||
DIRECTION_UP: DIRECTION_UP,
|
||||
DIRECTION_DOWN: DIRECTION_DOWN,
|
||||
DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL,
|
||||
DIRECTION_VERTICAL: DIRECTION_VERTICAL,
|
||||
DIRECTION_ALL: DIRECTION_ALL,
|
||||
|
||||
Manager: Manager,
|
||||
Input: Input,
|
||||
TouchAction: TouchAction,
|
||||
|
||||
TouchInput: TouchInput,
|
||||
MouseInput: MouseInput,
|
||||
PointerEventInput: PointerEventInput,
|
||||
TouchMouseInput: TouchMouseInput,
|
||||
SingleTouchInput: SingleTouchInput,
|
||||
|
||||
Recognizer: Recognizer,
|
||||
AttrRecognizer: AttrRecognizer,
|
||||
Tap: TapRecognizer,
|
||||
Pan: PanRecognizer,
|
||||
Swipe: SwipeRecognizer,
|
||||
Pinch: PinchRecognizer,
|
||||
Rotate: RotateRecognizer,
|
||||
Press: PressRecognizer,
|
||||
|
||||
on: addEventListeners,
|
||||
off: removeEventListeners,
|
||||
each: each,
|
||||
merge: merge,
|
||||
extend: extend,
|
||||
assign: assign,
|
||||
inherit: inherit,
|
||||
bindFn: bindFn,
|
||||
prefixed: prefixed
|
||||
});
|
||||
|
||||
// this prevents errors when Hammer is loaded in the presence of an AMD
|
||||
// style loader but by script tag, not by the loader.
|
||||
var freeGlobal = (typeof window !== 'undefined' ? window : (typeof self !== 'undefined' ? self : {})); // jshint ignore:line
|
||||
freeGlobal.Hammer = Hammer;
|
||||
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(function() {
|
||||
return Hammer;
|
||||
});
|
||||
} else if (typeof module != 'undefined' && module.exports) {
|
||||
module.exports = Hammer;
|
||||
} else {
|
||||
window[exportName] = Hammer;
|
||||
}
|
||||
128
LittleShop/wwwroot/lib/hammerjs/src/hammer.js
Normal file
128
LittleShop/wwwroot/lib/hammerjs/src/hammer.js
Normal file
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
* Simple way to create a manager with a default set of recognizers.
|
||||
* @param {HTMLElement} element
|
||||
* @param {Object} [options]
|
||||
* @constructor
|
||||
*/
|
||||
function Hammer(element, options) {
|
||||
options = options || {};
|
||||
options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset);
|
||||
return new Manager(element, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @const {string}
|
||||
*/
|
||||
Hammer.VERSION = '{{PKG_VERSION}}';
|
||||
|
||||
/**
|
||||
* default settings
|
||||
* @namespace
|
||||
*/
|
||||
Hammer.defaults = {
|
||||
/**
|
||||
* set if DOM events are being triggered.
|
||||
* But this is slower and unused by simple implementations, so disabled by default.
|
||||
* @type {Boolean}
|
||||
* @default false
|
||||
*/
|
||||
domEvents: false,
|
||||
|
||||
/**
|
||||
* The value for the touchAction property/fallback.
|
||||
* When set to `compute` it will magically set the correct value based on the added recognizers.
|
||||
* @type {String}
|
||||
* @default compute
|
||||
*/
|
||||
touchAction: TOUCH_ACTION_COMPUTE,
|
||||
|
||||
/**
|
||||
* @type {Boolean}
|
||||
* @default true
|
||||
*/
|
||||
enable: true,
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL FEATURE -- can be removed/changed
|
||||
* Change the parent input target element.
|
||||
* If Null, then it is being set the to main element.
|
||||
* @type {Null|EventTarget}
|
||||
* @default null
|
||||
*/
|
||||
inputTarget: null,
|
||||
|
||||
/**
|
||||
* force an input class
|
||||
* @type {Null|Function}
|
||||
* @default null
|
||||
*/
|
||||
inputClass: null,
|
||||
|
||||
/**
|
||||
* Default recognizer setup when calling `Hammer()`
|
||||
* When creating a new Manager these will be skipped.
|
||||
* @type {Array}
|
||||
*/
|
||||
preset: [
|
||||
// RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]
|
||||
[RotateRecognizer, {enable: false}],
|
||||
[PinchRecognizer, {enable: false}, ['rotate']],
|
||||
[SwipeRecognizer, {direction: DIRECTION_HORIZONTAL}],
|
||||
[PanRecognizer, {direction: DIRECTION_HORIZONTAL}, ['swipe']],
|
||||
[TapRecognizer],
|
||||
[TapRecognizer, {event: 'doubletap', taps: 2}, ['tap']],
|
||||
[PressRecognizer]
|
||||
],
|
||||
|
||||
/**
|
||||
* Some CSS properties can be used to improve the working of Hammer.
|
||||
* Add them to this method and they will be set when creating a new Manager.
|
||||
* @namespace
|
||||
*/
|
||||
cssProps: {
|
||||
/**
|
||||
* Disables text selection to improve the dragging gesture. Mainly for desktop browsers.
|
||||
* @type {String}
|
||||
* @default 'none'
|
||||
*/
|
||||
userSelect: 'none',
|
||||
|
||||
/**
|
||||
* Disable the Windows Phone grippers when pressing an element.
|
||||
* @type {String}
|
||||
* @default 'none'
|
||||
*/
|
||||
touchSelect: 'none',
|
||||
|
||||
/**
|
||||
* Disables the default callout shown when you touch and hold a touch target.
|
||||
* On iOS, when you touch and hold a touch target such as a link, Safari displays
|
||||
* a callout containing information about the link. This property allows you to disable that callout.
|
||||
* @type {String}
|
||||
* @default 'none'
|
||||
*/
|
||||
touchCallout: 'none',
|
||||
|
||||
/**
|
||||
* Specifies whether zooming is enabled. Used by IE10>
|
||||
* @type {String}
|
||||
* @default 'none'
|
||||
*/
|
||||
contentZooming: 'none',
|
||||
|
||||
/**
|
||||
* Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers.
|
||||
* @type {String}
|
||||
* @default 'none'
|
||||
*/
|
||||
userDrag: 'none',
|
||||
|
||||
/**
|
||||
* Overrides the highlight color shown when the user taps a link or a JavaScript
|
||||
* clickable element in iOS. This property obeys the alpha value, if specified.
|
||||
* @type {String}
|
||||
* @default 'rgba(0,0,0,0)'
|
||||
*/
|
||||
tapHighlightColor: 'rgba(0,0,0,0)'
|
||||
}
|
||||
};
|
||||
2
LittleShop/wwwroot/lib/hammerjs/src/hammer.prefix.js
Normal file
2
LittleShop/wwwroot/lib/hammerjs/src/hammer.prefix.js
Normal file
@@ -0,0 +1,2 @@
|
||||
(function(window, document, exportName, undefined) {
|
||||
'use strict';
|
||||
1
LittleShop/wwwroot/lib/hammerjs/src/hammer.suffix.js
Normal file
1
LittleShop/wwwroot/lib/hammerjs/src/hammer.suffix.js
Normal file
@@ -0,0 +1 @@
|
||||
})(window, document, 'Hammer');
|
||||
394
LittleShop/wwwroot/lib/hammerjs/src/input.js
Normal file
394
LittleShop/wwwroot/lib/hammerjs/src/input.js
Normal file
@@ -0,0 +1,394 @@
|
||||
var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;
|
||||
|
||||
var SUPPORT_TOUCH = ('ontouchstart' in window);
|
||||
var SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined;
|
||||
var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent);
|
||||
|
||||
var INPUT_TYPE_TOUCH = 'touch';
|
||||
var INPUT_TYPE_PEN = 'pen';
|
||||
var INPUT_TYPE_MOUSE = 'mouse';
|
||||
var INPUT_TYPE_KINECT = 'kinect';
|
||||
|
||||
var COMPUTE_INTERVAL = 25;
|
||||
|
||||
var INPUT_START = 1;
|
||||
var INPUT_MOVE = 2;
|
||||
var INPUT_END = 4;
|
||||
var INPUT_CANCEL = 8;
|
||||
|
||||
var DIRECTION_NONE = 1;
|
||||
var DIRECTION_LEFT = 2;
|
||||
var DIRECTION_RIGHT = 4;
|
||||
var DIRECTION_UP = 8;
|
||||
var DIRECTION_DOWN = 16;
|
||||
|
||||
var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT;
|
||||
var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN;
|
||||
var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;
|
||||
|
||||
var PROPS_XY = ['x', 'y'];
|
||||
var PROPS_CLIENT_XY = ['clientX', 'clientY'];
|
||||
|
||||
/**
|
||||
* create new input type manager
|
||||
* @param {Manager} manager
|
||||
* @param {Function} callback
|
||||
* @returns {Input}
|
||||
* @constructor
|
||||
*/
|
||||
function Input(manager, callback) {
|
||||
var self = this;
|
||||
this.manager = manager;
|
||||
this.callback = callback;
|
||||
this.element = manager.element;
|
||||
this.target = manager.options.inputTarget;
|
||||
|
||||
// smaller wrapper around the handler, for the scope and the enabled state of the manager,
|
||||
// so when disabled the input events are completely bypassed.
|
||||
this.domHandler = function(ev) {
|
||||
if (boolOrFn(manager.options.enable, [manager])) {
|
||||
self.handler(ev);
|
||||
}
|
||||
};
|
||||
|
||||
this.init();
|
||||
|
||||
}
|
||||
|
||||
Input.prototype = {
|
||||
/**
|
||||
* should handle the inputEvent data and trigger the callback
|
||||
* @virtual
|
||||
*/
|
||||
handler: function() { },
|
||||
|
||||
/**
|
||||
* bind the events
|
||||
*/
|
||||
init: function() {
|
||||
this.evEl && addEventListeners(this.element, this.evEl, this.domHandler);
|
||||
this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler);
|
||||
this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
|
||||
},
|
||||
|
||||
/**
|
||||
* unbind the events
|
||||
*/
|
||||
destroy: function() {
|
||||
this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler);
|
||||
this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler);
|
||||
this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* create new input type manager
|
||||
* called by the Manager constructor
|
||||
* @param {Hammer} manager
|
||||
* @returns {Input}
|
||||
*/
|
||||
function createInputInstance(manager) {
|
||||
var Type;
|
||||
var inputClass = manager.options.inputClass;
|
||||
|
||||
if (inputClass) {
|
||||
Type = inputClass;
|
||||
} else if (SUPPORT_POINTER_EVENTS) {
|
||||
Type = PointerEventInput;
|
||||
} else if (SUPPORT_ONLY_TOUCH) {
|
||||
Type = TouchInput;
|
||||
} else if (!SUPPORT_TOUCH) {
|
||||
Type = MouseInput;
|
||||
} else {
|
||||
Type = TouchMouseInput;
|
||||
}
|
||||
return new (Type)(manager, inputHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* handle input events
|
||||
* @param {Manager} manager
|
||||
* @param {String} eventType
|
||||
* @param {Object} input
|
||||
*/
|
||||
function inputHandler(manager, eventType, input) {
|
||||
var pointersLen = input.pointers.length;
|
||||
var changedPointersLen = input.changedPointers.length;
|
||||
var isFirst = (eventType & INPUT_START && (pointersLen - changedPointersLen === 0));
|
||||
var isFinal = (eventType & (INPUT_END | INPUT_CANCEL) && (pointersLen - changedPointersLen === 0));
|
||||
|
||||
input.isFirst = !!isFirst;
|
||||
input.isFinal = !!isFinal;
|
||||
|
||||
if (isFirst) {
|
||||
manager.session = {};
|
||||
}
|
||||
|
||||
// source event is the normalized value of the domEvents
|
||||
// like 'touchstart, mouseup, pointerdown'
|
||||
input.eventType = eventType;
|
||||
|
||||
// compute scale, rotation etc
|
||||
computeInputData(manager, input);
|
||||
|
||||
// emit secret event
|
||||
manager.emit('hammer.input', input);
|
||||
|
||||
manager.recognize(input);
|
||||
manager.session.prevInput = input;
|
||||
}
|
||||
|
||||
/**
|
||||
* extend the data with some usable properties like scale, rotate, velocity etc
|
||||
* @param {Object} manager
|
||||
* @param {Object} input
|
||||
*/
|
||||
function computeInputData(manager, input) {
|
||||
var session = manager.session;
|
||||
var pointers = input.pointers;
|
||||
var pointersLength = pointers.length;
|
||||
|
||||
// store the first input to calculate the distance and direction
|
||||
if (!session.firstInput) {
|
||||
session.firstInput = simpleCloneInputData(input);
|
||||
}
|
||||
|
||||
// to compute scale and rotation we need to store the multiple touches
|
||||
if (pointersLength > 1 && !session.firstMultiple) {
|
||||
session.firstMultiple = simpleCloneInputData(input);
|
||||
} else if (pointersLength === 1) {
|
||||
session.firstMultiple = false;
|
||||
}
|
||||
|
||||
var firstInput = session.firstInput;
|
||||
var firstMultiple = session.firstMultiple;
|
||||
var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center;
|
||||
|
||||
var center = input.center = getCenter(pointers);
|
||||
input.timeStamp = now();
|
||||
input.deltaTime = input.timeStamp - firstInput.timeStamp;
|
||||
|
||||
input.angle = getAngle(offsetCenter, center);
|
||||
input.distance = getDistance(offsetCenter, center);
|
||||
|
||||
computeDeltaXY(session, input);
|
||||
input.offsetDirection = getDirection(input.deltaX, input.deltaY);
|
||||
|
||||
var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY);
|
||||
input.overallVelocityX = overallVelocity.x;
|
||||
input.overallVelocityY = overallVelocity.y;
|
||||
input.overallVelocity = (abs(overallVelocity.x) > abs(overallVelocity.y)) ? overallVelocity.x : overallVelocity.y;
|
||||
|
||||
input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1;
|
||||
input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0;
|
||||
|
||||
input.maxPointers = !session.prevInput ? input.pointers.length : ((input.pointers.length >
|
||||
session.prevInput.maxPointers) ? input.pointers.length : session.prevInput.maxPointers);
|
||||
|
||||
computeIntervalInputData(session, input);
|
||||
|
||||
// find the correct target
|
||||
var target = manager.element;
|
||||
if (hasParent(input.srcEvent.target, target)) {
|
||||
target = input.srcEvent.target;
|
||||
}
|
||||
input.target = target;
|
||||
}
|
||||
|
||||
function computeDeltaXY(session, input) {
|
||||
var center = input.center;
|
||||
var offset = session.offsetDelta || {};
|
||||
var prevDelta = session.prevDelta || {};
|
||||
var prevInput = session.prevInput || {};
|
||||
|
||||
if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) {
|
||||
prevDelta = session.prevDelta = {
|
||||
x: prevInput.deltaX || 0,
|
||||
y: prevInput.deltaY || 0
|
||||
};
|
||||
|
||||
offset = session.offsetDelta = {
|
||||
x: center.x,
|
||||
y: center.y
|
||||
};
|
||||
}
|
||||
|
||||
input.deltaX = prevDelta.x + (center.x - offset.x);
|
||||
input.deltaY = prevDelta.y + (center.y - offset.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* velocity is calculated every x ms
|
||||
* @param {Object} session
|
||||
* @param {Object} input
|
||||
*/
|
||||
function computeIntervalInputData(session, input) {
|
||||
var last = session.lastInterval || input,
|
||||
deltaTime = input.timeStamp - last.timeStamp,
|
||||
velocity, velocityX, velocityY, direction;
|
||||
|
||||
if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) {
|
||||
var deltaX = input.deltaX - last.deltaX;
|
||||
var deltaY = input.deltaY - last.deltaY;
|
||||
|
||||
var v = getVelocity(deltaTime, deltaX, deltaY);
|
||||
velocityX = v.x;
|
||||
velocityY = v.y;
|
||||
velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y;
|
||||
direction = getDirection(deltaX, deltaY);
|
||||
|
||||
session.lastInterval = input;
|
||||
} else {
|
||||
// use latest velocity info if it doesn't overtake a minimum period
|
||||
velocity = last.velocity;
|
||||
velocityX = last.velocityX;
|
||||
velocityY = last.velocityY;
|
||||
direction = last.direction;
|
||||
}
|
||||
|
||||
input.velocity = velocity;
|
||||
input.velocityX = velocityX;
|
||||
input.velocityY = velocityY;
|
||||
input.direction = direction;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a simple clone from the input used for storage of firstInput and firstMultiple
|
||||
* @param {Object} input
|
||||
* @returns {Object} clonedInputData
|
||||
*/
|
||||
function simpleCloneInputData(input) {
|
||||
// make a simple copy of the pointers because we will get a reference if we don't
|
||||
// we only need clientXY for the calculations
|
||||
var pointers = [];
|
||||
var i = 0;
|
||||
while (i < input.pointers.length) {
|
||||
pointers[i] = {
|
||||
clientX: round(input.pointers[i].clientX),
|
||||
clientY: round(input.pointers[i].clientY)
|
||||
};
|
||||
i++;
|
||||
}
|
||||
|
||||
return {
|
||||
timeStamp: now(),
|
||||
pointers: pointers,
|
||||
center: getCenter(pointers),
|
||||
deltaX: input.deltaX,
|
||||
deltaY: input.deltaY
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* get the center of all the pointers
|
||||
* @param {Array} pointers
|
||||
* @return {Object} center contains `x` and `y` properties
|
||||
*/
|
||||
function getCenter(pointers) {
|
||||
var pointersLength = pointers.length;
|
||||
|
||||
// no need to loop when only one touch
|
||||
if (pointersLength === 1) {
|
||||
return {
|
||||
x: round(pointers[0].clientX),
|
||||
y: round(pointers[0].clientY)
|
||||
};
|
||||
}
|
||||
|
||||
var x = 0, y = 0, i = 0;
|
||||
while (i < pointersLength) {
|
||||
x += pointers[i].clientX;
|
||||
y += pointers[i].clientY;
|
||||
i++;
|
||||
}
|
||||
|
||||
return {
|
||||
x: round(x / pointersLength),
|
||||
y: round(y / pointersLength)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate the velocity between two points. unit is in px per ms.
|
||||
* @param {Number} deltaTime
|
||||
* @param {Number} x
|
||||
* @param {Number} y
|
||||
* @return {Object} velocity `x` and `y`
|
||||
*/
|
||||
function getVelocity(deltaTime, x, y) {
|
||||
return {
|
||||
x: x / deltaTime || 0,
|
||||
y: y / deltaTime || 0
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* get the direction between two points
|
||||
* @param {Number} x
|
||||
* @param {Number} y
|
||||
* @return {Number} direction
|
||||
*/
|
||||
function getDirection(x, y) {
|
||||
if (x === y) {
|
||||
return DIRECTION_NONE;
|
||||
}
|
||||
|
||||
if (abs(x) >= abs(y)) {
|
||||
return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;
|
||||
}
|
||||
return y < 0 ? DIRECTION_UP : DIRECTION_DOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate the absolute distance between two points
|
||||
* @param {Object} p1 {x, y}
|
||||
* @param {Object} p2 {x, y}
|
||||
* @param {Array} [props] containing x and y keys
|
||||
* @return {Number} distance
|
||||
*/
|
||||
function getDistance(p1, p2, props) {
|
||||
if (!props) {
|
||||
props = PROPS_XY;
|
||||
}
|
||||
var x = p2[props[0]] - p1[props[0]],
|
||||
y = p2[props[1]] - p1[props[1]];
|
||||
|
||||
return Math.sqrt((x * x) + (y * y));
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate the angle between two coordinates
|
||||
* @param {Object} p1
|
||||
* @param {Object} p2
|
||||
* @param {Array} [props] containing x and y keys
|
||||
* @return {Number} angle
|
||||
*/
|
||||
function getAngle(p1, p2, props) {
|
||||
if (!props) {
|
||||
props = PROPS_XY;
|
||||
}
|
||||
var x = p2[props[0]] - p1[props[0]],
|
||||
y = p2[props[1]] - p1[props[1]];
|
||||
return Math.atan2(y, x) * 180 / Math.PI;
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate the rotation degrees between two pointersets
|
||||
* @param {Array} start array of pointers
|
||||
* @param {Array} end array of pointers
|
||||
* @return {Number} rotation
|
||||
*/
|
||||
function getRotation(start, end) {
|
||||
return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY);
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate the scale factor between two pointersets
|
||||
* no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out
|
||||
* @param {Array} start array of pointers
|
||||
* @param {Array} end array of pointers
|
||||
* @return {Number} scale
|
||||
*/
|
||||
function getScale(start, end) {
|
||||
return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY);
|
||||
}
|
||||
57
LittleShop/wwwroot/lib/hammerjs/src/input/mouse.js
Normal file
57
LittleShop/wwwroot/lib/hammerjs/src/input/mouse.js
Normal file
@@ -0,0 +1,57 @@
|
||||
var MOUSE_INPUT_MAP = {
|
||||
mousedown: INPUT_START,
|
||||
mousemove: INPUT_MOVE,
|
||||
mouseup: INPUT_END
|
||||
};
|
||||
|
||||
var MOUSE_ELEMENT_EVENTS = 'mousedown';
|
||||
var MOUSE_WINDOW_EVENTS = 'mousemove mouseup';
|
||||
|
||||
/**
|
||||
* Mouse events input
|
||||
* @constructor
|
||||
* @extends Input
|
||||
*/
|
||||
function MouseInput() {
|
||||
this.evEl = MOUSE_ELEMENT_EVENTS;
|
||||
this.evWin = MOUSE_WINDOW_EVENTS;
|
||||
|
||||
this.pressed = false; // mousedown state
|
||||
|
||||
Input.apply(this, arguments);
|
||||
}
|
||||
|
||||
inherit(MouseInput, Input, {
|
||||
/**
|
||||
* handle mouse events
|
||||
* @param {Object} ev
|
||||
*/
|
||||
handler: function MEhandler(ev) {
|
||||
var eventType = MOUSE_INPUT_MAP[ev.type];
|
||||
|
||||
// on start we want to have the left mouse button down
|
||||
if (eventType & INPUT_START && ev.button === 0) {
|
||||
this.pressed = true;
|
||||
}
|
||||
|
||||
if (eventType & INPUT_MOVE && ev.which !== 1) {
|
||||
eventType = INPUT_END;
|
||||
}
|
||||
|
||||
// mouse must be down
|
||||
if (!this.pressed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (eventType & INPUT_END) {
|
||||
this.pressed = false;
|
||||
}
|
||||
|
||||
this.callback(this.manager, eventType, {
|
||||
pointers: [ev],
|
||||
changedPointers: [ev],
|
||||
pointerType: INPUT_TYPE_MOUSE,
|
||||
srcEvent: ev
|
||||
});
|
||||
}
|
||||
});
|
||||
88
LittleShop/wwwroot/lib/hammerjs/src/input/pointerevent.js
Normal file
88
LittleShop/wwwroot/lib/hammerjs/src/input/pointerevent.js
Normal file
@@ -0,0 +1,88 @@
|
||||
var POINTER_INPUT_MAP = {
|
||||
pointerdown: INPUT_START,
|
||||
pointermove: INPUT_MOVE,
|
||||
pointerup: INPUT_END,
|
||||
pointercancel: INPUT_CANCEL,
|
||||
pointerout: INPUT_CANCEL
|
||||
};
|
||||
|
||||
// in IE10 the pointer types is defined as an enum
|
||||
var IE10_POINTER_TYPE_ENUM = {
|
||||
2: INPUT_TYPE_TOUCH,
|
||||
3: INPUT_TYPE_PEN,
|
||||
4: INPUT_TYPE_MOUSE,
|
||||
5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816
|
||||
};
|
||||
|
||||
var POINTER_ELEMENT_EVENTS = 'pointerdown';
|
||||
var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel';
|
||||
|
||||
// IE10 has prefixed support, and case-sensitive
|
||||
if (window.MSPointerEvent && !window.PointerEvent) {
|
||||
POINTER_ELEMENT_EVENTS = 'MSPointerDown';
|
||||
POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel';
|
||||
}
|
||||
|
||||
/**
|
||||
* Pointer events input
|
||||
* @constructor
|
||||
* @extends Input
|
||||
*/
|
||||
function PointerEventInput() {
|
||||
this.evEl = POINTER_ELEMENT_EVENTS;
|
||||
this.evWin = POINTER_WINDOW_EVENTS;
|
||||
|
||||
Input.apply(this, arguments);
|
||||
|
||||
this.store = (this.manager.session.pointerEvents = []);
|
||||
}
|
||||
|
||||
inherit(PointerEventInput, Input, {
|
||||
/**
|
||||
* handle mouse events
|
||||
* @param {Object} ev
|
||||
*/
|
||||
handler: function PEhandler(ev) {
|
||||
var store = this.store;
|
||||
var removePointer = false;
|
||||
|
||||
var eventTypeNormalized = ev.type.toLowerCase().replace('ms', '');
|
||||
var eventType = POINTER_INPUT_MAP[eventTypeNormalized];
|
||||
var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType;
|
||||
|
||||
var isTouch = (pointerType == INPUT_TYPE_TOUCH);
|
||||
|
||||
// get index of the event in the store
|
||||
var storeIndex = inArray(store, ev.pointerId, 'pointerId');
|
||||
|
||||
// start and mouse must be down
|
||||
if (eventType & INPUT_START && (ev.button === 0 || isTouch)) {
|
||||
if (storeIndex < 0) {
|
||||
store.push(ev);
|
||||
storeIndex = store.length - 1;
|
||||
}
|
||||
} else if (eventType & (INPUT_END | INPUT_CANCEL)) {
|
||||
removePointer = true;
|
||||
}
|
||||
|
||||
// it not found, so the pointer hasn't been down (so it's probably a hover)
|
||||
if (storeIndex < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// update the event in the store
|
||||
store[storeIndex] = ev;
|
||||
|
||||
this.callback(this.manager, eventType, {
|
||||
pointers: store,
|
||||
changedPointers: [ev],
|
||||
pointerType: pointerType,
|
||||
srcEvent: ev
|
||||
});
|
||||
|
||||
if (removePointer) {
|
||||
// remove from the store
|
||||
store.splice(storeIndex, 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
68
LittleShop/wwwroot/lib/hammerjs/src/input/singletouch.js
Normal file
68
LittleShop/wwwroot/lib/hammerjs/src/input/singletouch.js
Normal file
@@ -0,0 +1,68 @@
|
||||
var SINGLE_TOUCH_INPUT_MAP = {
|
||||
touchstart: INPUT_START,
|
||||
touchmove: INPUT_MOVE,
|
||||
touchend: INPUT_END,
|
||||
touchcancel: INPUT_CANCEL
|
||||
};
|
||||
|
||||
var SINGLE_TOUCH_TARGET_EVENTS = 'touchstart';
|
||||
var SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel';
|
||||
|
||||
/**
|
||||
* Touch events input
|
||||
* @constructor
|
||||
* @extends Input
|
||||
*/
|
||||
function SingleTouchInput() {
|
||||
this.evTarget = SINGLE_TOUCH_TARGET_EVENTS;
|
||||
this.evWin = SINGLE_TOUCH_WINDOW_EVENTS;
|
||||
this.started = false;
|
||||
|
||||
Input.apply(this, arguments);
|
||||
}
|
||||
|
||||
inherit(SingleTouchInput, Input, {
|
||||
handler: function TEhandler(ev) {
|
||||
var type = SINGLE_TOUCH_INPUT_MAP[ev.type];
|
||||
|
||||
// should we handle the touch events?
|
||||
if (type === INPUT_START) {
|
||||
this.started = true;
|
||||
}
|
||||
|
||||
if (!this.started) {
|
||||
return;
|
||||
}
|
||||
|
||||
var touches = normalizeSingleTouches.call(this, ev, type);
|
||||
|
||||
// when done, reset the started state
|
||||
if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) {
|
||||
this.started = false;
|
||||
}
|
||||
|
||||
this.callback(this.manager, type, {
|
||||
pointers: touches[0],
|
||||
changedPointers: touches[1],
|
||||
pointerType: INPUT_TYPE_TOUCH,
|
||||
srcEvent: ev
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @this {TouchInput}
|
||||
* @param {Object} ev
|
||||
* @param {Number} type flag
|
||||
* @returns {undefined|Array} [all, changed]
|
||||
*/
|
||||
function normalizeSingleTouches(ev, type) {
|
||||
var all = toArray(ev.touches);
|
||||
var changed = toArray(ev.changedTouches);
|
||||
|
||||
if (type & (INPUT_END | INPUT_CANCEL)) {
|
||||
all = uniqueArray(all.concat(changed), 'identifier', true);
|
||||
}
|
||||
|
||||
return [all, changed];
|
||||
}
|
||||
98
LittleShop/wwwroot/lib/hammerjs/src/input/touch.js
Normal file
98
LittleShop/wwwroot/lib/hammerjs/src/input/touch.js
Normal file
@@ -0,0 +1,98 @@
|
||||
var TOUCH_INPUT_MAP = {
|
||||
touchstart: INPUT_START,
|
||||
touchmove: INPUT_MOVE,
|
||||
touchend: INPUT_END,
|
||||
touchcancel: INPUT_CANCEL
|
||||
};
|
||||
|
||||
var TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel';
|
||||
|
||||
/**
|
||||
* Multi-user touch events input
|
||||
* @constructor
|
||||
* @extends Input
|
||||
*/
|
||||
function TouchInput() {
|
||||
this.evTarget = TOUCH_TARGET_EVENTS;
|
||||
this.targetIds = {};
|
||||
|
||||
Input.apply(this, arguments);
|
||||
}
|
||||
|
||||
inherit(TouchInput, Input, {
|
||||
handler: function MTEhandler(ev) {
|
||||
var type = TOUCH_INPUT_MAP[ev.type];
|
||||
var touches = getTouches.call(this, ev, type);
|
||||
if (!touches) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.callback(this.manager, type, {
|
||||
pointers: touches[0],
|
||||
changedPointers: touches[1],
|
||||
pointerType: INPUT_TYPE_TOUCH,
|
||||
srcEvent: ev
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @this {TouchInput}
|
||||
* @param {Object} ev
|
||||
* @param {Number} type flag
|
||||
* @returns {undefined|Array} [all, changed]
|
||||
*/
|
||||
function getTouches(ev, type) {
|
||||
var allTouches = toArray(ev.touches);
|
||||
var targetIds = this.targetIds;
|
||||
|
||||
// when there is only one touch, the process can be simplified
|
||||
if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) {
|
||||
targetIds[allTouches[0].identifier] = true;
|
||||
return [allTouches, allTouches];
|
||||
}
|
||||
|
||||
var i,
|
||||
targetTouches,
|
||||
changedTouches = toArray(ev.changedTouches),
|
||||
changedTargetTouches = [],
|
||||
target = this.target;
|
||||
|
||||
// get target touches from touches
|
||||
targetTouches = allTouches.filter(function(touch) {
|
||||
return hasParent(touch.target, target);
|
||||
});
|
||||
|
||||
// collect touches
|
||||
if (type === INPUT_START) {
|
||||
i = 0;
|
||||
while (i < targetTouches.length) {
|
||||
targetIds[targetTouches[i].identifier] = true;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// filter changed touches to only contain touches that exist in the collected target ids
|
||||
i = 0;
|
||||
while (i < changedTouches.length) {
|
||||
if (targetIds[changedTouches[i].identifier]) {
|
||||
changedTargetTouches.push(changedTouches[i]);
|
||||
}
|
||||
|
||||
// cleanup removed touches
|
||||
if (type & (INPUT_END | INPUT_CANCEL)) {
|
||||
delete targetIds[changedTouches[i].identifier];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (!changedTargetTouches.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
return [
|
||||
// merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel'
|
||||
uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true),
|
||||
changedTargetTouches
|
||||
];
|
||||
}
|
||||
95
LittleShop/wwwroot/lib/hammerjs/src/input/touchmouse.js
Normal file
95
LittleShop/wwwroot/lib/hammerjs/src/input/touchmouse.js
Normal file
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* Combined touch and mouse input
|
||||
*
|
||||
* Touch has a higher priority then mouse, and while touching no mouse events are allowed.
|
||||
* This because touch devices also emit mouse events while doing a touch.
|
||||
*
|
||||
* @constructor
|
||||
* @extends Input
|
||||
*/
|
||||
|
||||
var DEDUP_TIMEOUT = 2500;
|
||||
var DEDUP_DISTANCE = 25;
|
||||
|
||||
function TouchMouseInput() {
|
||||
Input.apply(this, arguments);
|
||||
|
||||
var handler = bindFn(this.handler, this);
|
||||
this.touch = new TouchInput(this.manager, handler);
|
||||
this.mouse = new MouseInput(this.manager, handler);
|
||||
|
||||
this.primaryTouch = null;
|
||||
this.lastTouches = [];
|
||||
}
|
||||
|
||||
inherit(TouchMouseInput, Input, {
|
||||
/**
|
||||
* handle mouse and touch events
|
||||
* @param {Hammer} manager
|
||||
* @param {String} inputEvent
|
||||
* @param {Object} inputData
|
||||
*/
|
||||
handler: function TMEhandler(manager, inputEvent, inputData) {
|
||||
var isTouch = (inputData.pointerType == INPUT_TYPE_TOUCH),
|
||||
isMouse = (inputData.pointerType == INPUT_TYPE_MOUSE);
|
||||
|
||||
if (isMouse && inputData.sourceCapabilities && inputData.sourceCapabilities.firesTouchEvents) {
|
||||
return;
|
||||
}
|
||||
|
||||
// when we're in a touch event, record touches to de-dupe synthetic mouse event
|
||||
if (isTouch) {
|
||||
recordTouches.call(this, inputEvent, inputData);
|
||||
} else if (isMouse && isSyntheticEvent.call(this, inputData)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.callback(manager, inputEvent, inputData);
|
||||
},
|
||||
|
||||
/**
|
||||
* remove the event listeners
|
||||
*/
|
||||
destroy: function destroy() {
|
||||
this.touch.destroy();
|
||||
this.mouse.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
function recordTouches(eventType, eventData) {
|
||||
if (eventType & INPUT_START) {
|
||||
this.primaryTouch = eventData.changedPointers[0].identifier;
|
||||
setLastTouch.call(this, eventData);
|
||||
} else if (eventType & (INPUT_END | INPUT_CANCEL)) {
|
||||
setLastTouch.call(this, eventData);
|
||||
}
|
||||
}
|
||||
|
||||
function setLastTouch(eventData) {
|
||||
var touch = eventData.changedPointers[0];
|
||||
|
||||
if (touch.identifier === this.primaryTouch) {
|
||||
var lastTouch = {x: touch.clientX, y: touch.clientY};
|
||||
this.lastTouches.push(lastTouch);
|
||||
var lts = this.lastTouches;
|
||||
var removeLastTouch = function() {
|
||||
var i = lts.indexOf(lastTouch);
|
||||
if (i > -1) {
|
||||
lts.splice(i, 1);
|
||||
}
|
||||
};
|
||||
setTimeout(removeLastTouch, DEDUP_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
function isSyntheticEvent(eventData) {
|
||||
var x = eventData.srcEvent.clientX, y = eventData.srcEvent.clientY;
|
||||
for (var i = 0; i < this.lastTouches.length; i++) {
|
||||
var t = this.lastTouches[i];
|
||||
var dx = Math.abs(x - t.x), dy = Math.abs(y - t.y);
|
||||
if (dx <= DEDUP_DISTANCE && dy <= DEDUP_DISTANCE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
312
LittleShop/wwwroot/lib/hammerjs/src/manager.js
Normal file
312
LittleShop/wwwroot/lib/hammerjs/src/manager.js
Normal file
@@ -0,0 +1,312 @@
|
||||
var STOP = 1;
|
||||
var FORCED_STOP = 2;
|
||||
|
||||
/**
|
||||
* Manager
|
||||
* @param {HTMLElement} element
|
||||
* @param {Object} [options]
|
||||
* @constructor
|
||||
*/
|
||||
function Manager(element, options) {
|
||||
this.options = assign({}, Hammer.defaults, options || {});
|
||||
|
||||
this.options.inputTarget = this.options.inputTarget || element;
|
||||
|
||||
this.handlers = {};
|
||||
this.session = {};
|
||||
this.recognizers = [];
|
||||
this.oldCssProps = {};
|
||||
|
||||
this.element = element;
|
||||
this.input = createInputInstance(this);
|
||||
this.touchAction = new TouchAction(this, this.options.touchAction);
|
||||
|
||||
toggleCssProps(this, true);
|
||||
|
||||
each(this.options.recognizers, function(item) {
|
||||
var recognizer = this.add(new (item[0])(item[1]));
|
||||
item[2] && recognizer.recognizeWith(item[2]);
|
||||
item[3] && recognizer.requireFailure(item[3]);
|
||||
}, this);
|
||||
}
|
||||
|
||||
Manager.prototype = {
|
||||
/**
|
||||
* set options
|
||||
* @param {Object} options
|
||||
* @returns {Manager}
|
||||
*/
|
||||
set: function(options) {
|
||||
assign(this.options, options);
|
||||
|
||||
// Options that need a little more setup
|
||||
if (options.touchAction) {
|
||||
this.touchAction.update();
|
||||
}
|
||||
if (options.inputTarget) {
|
||||
// Clean up existing event listeners and reinitialize
|
||||
this.input.destroy();
|
||||
this.input.target = options.inputTarget;
|
||||
this.input.init();
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* stop recognizing for this session.
|
||||
* This session will be discarded, when a new [input]start event is fired.
|
||||
* When forced, the recognizer cycle is stopped immediately.
|
||||
* @param {Boolean} [force]
|
||||
*/
|
||||
stop: function(force) {
|
||||
this.session.stopped = force ? FORCED_STOP : STOP;
|
||||
},
|
||||
|
||||
/**
|
||||
* run the recognizers!
|
||||
* called by the inputHandler function on every movement of the pointers (touches)
|
||||
* it walks through all the recognizers and tries to detect the gesture that is being made
|
||||
* @param {Object} inputData
|
||||
*/
|
||||
recognize: function(inputData) {
|
||||
var session = this.session;
|
||||
if (session.stopped) {
|
||||
return;
|
||||
}
|
||||
|
||||
// run the touch-action polyfill
|
||||
this.touchAction.preventDefaults(inputData);
|
||||
|
||||
var recognizer;
|
||||
var recognizers = this.recognizers;
|
||||
|
||||
// this holds the recognizer that is being recognized.
|
||||
// so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED
|
||||
// if no recognizer is detecting a thing, it is set to `null`
|
||||
var curRecognizer = session.curRecognizer;
|
||||
|
||||
// reset when the last recognizer is recognized
|
||||
// or when we're in a new session
|
||||
if (!curRecognizer || (curRecognizer && curRecognizer.state & STATE_RECOGNIZED)) {
|
||||
curRecognizer = session.curRecognizer = null;
|
||||
}
|
||||
|
||||
var i = 0;
|
||||
while (i < recognizers.length) {
|
||||
recognizer = recognizers[i];
|
||||
|
||||
// find out if we are allowed try to recognize the input for this one.
|
||||
// 1. allow if the session is NOT forced stopped (see the .stop() method)
|
||||
// 2. allow if we still haven't recognized a gesture in this session, or the this recognizer is the one
|
||||
// that is being recognized.
|
||||
// 3. allow if the recognizer is allowed to run simultaneous with the current recognized recognizer.
|
||||
// this can be setup with the `recognizeWith()` method on the recognizer.
|
||||
if (session.stopped !== FORCED_STOP && ( // 1
|
||||
!curRecognizer || recognizer == curRecognizer || // 2
|
||||
recognizer.canRecognizeWith(curRecognizer))) { // 3
|
||||
recognizer.recognize(inputData);
|
||||
} else {
|
||||
recognizer.reset();
|
||||
}
|
||||
|
||||
// if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the
|
||||
// current active recognizer. but only if we don't already have an active recognizer
|
||||
if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {
|
||||
curRecognizer = session.curRecognizer = recognizer;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* get a recognizer by its event name.
|
||||
* @param {Recognizer|String} recognizer
|
||||
* @returns {Recognizer|Null}
|
||||
*/
|
||||
get: function(recognizer) {
|
||||
if (recognizer instanceof Recognizer) {
|
||||
return recognizer;
|
||||
}
|
||||
|
||||
var recognizers = this.recognizers;
|
||||
for (var i = 0; i < recognizers.length; i++) {
|
||||
if (recognizers[i].options.event == recognizer) {
|
||||
return recognizers[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* add a recognizer to the manager
|
||||
* existing recognizers with the same event name will be removed
|
||||
* @param {Recognizer} recognizer
|
||||
* @returns {Recognizer|Manager}
|
||||
*/
|
||||
add: function(recognizer) {
|
||||
if (invokeArrayArg(recognizer, 'add', this)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
// remove existing
|
||||
var existing = this.get(recognizer.options.event);
|
||||
if (existing) {
|
||||
this.remove(existing);
|
||||
}
|
||||
|
||||
this.recognizers.push(recognizer);
|
||||
recognizer.manager = this;
|
||||
|
||||
this.touchAction.update();
|
||||
return recognizer;
|
||||
},
|
||||
|
||||
/**
|
||||
* remove a recognizer by name or instance
|
||||
* @param {Recognizer|String} recognizer
|
||||
* @returns {Manager}
|
||||
*/
|
||||
remove: function(recognizer) {
|
||||
if (invokeArrayArg(recognizer, 'remove', this)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
recognizer = this.get(recognizer);
|
||||
|
||||
// let's make sure this recognizer exists
|
||||
if (recognizer) {
|
||||
var recognizers = this.recognizers;
|
||||
var index = inArray(recognizers, recognizer);
|
||||
|
||||
if (index !== -1) {
|
||||
recognizers.splice(index, 1);
|
||||
this.touchAction.update();
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* bind event
|
||||
* @param {String} events
|
||||
* @param {Function} handler
|
||||
* @returns {EventEmitter} this
|
||||
*/
|
||||
on: function(events, handler) {
|
||||
if (events === undefined) {
|
||||
return;
|
||||
}
|
||||
if (handler === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
var handlers = this.handlers;
|
||||
each(splitStr(events), function(event) {
|
||||
handlers[event] = handlers[event] || [];
|
||||
handlers[event].push(handler);
|
||||
});
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* unbind event, leave emit blank to remove all handlers
|
||||
* @param {String} events
|
||||
* @param {Function} [handler]
|
||||
* @returns {EventEmitter} this
|
||||
*/
|
||||
off: function(events, handler) {
|
||||
if (events === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
var handlers = this.handlers;
|
||||
each(splitStr(events), function(event) {
|
||||
if (!handler) {
|
||||
delete handlers[event];
|
||||
} else {
|
||||
handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);
|
||||
}
|
||||
});
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* emit event to the listeners
|
||||
* @param {String} event
|
||||
* @param {Object} data
|
||||
*/
|
||||
emit: function(event, data) {
|
||||
// we also want to trigger dom events
|
||||
if (this.options.domEvents) {
|
||||
triggerDomEvent(event, data);
|
||||
}
|
||||
|
||||
// no handlers, so skip it all
|
||||
var handlers = this.handlers[event] && this.handlers[event].slice();
|
||||
if (!handlers || !handlers.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
data.type = event;
|
||||
data.preventDefault = function() {
|
||||
data.srcEvent.preventDefault();
|
||||
};
|
||||
|
||||
var i = 0;
|
||||
while (i < handlers.length) {
|
||||
handlers[i](data);
|
||||
i++;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* destroy the manager and unbinds all events
|
||||
* it doesn't unbind dom events, that is the user own responsibility
|
||||
*/
|
||||
destroy: function() {
|
||||
this.element && toggleCssProps(this, false);
|
||||
|
||||
this.handlers = {};
|
||||
this.session = {};
|
||||
this.input.destroy();
|
||||
this.element = null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* add/remove the css properties as defined in manager.options.cssProps
|
||||
* @param {Manager} manager
|
||||
* @param {Boolean} add
|
||||
*/
|
||||
function toggleCssProps(manager, add) {
|
||||
var element = manager.element;
|
||||
if (!element.style) {
|
||||
return;
|
||||
}
|
||||
var prop;
|
||||
each(manager.options.cssProps, function(value, name) {
|
||||
prop = prefixed(element.style, name);
|
||||
if (add) {
|
||||
manager.oldCssProps[prop] = element.style[prop];
|
||||
element.style[prop] = value;
|
||||
} else {
|
||||
element.style[prop] = manager.oldCssProps[prop] || '';
|
||||
}
|
||||
});
|
||||
if (!add) {
|
||||
manager.oldCssProps = {};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* trigger dom event
|
||||
* @param {String} event
|
||||
* @param {Object} data
|
||||
*/
|
||||
function triggerDomEvent(event, data) {
|
||||
var gestureEvent = document.createEvent('Event');
|
||||
gestureEvent.initEvent(event, true, true);
|
||||
gestureEvent.gesture = data;
|
||||
data.target.dispatchEvent(gestureEvent);
|
||||
}
|
||||
327
LittleShop/wwwroot/lib/hammerjs/src/recognizer.js
Normal file
327
LittleShop/wwwroot/lib/hammerjs/src/recognizer.js
Normal file
@@ -0,0 +1,327 @@
|
||||
/**
|
||||
* Recognizer flow explained; *
|
||||
* All recognizers have the initial state of POSSIBLE when a input session starts.
|
||||
* The definition of a input session is from the first input until the last input, with all it's movement in it. *
|
||||
* Example session for mouse-input: mousedown -> mousemove -> mouseup
|
||||
*
|
||||
* On each recognizing cycle (see Manager.recognize) the .recognize() method is executed
|
||||
* which determines with state it should be.
|
||||
*
|
||||
* If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to
|
||||
* POSSIBLE to give it another change on the next cycle.
|
||||
*
|
||||
* Possible
|
||||
* |
|
||||
* +-----+---------------+
|
||||
* | |
|
||||
* +-----+-----+ |
|
||||
* | | |
|
||||
* Failed Cancelled |
|
||||
* +-------+------+
|
||||
* | |
|
||||
* Recognized Began
|
||||
* |
|
||||
* Changed
|
||||
* |
|
||||
* Ended/Recognized
|
||||
*/
|
||||
var STATE_POSSIBLE = 1;
|
||||
var STATE_BEGAN = 2;
|
||||
var STATE_CHANGED = 4;
|
||||
var STATE_ENDED = 8;
|
||||
var STATE_RECOGNIZED = STATE_ENDED;
|
||||
var STATE_CANCELLED = 16;
|
||||
var STATE_FAILED = 32;
|
||||
|
||||
/**
|
||||
* Recognizer
|
||||
* Every recognizer needs to extend from this class.
|
||||
* @constructor
|
||||
* @param {Object} options
|
||||
*/
|
||||
function Recognizer(options) {
|
||||
this.options = assign({}, this.defaults, options || {});
|
||||
|
||||
this.id = uniqueId();
|
||||
|
||||
this.manager = null;
|
||||
|
||||
// default is enable true
|
||||
this.options.enable = ifUndefined(this.options.enable, true);
|
||||
|
||||
this.state = STATE_POSSIBLE;
|
||||
|
||||
this.simultaneous = {};
|
||||
this.requireFail = [];
|
||||
}
|
||||
|
||||
Recognizer.prototype = {
|
||||
/**
|
||||
* @virtual
|
||||
* @type {Object}
|
||||
*/
|
||||
defaults: {},
|
||||
|
||||
/**
|
||||
* set options
|
||||
* @param {Object} options
|
||||
* @return {Recognizer}
|
||||
*/
|
||||
set: function(options) {
|
||||
assign(this.options, options);
|
||||
|
||||
// also update the touchAction, in case something changed about the directions/enabled state
|
||||
this.manager && this.manager.touchAction.update();
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* recognize simultaneous with an other recognizer.
|
||||
* @param {Recognizer} otherRecognizer
|
||||
* @returns {Recognizer} this
|
||||
*/
|
||||
recognizeWith: function(otherRecognizer) {
|
||||
if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
var simultaneous = this.simultaneous;
|
||||
otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
|
||||
if (!simultaneous[otherRecognizer.id]) {
|
||||
simultaneous[otherRecognizer.id] = otherRecognizer;
|
||||
otherRecognizer.recognizeWith(this);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* drop the simultaneous link. it doesnt remove the link on the other recognizer.
|
||||
* @param {Recognizer} otherRecognizer
|
||||
* @returns {Recognizer} this
|
||||
*/
|
||||
dropRecognizeWith: function(otherRecognizer) {
|
||||
if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
|
||||
delete this.simultaneous[otherRecognizer.id];
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* recognizer can only run when an other is failing
|
||||
* @param {Recognizer} otherRecognizer
|
||||
* @returns {Recognizer} this
|
||||
*/
|
||||
requireFailure: function(otherRecognizer) {
|
||||
if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
var requireFail = this.requireFail;
|
||||
otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
|
||||
if (inArray(requireFail, otherRecognizer) === -1) {
|
||||
requireFail.push(otherRecognizer);
|
||||
otherRecognizer.requireFailure(this);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* drop the requireFailure link. it does not remove the link on the other recognizer.
|
||||
* @param {Recognizer} otherRecognizer
|
||||
* @returns {Recognizer} this
|
||||
*/
|
||||
dropRequireFailure: function(otherRecognizer) {
|
||||
if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);
|
||||
var index = inArray(this.requireFail, otherRecognizer);
|
||||
if (index > -1) {
|
||||
this.requireFail.splice(index, 1);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* has require failures boolean
|
||||
* @returns {boolean}
|
||||
*/
|
||||
hasRequireFailures: function() {
|
||||
return this.requireFail.length > 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* if the recognizer can recognize simultaneous with an other recognizer
|
||||
* @param {Recognizer} otherRecognizer
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
canRecognizeWith: function(otherRecognizer) {
|
||||
return !!this.simultaneous[otherRecognizer.id];
|
||||
},
|
||||
|
||||
/**
|
||||
* You should use `tryEmit` instead of `emit` directly to check
|
||||
* that all the needed recognizers has failed before emitting.
|
||||
* @param {Object} input
|
||||
*/
|
||||
emit: function(input) {
|
||||
var self = this;
|
||||
var state = this.state;
|
||||
|
||||
function emit(event) {
|
||||
self.manager.emit(event, input);
|
||||
}
|
||||
|
||||
// 'panstart' and 'panmove'
|
||||
if (state < STATE_ENDED) {
|
||||
emit(self.options.event + stateStr(state));
|
||||
}
|
||||
|
||||
emit(self.options.event); // simple 'eventName' events
|
||||
|
||||
if (input.additionalEvent) { // additional event(panleft, panright, pinchin, pinchout...)
|
||||
emit(input.additionalEvent);
|
||||
}
|
||||
|
||||
// panend and pancancel
|
||||
if (state >= STATE_ENDED) {
|
||||
emit(self.options.event + stateStr(state));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Check that all the require failure recognizers has failed,
|
||||
* if true, it emits a gesture event,
|
||||
* otherwise, setup the state to FAILED.
|
||||
* @param {Object} input
|
||||
*/
|
||||
tryEmit: function(input) {
|
||||
if (this.canEmit()) {
|
||||
return this.emit(input);
|
||||
}
|
||||
// it's failing anyway
|
||||
this.state = STATE_FAILED;
|
||||
},
|
||||
|
||||
/**
|
||||
* can we emit?
|
||||
* @returns {boolean}
|
||||
*/
|
||||
canEmit: function() {
|
||||
var i = 0;
|
||||
while (i < this.requireFail.length) {
|
||||
if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) {
|
||||
return false;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* update the recognizer
|
||||
* @param {Object} inputData
|
||||
*/
|
||||
recognize: function(inputData) {
|
||||
// make a new copy of the inputData
|
||||
// so we can change the inputData without messing up the other recognizers
|
||||
var inputDataClone = assign({}, inputData);
|
||||
|
||||
// is is enabled and allow recognizing?
|
||||
if (!boolOrFn(this.options.enable, [this, inputDataClone])) {
|
||||
this.reset();
|
||||
this.state = STATE_FAILED;
|
||||
return;
|
||||
}
|
||||
|
||||
// reset when we've reached the end
|
||||
if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) {
|
||||
this.state = STATE_POSSIBLE;
|
||||
}
|
||||
|
||||
this.state = this.process(inputDataClone);
|
||||
|
||||
// the recognizer has recognized a gesture
|
||||
// so trigger an event
|
||||
if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) {
|
||||
this.tryEmit(inputDataClone);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* return the state of the recognizer
|
||||
* the actual recognizing happens in this method
|
||||
* @virtual
|
||||
* @param {Object} inputData
|
||||
* @returns {Const} STATE
|
||||
*/
|
||||
process: function(inputData) { }, // jshint ignore:line
|
||||
|
||||
/**
|
||||
* return the preferred touch-action
|
||||
* @virtual
|
||||
* @returns {Array}
|
||||
*/
|
||||
getTouchAction: function() { },
|
||||
|
||||
/**
|
||||
* called when the gesture isn't allowed to recognize
|
||||
* like when another is being recognized or it is disabled
|
||||
* @virtual
|
||||
*/
|
||||
reset: function() { }
|
||||
};
|
||||
|
||||
/**
|
||||
* get a usable string, used as event postfix
|
||||
* @param {Const} state
|
||||
* @returns {String} state
|
||||
*/
|
||||
function stateStr(state) {
|
||||
if (state & STATE_CANCELLED) {
|
||||
return 'cancel';
|
||||
} else if (state & STATE_ENDED) {
|
||||
return 'end';
|
||||
} else if (state & STATE_CHANGED) {
|
||||
return 'move';
|
||||
} else if (state & STATE_BEGAN) {
|
||||
return 'start';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* direction cons to string
|
||||
* @param {Const} direction
|
||||
* @returns {String}
|
||||
*/
|
||||
function directionStr(direction) {
|
||||
if (direction == DIRECTION_DOWN) {
|
||||
return 'down';
|
||||
} else if (direction == DIRECTION_UP) {
|
||||
return 'up';
|
||||
} else if (direction == DIRECTION_LEFT) {
|
||||
return 'left';
|
||||
} else if (direction == DIRECTION_RIGHT) {
|
||||
return 'right';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* get a recognizer by name if it is bound to a manager
|
||||
* @param {Recognizer|String} otherRecognizer
|
||||
* @param {Recognizer} recognizer
|
||||
* @returns {Recognizer}
|
||||
*/
|
||||
function getRecognizerByNameIfManager(otherRecognizer, recognizer) {
|
||||
var manager = recognizer.manager;
|
||||
if (manager) {
|
||||
return manager.get(otherRecognizer);
|
||||
}
|
||||
return otherRecognizer;
|
||||
}
|
||||
60
LittleShop/wwwroot/lib/hammerjs/src/recognizers/attribute.js
Normal file
60
LittleShop/wwwroot/lib/hammerjs/src/recognizers/attribute.js
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* This recognizer is just used as a base for the simple attribute recognizers.
|
||||
* @constructor
|
||||
* @extends Recognizer
|
||||
*/
|
||||
function AttrRecognizer() {
|
||||
Recognizer.apply(this, arguments);
|
||||
}
|
||||
|
||||
inherit(AttrRecognizer, Recognizer, {
|
||||
/**
|
||||
* @namespace
|
||||
* @memberof AttrRecognizer
|
||||
*/
|
||||
defaults: {
|
||||
/**
|
||||
* @type {Number}
|
||||
* @default 1
|
||||
*/
|
||||
pointers: 1
|
||||
},
|
||||
|
||||
/**
|
||||
* Used to check if it the recognizer receives valid input, like input.distance > 10.
|
||||
* @memberof AttrRecognizer
|
||||
* @param {Object} input
|
||||
* @returns {Boolean} recognized
|
||||
*/
|
||||
attrTest: function(input) {
|
||||
var optionPointers = this.options.pointers;
|
||||
return optionPointers === 0 || input.pointers.length === optionPointers;
|
||||
},
|
||||
|
||||
/**
|
||||
* Process the input and return the state for the recognizer
|
||||
* @memberof AttrRecognizer
|
||||
* @param {Object} input
|
||||
* @returns {*} State
|
||||
*/
|
||||
process: function(input) {
|
||||
var state = this.state;
|
||||
var eventType = input.eventType;
|
||||
|
||||
var isRecognized = state & (STATE_BEGAN | STATE_CHANGED);
|
||||
var isValid = this.attrTest(input);
|
||||
|
||||
// on cancel input and we've recognized before, return STATE_CANCELLED
|
||||
if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) {
|
||||
return state | STATE_CANCELLED;
|
||||
} else if (isRecognized || isValid) {
|
||||
if (eventType & INPUT_END) {
|
||||
return state | STATE_ENDED;
|
||||
} else if (!(state & STATE_BEGAN)) {
|
||||
return STATE_BEGAN;
|
||||
}
|
||||
return state | STATE_CHANGED;
|
||||
}
|
||||
return STATE_FAILED;
|
||||
}
|
||||
});
|
||||
79
LittleShop/wwwroot/lib/hammerjs/src/recognizers/pan.js
Normal file
79
LittleShop/wwwroot/lib/hammerjs/src/recognizers/pan.js
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Pan
|
||||
* Recognized when the pointer is down and moved in the allowed direction.
|
||||
* @constructor
|
||||
* @extends AttrRecognizer
|
||||
*/
|
||||
function PanRecognizer() {
|
||||
AttrRecognizer.apply(this, arguments);
|
||||
|
||||
this.pX = null;
|
||||
this.pY = null;
|
||||
}
|
||||
|
||||
inherit(PanRecognizer, AttrRecognizer, {
|
||||
/**
|
||||
* @namespace
|
||||
* @memberof PanRecognizer
|
||||
*/
|
||||
defaults: {
|
||||
event: 'pan',
|
||||
threshold: 10,
|
||||
pointers: 1,
|
||||
direction: DIRECTION_ALL
|
||||
},
|
||||
|
||||
getTouchAction: function() {
|
||||
var direction = this.options.direction;
|
||||
var actions = [];
|
||||
if (direction & DIRECTION_HORIZONTAL) {
|
||||
actions.push(TOUCH_ACTION_PAN_Y);
|
||||
}
|
||||
if (direction & DIRECTION_VERTICAL) {
|
||||
actions.push(TOUCH_ACTION_PAN_X);
|
||||
}
|
||||
return actions;
|
||||
},
|
||||
|
||||
directionTest: function(input) {
|
||||
var options = this.options;
|
||||
var hasMoved = true;
|
||||
var distance = input.distance;
|
||||
var direction = input.direction;
|
||||
var x = input.deltaX;
|
||||
var y = input.deltaY;
|
||||
|
||||
// lock to axis?
|
||||
if (!(direction & options.direction)) {
|
||||
if (options.direction & DIRECTION_HORIZONTAL) {
|
||||
direction = (x === 0) ? DIRECTION_NONE : (x < 0) ? DIRECTION_LEFT : DIRECTION_RIGHT;
|
||||
hasMoved = x != this.pX;
|
||||
distance = Math.abs(input.deltaX);
|
||||
} else {
|
||||
direction = (y === 0) ? DIRECTION_NONE : (y < 0) ? DIRECTION_UP : DIRECTION_DOWN;
|
||||
hasMoved = y != this.pY;
|
||||
distance = Math.abs(input.deltaY);
|
||||
}
|
||||
}
|
||||
input.direction = direction;
|
||||
return hasMoved && distance > options.threshold && direction & options.direction;
|
||||
},
|
||||
|
||||
attrTest: function(input) {
|
||||
return AttrRecognizer.prototype.attrTest.call(this, input) &&
|
||||
(this.state & STATE_BEGAN || (!(this.state & STATE_BEGAN) && this.directionTest(input)));
|
||||
},
|
||||
|
||||
emit: function(input) {
|
||||
|
||||
this.pX = input.deltaX;
|
||||
this.pY = input.deltaY;
|
||||
|
||||
var direction = directionStr(input.direction);
|
||||
|
||||
if (direction) {
|
||||
input.additionalEvent = this.options.event + direction;
|
||||
}
|
||||
this._super.emit.call(this, input);
|
||||
}
|
||||
});
|
||||
38
LittleShop/wwwroot/lib/hammerjs/src/recognizers/pinch.js
Normal file
38
LittleShop/wwwroot/lib/hammerjs/src/recognizers/pinch.js
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Pinch
|
||||
* Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out).
|
||||
* @constructor
|
||||
* @extends AttrRecognizer
|
||||
*/
|
||||
function PinchRecognizer() {
|
||||
AttrRecognizer.apply(this, arguments);
|
||||
}
|
||||
|
||||
inherit(PinchRecognizer, AttrRecognizer, {
|
||||
/**
|
||||
* @namespace
|
||||
* @memberof PinchRecognizer
|
||||
*/
|
||||
defaults: {
|
||||
event: 'pinch',
|
||||
threshold: 0,
|
||||
pointers: 2
|
||||
},
|
||||
|
||||
getTouchAction: function() {
|
||||
return [TOUCH_ACTION_NONE];
|
||||
},
|
||||
|
||||
attrTest: function(input) {
|
||||
return this._super.attrTest.call(this, input) &&
|
||||
(Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN);
|
||||
},
|
||||
|
||||
emit: function(input) {
|
||||
if (input.scale !== 1) {
|
||||
var inOut = input.scale < 1 ? 'in' : 'out';
|
||||
input.additionalEvent = this.options.event + inOut;
|
||||
}
|
||||
this._super.emit.call(this, input);
|
||||
}
|
||||
});
|
||||
70
LittleShop/wwwroot/lib/hammerjs/src/recognizers/press.js
Normal file
70
LittleShop/wwwroot/lib/hammerjs/src/recognizers/press.js
Normal file
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* Press
|
||||
* Recognized when the pointer is down for x ms without any movement.
|
||||
* @constructor
|
||||
* @extends Recognizer
|
||||
*/
|
||||
function PressRecognizer() {
|
||||
Recognizer.apply(this, arguments);
|
||||
|
||||
this._timer = null;
|
||||
this._input = null;
|
||||
}
|
||||
|
||||
inherit(PressRecognizer, Recognizer, {
|
||||
/**
|
||||
* @namespace
|
||||
* @memberof PressRecognizer
|
||||
*/
|
||||
defaults: {
|
||||
event: 'press',
|
||||
pointers: 1,
|
||||
time: 251, // minimal time of the pointer to be pressed
|
||||
threshold: 9 // a minimal movement is ok, but keep it low
|
||||
},
|
||||
|
||||
getTouchAction: function() {
|
||||
return [TOUCH_ACTION_AUTO];
|
||||
},
|
||||
|
||||
process: function(input) {
|
||||
var options = this.options;
|
||||
var validPointers = input.pointers.length === options.pointers;
|
||||
var validMovement = input.distance < options.threshold;
|
||||
var validTime = input.deltaTime > options.time;
|
||||
|
||||
this._input = input;
|
||||
|
||||
// we only allow little movement
|
||||
// and we've reached an end event, so a tap is possible
|
||||
if (!validMovement || !validPointers || (input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime)) {
|
||||
this.reset();
|
||||
} else if (input.eventType & INPUT_START) {
|
||||
this.reset();
|
||||
this._timer = setTimeoutContext(function() {
|
||||
this.state = STATE_RECOGNIZED;
|
||||
this.tryEmit();
|
||||
}, options.time, this);
|
||||
} else if (input.eventType & INPUT_END) {
|
||||
return STATE_RECOGNIZED;
|
||||
}
|
||||
return STATE_FAILED;
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
clearTimeout(this._timer);
|
||||
},
|
||||
|
||||
emit: function(input) {
|
||||
if (this.state !== STATE_RECOGNIZED) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (input && (input.eventType & INPUT_END)) {
|
||||
this.manager.emit(this.options.event + 'up', input);
|
||||
} else {
|
||||
this._input.timeStamp = now();
|
||||
this.manager.emit(this.options.event, this._input);
|
||||
}
|
||||
}
|
||||
});
|
||||
30
LittleShop/wwwroot/lib/hammerjs/src/recognizers/rotate.js
Normal file
30
LittleShop/wwwroot/lib/hammerjs/src/recognizers/rotate.js
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Rotate
|
||||
* Recognized when two or more pointer are moving in a circular motion.
|
||||
* @constructor
|
||||
* @extends AttrRecognizer
|
||||
*/
|
||||
function RotateRecognizer() {
|
||||
AttrRecognizer.apply(this, arguments);
|
||||
}
|
||||
|
||||
inherit(RotateRecognizer, AttrRecognizer, {
|
||||
/**
|
||||
* @namespace
|
||||
* @memberof RotateRecognizer
|
||||
*/
|
||||
defaults: {
|
||||
event: 'rotate',
|
||||
threshold: 0,
|
||||
pointers: 2
|
||||
},
|
||||
|
||||
getTouchAction: function() {
|
||||
return [TOUCH_ACTION_NONE];
|
||||
},
|
||||
|
||||
attrTest: function(input) {
|
||||
return this._super.attrTest.call(this, input) &&
|
||||
(Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);
|
||||
}
|
||||
});
|
||||
55
LittleShop/wwwroot/lib/hammerjs/src/recognizers/swipe.js
Normal file
55
LittleShop/wwwroot/lib/hammerjs/src/recognizers/swipe.js
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Swipe
|
||||
* Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction.
|
||||
* @constructor
|
||||
* @extends AttrRecognizer
|
||||
*/
|
||||
function SwipeRecognizer() {
|
||||
AttrRecognizer.apply(this, arguments);
|
||||
}
|
||||
|
||||
inherit(SwipeRecognizer, AttrRecognizer, {
|
||||
/**
|
||||
* @namespace
|
||||
* @memberof SwipeRecognizer
|
||||
*/
|
||||
defaults: {
|
||||
event: 'swipe',
|
||||
threshold: 10,
|
||||
velocity: 0.3,
|
||||
direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,
|
||||
pointers: 1
|
||||
},
|
||||
|
||||
getTouchAction: function() {
|
||||
return PanRecognizer.prototype.getTouchAction.call(this);
|
||||
},
|
||||
|
||||
attrTest: function(input) {
|
||||
var direction = this.options.direction;
|
||||
var velocity;
|
||||
|
||||
if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {
|
||||
velocity = input.overallVelocity;
|
||||
} else if (direction & DIRECTION_HORIZONTAL) {
|
||||
velocity = input.overallVelocityX;
|
||||
} else if (direction & DIRECTION_VERTICAL) {
|
||||
velocity = input.overallVelocityY;
|
||||
}
|
||||
|
||||
return this._super.attrTest.call(this, input) &&
|
||||
direction & input.offsetDirection &&
|
||||
input.distance > this.options.threshold &&
|
||||
input.maxPointers == this.options.pointers &&
|
||||
abs(velocity) > this.options.velocity && input.eventType & INPUT_END;
|
||||
},
|
||||
|
||||
emit: function(input) {
|
||||
var direction = directionStr(input.offsetDirection);
|
||||
if (direction) {
|
||||
this.manager.emit(this.options.event + direction, input);
|
||||
}
|
||||
|
||||
this.manager.emit(this.options.event, input);
|
||||
}
|
||||
});
|
||||
114
LittleShop/wwwroot/lib/hammerjs/src/recognizers/tap.js
Normal file
114
LittleShop/wwwroot/lib/hammerjs/src/recognizers/tap.js
Normal file
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur
|
||||
* between the given interval and position. The delay option can be used to recognize multi-taps without firing
|
||||
* a single tap.
|
||||
*
|
||||
* The eventData from the emitted event contains the property `tapCount`, which contains the amount of
|
||||
* multi-taps being recognized.
|
||||
* @constructor
|
||||
* @extends Recognizer
|
||||
*/
|
||||
function TapRecognizer() {
|
||||
Recognizer.apply(this, arguments);
|
||||
|
||||
// previous time and center,
|
||||
// used for tap counting
|
||||
this.pTime = false;
|
||||
this.pCenter = false;
|
||||
|
||||
this._timer = null;
|
||||
this._input = null;
|
||||
this.count = 0;
|
||||
}
|
||||
|
||||
inherit(TapRecognizer, Recognizer, {
|
||||
/**
|
||||
* @namespace
|
||||
* @memberof PinchRecognizer
|
||||
*/
|
||||
defaults: {
|
||||
event: 'tap',
|
||||
pointers: 1,
|
||||
taps: 1,
|
||||
interval: 300, // max time between the multi-tap taps
|
||||
time: 250, // max time of the pointer to be down (like finger on the screen)
|
||||
threshold: 9, // a minimal movement is ok, but keep it low
|
||||
posThreshold: 10 // a multi-tap can be a bit off the initial position
|
||||
},
|
||||
|
||||
getTouchAction: function() {
|
||||
return [TOUCH_ACTION_MANIPULATION];
|
||||
},
|
||||
|
||||
process: function(input) {
|
||||
var options = this.options;
|
||||
|
||||
var validPointers = input.pointers.length === options.pointers;
|
||||
var validMovement = input.distance < options.threshold;
|
||||
var validTouchTime = input.deltaTime < options.time;
|
||||
|
||||
this.reset();
|
||||
|
||||
if ((input.eventType & INPUT_START) && (this.count === 0)) {
|
||||
return this.failTimeout();
|
||||
}
|
||||
|
||||
// we only allow little movement
|
||||
// and we've reached an end event, so a tap is possible
|
||||
if (validMovement && validTouchTime && validPointers) {
|
||||
if (input.eventType != INPUT_END) {
|
||||
return this.failTimeout();
|
||||
}
|
||||
|
||||
var validInterval = this.pTime ? (input.timeStamp - this.pTime < options.interval) : true;
|
||||
var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;
|
||||
|
||||
this.pTime = input.timeStamp;
|
||||
this.pCenter = input.center;
|
||||
|
||||
if (!validMultiTap || !validInterval) {
|
||||
this.count = 1;
|
||||
} else {
|
||||
this.count += 1;
|
||||
}
|
||||
|
||||
this._input = input;
|
||||
|
||||
// if tap count matches we have recognized it,
|
||||
// else it has began recognizing...
|
||||
var tapCount = this.count % options.taps;
|
||||
if (tapCount === 0) {
|
||||
// no failing requirements, immediately trigger the tap event
|
||||
// or wait as long as the multitap interval to trigger
|
||||
if (!this.hasRequireFailures()) {
|
||||
return STATE_RECOGNIZED;
|
||||
} else {
|
||||
this._timer = setTimeoutContext(function() {
|
||||
this.state = STATE_RECOGNIZED;
|
||||
this.tryEmit();
|
||||
}, options.interval, this);
|
||||
return STATE_BEGAN;
|
||||
}
|
||||
}
|
||||
}
|
||||
return STATE_FAILED;
|
||||
},
|
||||
|
||||
failTimeout: function() {
|
||||
this._timer = setTimeoutContext(function() {
|
||||
this.state = STATE_FAILED;
|
||||
}, this.options.interval, this);
|
||||
return STATE_FAILED;
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
clearTimeout(this._timer);
|
||||
},
|
||||
|
||||
emit: function() {
|
||||
if (this.state == STATE_RECOGNIZED) {
|
||||
this._input.tapCount = this.count;
|
||||
this.manager.emit(this.options.event, this._input);
|
||||
}
|
||||
}
|
||||
});
|
||||
164
LittleShop/wwwroot/lib/hammerjs/src/touchaction.js
Normal file
164
LittleShop/wwwroot/lib/hammerjs/src/touchaction.js
Normal file
@@ -0,0 +1,164 @@
|
||||
var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');
|
||||
var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined;
|
||||
|
||||
// magical touchAction value
|
||||
var TOUCH_ACTION_COMPUTE = 'compute';
|
||||
var TOUCH_ACTION_AUTO = 'auto';
|
||||
var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented
|
||||
var TOUCH_ACTION_NONE = 'none';
|
||||
var TOUCH_ACTION_PAN_X = 'pan-x';
|
||||
var TOUCH_ACTION_PAN_Y = 'pan-y';
|
||||
var TOUCH_ACTION_MAP = getTouchActionProps();
|
||||
|
||||
/**
|
||||
* Touch Action
|
||||
* sets the touchAction property or uses the js alternative
|
||||
* @param {Manager} manager
|
||||
* @param {String} value
|
||||
* @constructor
|
||||
*/
|
||||
function TouchAction(manager, value) {
|
||||
this.manager = manager;
|
||||
this.set(value);
|
||||
}
|
||||
|
||||
TouchAction.prototype = {
|
||||
/**
|
||||
* set the touchAction value on the element or enable the polyfill
|
||||
* @param {String} value
|
||||
*/
|
||||
set: function(value) {
|
||||
// find out the touch-action by the event handlers
|
||||
if (value == TOUCH_ACTION_COMPUTE) {
|
||||
value = this.compute();
|
||||
}
|
||||
|
||||
if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) {
|
||||
this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;
|
||||
}
|
||||
this.actions = value.toLowerCase().trim();
|
||||
},
|
||||
|
||||
/**
|
||||
* just re-set the touchAction value
|
||||
*/
|
||||
update: function() {
|
||||
this.set(this.manager.options.touchAction);
|
||||
},
|
||||
|
||||
/**
|
||||
* compute the value for the touchAction property based on the recognizer's settings
|
||||
* @returns {String} value
|
||||
*/
|
||||
compute: function() {
|
||||
var actions = [];
|
||||
each(this.manager.recognizers, function(recognizer) {
|
||||
if (boolOrFn(recognizer.options.enable, [recognizer])) {
|
||||
actions = actions.concat(recognizer.getTouchAction());
|
||||
}
|
||||
});
|
||||
return cleanTouchActions(actions.join(' '));
|
||||
},
|
||||
|
||||
/**
|
||||
* this method is called on each input cycle and provides the preventing of the browser behavior
|
||||
* @param {Object} input
|
||||
*/
|
||||
preventDefaults: function(input) {
|
||||
var srcEvent = input.srcEvent;
|
||||
var direction = input.offsetDirection;
|
||||
|
||||
// if the touch action did prevented once this session
|
||||
if (this.manager.session.prevented) {
|
||||
srcEvent.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
var actions = this.actions;
|
||||
var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE];
|
||||
var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y];
|
||||
var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X];
|
||||
|
||||
if (hasNone) {
|
||||
//do not prevent defaults if this is a tap gesture
|
||||
|
||||
var isTapPointer = input.pointers.length === 1;
|
||||
var isTapMovement = input.distance < 2;
|
||||
var isTapTouchTime = input.deltaTime < 250;
|
||||
|
||||
if (isTapPointer && isTapMovement && isTapTouchTime) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasPanX && hasPanY) {
|
||||
// `pan-x pan-y` means browser handles all scrolling/panning, do not prevent
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasNone ||
|
||||
(hasPanY && direction & DIRECTION_HORIZONTAL) ||
|
||||
(hasPanX && direction & DIRECTION_VERTICAL)) {
|
||||
return this.preventSrc(srcEvent);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* call preventDefault to prevent the browser's default behavior (scrolling in most cases)
|
||||
* @param {Object} srcEvent
|
||||
*/
|
||||
preventSrc: function(srcEvent) {
|
||||
this.manager.session.prevented = true;
|
||||
srcEvent.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* when the touchActions are collected they are not a valid value, so we need to clean things up. *
|
||||
* @param {String} actions
|
||||
* @returns {*}
|
||||
*/
|
||||
function cleanTouchActions(actions) {
|
||||
// none
|
||||
if (inStr(actions, TOUCH_ACTION_NONE)) {
|
||||
return TOUCH_ACTION_NONE;
|
||||
}
|
||||
|
||||
var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);
|
||||
var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y);
|
||||
|
||||
// if both pan-x and pan-y are set (different recognizers
|
||||
// for different directions, e.g. horizontal pan but vertical swipe?)
|
||||
// we need none (as otherwise with pan-x pan-y combined none of these
|
||||
// recognizers will work, since the browser would handle all panning
|
||||
if (hasPanX && hasPanY) {
|
||||
return TOUCH_ACTION_NONE;
|
||||
}
|
||||
|
||||
// pan-x OR pan-y
|
||||
if (hasPanX || hasPanY) {
|
||||
return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;
|
||||
}
|
||||
|
||||
// manipulation
|
||||
if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {
|
||||
return TOUCH_ACTION_MANIPULATION;
|
||||
}
|
||||
|
||||
return TOUCH_ACTION_AUTO;
|
||||
}
|
||||
|
||||
function getTouchActionProps() {
|
||||
if (!NATIVE_TOUCH_ACTION) {
|
||||
return false;
|
||||
}
|
||||
var touchMap = {};
|
||||
var cssSupports = window.CSS && window.CSS.supports;
|
||||
['auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'].forEach(function(val) {
|
||||
|
||||
// If css.supports is not supported but there is native touch-action assume it supports
|
||||
// all values. This is the case for IE 10 and 11.
|
||||
touchMap[val] = cssSupports ? window.CSS.supports('touch-action', val) : true;
|
||||
});
|
||||
return touchMap;
|
||||
}
|
||||
371
LittleShop/wwwroot/lib/hammerjs/src/utils.js
Normal file
371
LittleShop/wwwroot/lib/hammerjs/src/utils.js
Normal file
@@ -0,0 +1,371 @@
|
||||
var VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];
|
||||
var TEST_ELEMENT = document.createElement('div');
|
||||
|
||||
var TYPE_FUNCTION = 'function';
|
||||
|
||||
var round = Math.round;
|
||||
var abs = Math.abs;
|
||||
var now = Date.now;
|
||||
|
||||
/**
|
||||
* set a timeout with a given scope
|
||||
* @param {Function} fn
|
||||
* @param {Number} timeout
|
||||
* @param {Object} context
|
||||
* @returns {number}
|
||||
*/
|
||||
function setTimeoutContext(fn, timeout, context) {
|
||||
return setTimeout(bindFn(fn, context), timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* if the argument is an array, we want to execute the fn on each entry
|
||||
* if it aint an array we don't want to do a thing.
|
||||
* this is used by all the methods that accept a single and array argument.
|
||||
* @param {*|Array} arg
|
||||
* @param {String} fn
|
||||
* @param {Object} [context]
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
function invokeArrayArg(arg, fn, context) {
|
||||
if (Array.isArray(arg)) {
|
||||
each(arg, context[fn], context);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* walk objects and arrays
|
||||
* @param {Object} obj
|
||||
* @param {Function} iterator
|
||||
* @param {Object} context
|
||||
*/
|
||||
function each(obj, iterator, context) {
|
||||
var i;
|
||||
|
||||
if (!obj) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj.forEach) {
|
||||
obj.forEach(iterator, context);
|
||||
} else if (obj.length !== undefined) {
|
||||
i = 0;
|
||||
while (i < obj.length) {
|
||||
iterator.call(context, obj[i], i, obj);
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
for (i in obj) {
|
||||
obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wrap a method with a deprecation warning and stack trace
|
||||
* @param {Function} method
|
||||
* @param {String} name
|
||||
* @param {String} message
|
||||
* @returns {Function} A new function wrapping the supplied method.
|
||||
*/
|
||||
function deprecate(method, name, message) {
|
||||
var deprecationMessage = 'DEPRECATED METHOD: ' + name + '\n' + message + ' AT \n';
|
||||
return function() {
|
||||
var e = new Error('get-stack-trace');
|
||||
var stack = e && e.stack ? e.stack.replace(/^[^\(]+?[\n$]/gm, '')
|
||||
.replace(/^\s+at\s+/gm, '')
|
||||
.replace(/^Object.<anonymous>\s*\(/gm, '{anonymous}()@') : 'Unknown Stack Trace';
|
||||
|
||||
var log = window.console && (window.console.warn || window.console.log);
|
||||
if (log) {
|
||||
log.call(window.console, deprecationMessage, stack);
|
||||
}
|
||||
return method.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* extend object.
|
||||
* means that properties in dest will be overwritten by the ones in src.
|
||||
* @param {Object} target
|
||||
* @param {...Object} objects_to_assign
|
||||
* @returns {Object} target
|
||||
*/
|
||||
var assign;
|
||||
if (typeof Object.assign !== 'function') {
|
||||
assign = function assign(target) {
|
||||
if (target === undefined || target === null) {
|
||||
throw new TypeError('Cannot convert undefined or null to object');
|
||||
}
|
||||
|
||||
var output = Object(target);
|
||||
for (var index = 1; index < arguments.length; index++) {
|
||||
var source = arguments[index];
|
||||
if (source !== undefined && source !== null) {
|
||||
for (var nextKey in source) {
|
||||
if (source.hasOwnProperty(nextKey)) {
|
||||
output[nextKey] = source[nextKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return output;
|
||||
};
|
||||
} else {
|
||||
assign = Object.assign;
|
||||
}
|
||||
|
||||
/**
|
||||
* extend object.
|
||||
* means that properties in dest will be overwritten by the ones in src.
|
||||
* @param {Object} dest
|
||||
* @param {Object} src
|
||||
* @param {Boolean} [merge=false]
|
||||
* @returns {Object} dest
|
||||
*/
|
||||
var extend = deprecate(function extend(dest, src, merge) {
|
||||
var keys = Object.keys(src);
|
||||
var i = 0;
|
||||
while (i < keys.length) {
|
||||
if (!merge || (merge && dest[keys[i]] === undefined)) {
|
||||
dest[keys[i]] = src[keys[i]];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return dest;
|
||||
}, 'extend', 'Use `assign`.');
|
||||
|
||||
/**
|
||||
* merge the values from src in the dest.
|
||||
* means that properties that exist in dest will not be overwritten by src
|
||||
* @param {Object} dest
|
||||
* @param {Object} src
|
||||
* @returns {Object} dest
|
||||
*/
|
||||
var merge = deprecate(function merge(dest, src) {
|
||||
return extend(dest, src, true);
|
||||
}, 'merge', 'Use `assign`.');
|
||||
|
||||
/**
|
||||
* simple class inheritance
|
||||
* @param {Function} child
|
||||
* @param {Function} base
|
||||
* @param {Object} [properties]
|
||||
*/
|
||||
function inherit(child, base, properties) {
|
||||
var baseP = base.prototype,
|
||||
childP;
|
||||
|
||||
childP = child.prototype = Object.create(baseP);
|
||||
childP.constructor = child;
|
||||
childP._super = baseP;
|
||||
|
||||
if (properties) {
|
||||
assign(childP, properties);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* simple function bind
|
||||
* @param {Function} fn
|
||||
* @param {Object} context
|
||||
* @returns {Function}
|
||||
*/
|
||||
function bindFn(fn, context) {
|
||||
return function boundFn() {
|
||||
return fn.apply(context, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* let a boolean value also be a function that must return a boolean
|
||||
* this first item in args will be used as the context
|
||||
* @param {Boolean|Function} val
|
||||
* @param {Array} [args]
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
function boolOrFn(val, args) {
|
||||
if (typeof val == TYPE_FUNCTION) {
|
||||
return val.apply(args ? args[0] || undefined : undefined, args);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* use the val2 when val1 is undefined
|
||||
* @param {*} val1
|
||||
* @param {*} val2
|
||||
* @returns {*}
|
||||
*/
|
||||
function ifUndefined(val1, val2) {
|
||||
return (val1 === undefined) ? val2 : val1;
|
||||
}
|
||||
|
||||
/**
|
||||
* addEventListener with multiple events at once
|
||||
* @param {EventTarget} target
|
||||
* @param {String} types
|
||||
* @param {Function} handler
|
||||
*/
|
||||
function addEventListeners(target, types, handler) {
|
||||
each(splitStr(types), function(type) {
|
||||
target.addEventListener(type, handler, false);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* removeEventListener with multiple events at once
|
||||
* @param {EventTarget} target
|
||||
* @param {String} types
|
||||
* @param {Function} handler
|
||||
*/
|
||||
function removeEventListeners(target, types, handler) {
|
||||
each(splitStr(types), function(type) {
|
||||
target.removeEventListener(type, handler, false);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* find if a node is in the given parent
|
||||
* @method hasParent
|
||||
* @param {HTMLElement} node
|
||||
* @param {HTMLElement} parent
|
||||
* @return {Boolean} found
|
||||
*/
|
||||
function hasParent(node, parent) {
|
||||
while (node) {
|
||||
if (node == parent) {
|
||||
return true;
|
||||
}
|
||||
node = node.parentNode;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* small indexOf wrapper
|
||||
* @param {String} str
|
||||
* @param {String} find
|
||||
* @returns {Boolean} found
|
||||
*/
|
||||
function inStr(str, find) {
|
||||
return str.indexOf(find) > -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* split string on whitespace
|
||||
* @param {String} str
|
||||
* @returns {Array} words
|
||||
*/
|
||||
function splitStr(str) {
|
||||
return str.trim().split(/\s+/g);
|
||||
}
|
||||
|
||||
/**
|
||||
* find if a array contains the object using indexOf or a simple polyFill
|
||||
* @param {Array} src
|
||||
* @param {String} find
|
||||
* @param {String} [findByKey]
|
||||
* @return {Boolean|Number} false when not found, or the index
|
||||
*/
|
||||
function inArray(src, find, findByKey) {
|
||||
if (src.indexOf && !findByKey) {
|
||||
return src.indexOf(find);
|
||||
} else {
|
||||
var i = 0;
|
||||
while (i < src.length) {
|
||||
if ((findByKey && src[i][findByKey] == find) || (!findByKey && src[i] === find)) {
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* convert array-like objects to real arrays
|
||||
* @param {Object} obj
|
||||
* @returns {Array}
|
||||
*/
|
||||
function toArray(obj) {
|
||||
return Array.prototype.slice.call(obj, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* unique array with objects based on a key (like 'id') or just by the array's value
|
||||
* @param {Array} src [{id:1},{id:2},{id:1}]
|
||||
* @param {String} [key]
|
||||
* @param {Boolean} [sort=False]
|
||||
* @returns {Array} [{id:1},{id:2}]
|
||||
*/
|
||||
function uniqueArray(src, key, sort) {
|
||||
var results = [];
|
||||
var values = [];
|
||||
var i = 0;
|
||||
|
||||
while (i < src.length) {
|
||||
var val = key ? src[i][key] : src[i];
|
||||
if (inArray(values, val) < 0) {
|
||||
results.push(src[i]);
|
||||
}
|
||||
values[i] = val;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (sort) {
|
||||
if (!key) {
|
||||
results = results.sort();
|
||||
} else {
|
||||
results = results.sort(function sortUniqueArray(a, b) {
|
||||
return a[key] > b[key];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the prefixed property
|
||||
* @param {Object} obj
|
||||
* @param {String} property
|
||||
* @returns {String|Undefined} prefixed
|
||||
*/
|
||||
function prefixed(obj, property) {
|
||||
var prefix, prop;
|
||||
var camelProp = property[0].toUpperCase() + property.slice(1);
|
||||
|
||||
var i = 0;
|
||||
while (i < VENDOR_PREFIXES.length) {
|
||||
prefix = VENDOR_PREFIXES[i];
|
||||
prop = (prefix) ? prefix + camelProp : property;
|
||||
|
||||
if (prop in obj) {
|
||||
return prop;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* get a unique id
|
||||
* @returns {number} uniqueId
|
||||
*/
|
||||
var _uniqueId = 1;
|
||||
function uniqueId() {
|
||||
return _uniqueId++;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the window object of an element
|
||||
* @param {HTMLElement} element
|
||||
* @returns {DocumentView|Window}
|
||||
*/
|
||||
function getWindowForElement(element) {
|
||||
var doc = element.ownerDocument || element;
|
||||
return (doc.defaultView || doc.parentWindow || window);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
@import url(http://fonts.googleapis.com/css?family=Open+Sans);
|
||||
|
||||
*, *:after, *:before {
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
background: #eee;
|
||||
font: 13px/1.5em 'Open Sans', Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #4986e7;
|
||||
}
|
||||
|
||||
.bg1, .green { background: #42d692; }
|
||||
.bg2, .blue { background: #4986e7; }
|
||||
.bg3, .red { background: #d06b64; }
|
||||
.bg4, .purple { background: #cd74e6; }
|
||||
.bg5, .azure { background: #9fe1e7; }
|
||||
|
||||
body {
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.clear { clear: both; }
|
||||
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no">
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
Open the inspector and play a bit with the touchAction property.
|
||||
<script src="../../hammer.min.js"></script>
|
||||
<script>
|
||||
var mc = new Hammer(document.body);
|
||||
mc.add(new Hammer.Swipe({ direction: Hammer.DIRECTION_HORIZONTAL }));
|
||||
mc.add(new Hammer.Pan({ direction: Hammer.DIRECTION_HORIZONTAL }));
|
||||
|
||||
console.log(document.body.style.touchAction)
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
51
LittleShop/wwwroot/lib/hammerjs/tests/manual/input.html
Normal file
51
LittleShop/wwwroot/lib/hammerjs/tests/manual/input.html
Normal file
@@ -0,0 +1,51 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
|
||||
<meta name="msapplication-tap-highlight" content="no"/>
|
||||
<link rel="stylesheet" href="assets/style.css">
|
||||
<title>Hammer.js</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div id="hit" class="bg1" style="padding: 30px; height: 200px;">
|
||||
</div>
|
||||
|
||||
<pre id="debug" style="overflow:hidden; background: #eee; padding: 15px;"></pre>
|
||||
|
||||
<pre id="log" style="overflow:hidden;"></pre>
|
||||
</div>
|
||||
<script src="../../hammer.js"></script>
|
||||
<script>
|
||||
|
||||
Object.prototype.toDirString = function() {
|
||||
var output = [];
|
||||
for(var key in this) {
|
||||
if(this.hasOwnProperty(key)) {
|
||||
var value = this[key];
|
||||
if(Array.isArray(value)) {
|
||||
value = "Array("+ value.length +"):"+ value;
|
||||
} else if(value instanceof HTMLElement) {
|
||||
value = value +" ("+ value.outerHTML.substring(0, 50) +"...)";
|
||||
}
|
||||
output.push(key +": "+ value);
|
||||
}
|
||||
}
|
||||
return output.join("\n")
|
||||
};
|
||||
|
||||
var el = document.querySelector("#hit");
|
||||
var log = document.querySelector("#log");
|
||||
var debug = document.querySelector("#debug");
|
||||
|
||||
var mc = new Hammer(el);
|
||||
mc.get('pinch').set({ enable: true });
|
||||
|
||||
mc.on("hammer.input", function(ev) {
|
||||
debug.innerHTML = [ev.srcEvent.type, ev.pointers.length, ev.isFinal, ev.deltaX, ev.deltaY].join("<br>");
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
61
LittleShop/wwwroot/lib/hammerjs/tests/manual/log.html
Normal file
61
LittleShop/wwwroot/lib/hammerjs/tests/manual/log.html
Normal file
@@ -0,0 +1,61 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
|
||||
<link rel="stylesheet" href="assets/style.css">
|
||||
<title>Hammer.js</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
<div id="hit" class="bg1" style="padding: 30px;">
|
||||
<span id="target" class="bg5" style="display: block; height: 100px;"></span>
|
||||
</div>
|
||||
|
||||
<pre id="debug" style="overflow:hidden; background: #eee; padding: 15px;"></pre>
|
||||
|
||||
<pre id="log" style="overflow:hidden;"></pre>
|
||||
|
||||
</div>
|
||||
<script src="../../hammer.min.js"></script>
|
||||
<script>
|
||||
|
||||
Object.prototype.toDirString = function() {
|
||||
var output = [];
|
||||
for(var key in this) {
|
||||
if(this.hasOwnProperty(key)) {
|
||||
var value = this[key];
|
||||
if(Array.isArray(value)) {
|
||||
value = "Array("+ value.length +"):"+ value;
|
||||
} else if(value instanceof HTMLElement) {
|
||||
value = value +" ("+ value.outerHTML.substring(0, 50) +"...)";
|
||||
}
|
||||
output.push(key +": "+ value);
|
||||
}
|
||||
}
|
||||
return output.join("\n")
|
||||
};
|
||||
|
||||
|
||||
var el = document.querySelector("#hit");
|
||||
var log = document.querySelector("#log");
|
||||
var debug = document.querySelector("#debug");
|
||||
|
||||
var mc = new Hammer(el);
|
||||
mc.get('pinch').set({ enable: true });
|
||||
mc.get('rotate').set({ enable: true });
|
||||
mc.on("swipe pan panstart panmove panend pancancel multipan press pressup pinch rotate tap doubletap",
|
||||
logGesture);
|
||||
|
||||
function DEBUG(str) {
|
||||
debug.textContent = str;
|
||||
}
|
||||
function logGesture(ev) {
|
||||
console.log(ev.timeStamp, ev.type, ev);
|
||||
log.textContent = ev.toDirString();
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
73
LittleShop/wwwroot/lib/hammerjs/tests/manual/multiple.html
Normal file
73
LittleShop/wwwroot/lib/hammerjs/tests/manual/multiple.html
Normal file
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
|
||||
<link rel="stylesheet" href="assets/style.css">
|
||||
<title>Hammer.js</title>
|
||||
<style>
|
||||
|
||||
#right,
|
||||
#left {
|
||||
display: block;
|
||||
width: 50%;
|
||||
height: 500px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#left { float: left; }
|
||||
#right { float: right; }
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<pre id="left" class="bg1"></pre>
|
||||
<pre id="right" class="bg5"></pre>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<h1>Multiple instances the same time</h1>
|
||||
<p>You can run multiple instances of Hammer on your page and they will recognize each completely isolated
|
||||
from each other. This makes it possible to build multi-user interfaces.</p>
|
||||
|
||||
</div>
|
||||
<script src="../../hammer.min.js"></script>
|
||||
<script>
|
||||
|
||||
Object.prototype.toDirString = function() {
|
||||
var output = [];
|
||||
for(var key in this) {
|
||||
if(this.hasOwnProperty(key)) {
|
||||
var value = this[key];
|
||||
if(Array.isArray(value)) {
|
||||
value = "Array("+ value.length +"):"+ value;
|
||||
} else if(value instanceof HTMLElement) {
|
||||
value = value +" ("+ value.outerHTML.substring(0, 50) +"...)";
|
||||
}
|
||||
output.push(key +": "+ value);
|
||||
}
|
||||
}
|
||||
return output.join("\n")
|
||||
};
|
||||
|
||||
|
||||
function addHammer(el) {
|
||||
var mc = new Hammer(el, { multiUser: true });
|
||||
mc.get('pan').set({ direction: Hammer.DIRECTION_ALL });
|
||||
mc.get('swipe').set({ direction: Hammer.DIRECTION_ALL });
|
||||
mc.get('pinch').set({ enable: true });
|
||||
mc.get('rotate').set({ enable: true });
|
||||
|
||||
mc.on("swipe pan press pinch rotate tap doubletap", function (ev) {
|
||||
ev.preventDefault();
|
||||
el.innerText = ev.toDirString();
|
||||
});
|
||||
}
|
||||
|
||||
addHammer(document.querySelector("#left"));
|
||||
addHammer(document.querySelector("#right"));
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
217
LittleShop/wwwroot/lib/hammerjs/tests/manual/nested.html
Normal file
217
LittleShop/wwwroot/lib/hammerjs/tests/manual/nested.html
Normal file
@@ -0,0 +1,217 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
|
||||
<meta name="msapplication-tap-highlight" content="no"/>
|
||||
<link rel="stylesheet" href="assets/style.css">
|
||||
<title>Hammer.js</title>
|
||||
<style>
|
||||
|
||||
.container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.panes.wrapper {
|
||||
max-height: 400px;
|
||||
max-width: 800px;
|
||||
background: #666;
|
||||
margin: 40px auto;
|
||||
}
|
||||
|
||||
.panes {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.pane {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
text-align: center;
|
||||
font: bold 60px/250px 'Open Sans', Helvetica, Arial, sans-serif;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.panes.animate > .pane {
|
||||
transition: all .3s;
|
||||
-webkit-transition: all .3s;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="panes wrapper">
|
||||
<div class="pane bg1">
|
||||
<div class="panes">
|
||||
<div class="pane" style="background: rgba(0,0,0,0);">1.1</div>
|
||||
<div class="pane" style="background: rgba(0,0,0,.2);">1.2</div>
|
||||
<div class="pane" style="background: rgba(0,0,0,.4);">1.3</div>
|
||||
<div class="pane" style="background: rgba(0,0,0,.6);">1.4</div>
|
||||
<div class="pane" style="background: rgba(0,0,0,.8);">1.5</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pane bg2">
|
||||
<div class="panes">
|
||||
<div class="pane" style="background: rgba(0,0,0,0);">2.1</div>
|
||||
<div class="pane" style="background: rgba(0,0,0,.2);">2.2</div>
|
||||
<div class="pane" style="background: rgba(0,0,0,.4);">2.3</div>
|
||||
<div class="pane" style="background: rgba(0,0,0,.6);">2.4</div>
|
||||
<div class="pane" style="background: rgba(0,0,0,.8);">2.5</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pane bg3">
|
||||
<div class="panes">
|
||||
<div class="pane" style="background: rgba(0,0,0,0);">3.1</div>
|
||||
<div class="pane" style="background: rgba(0,0,0,.2);">3.2</div>
|
||||
<div class="pane" style="background: rgba(0,0,0,.4);">3.3</div>
|
||||
<div class="pane" style="background: rgba(0,0,0,.6);">3.4</div>
|
||||
<div class="pane" style="background: rgba(0,0,0,.8);">3.5</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pane bg4">
|
||||
<div class="panes">
|
||||
<div class="pane" style="background: rgba(0,0,0,0);">4.1</div>
|
||||
<div class="pane" style="background: rgba(0,0,0,.2);">4.2</div>
|
||||
<div class="pane" style="background: rgba(0,0,0,.4);">4.3</div>
|
||||
<div class="pane" style="background: rgba(0,0,0,.6);">4.4</div>
|
||||
<div class="pane" style="background: rgba(0,0,0,.8);">4.5</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pane bg5">
|
||||
<div class="panes">
|
||||
<div class="pane" style="background: rgba(0,0,0,0);">5.1</div>
|
||||
<div class="pane" style="background: rgba(0,0,0,.2);">5.2</div>
|
||||
<div class="pane" style="background: rgba(0,0,0,.4);">5.3</div>
|
||||
<div class="pane" style="background: rgba(0,0,0,.6);">5.4</div>
|
||||
<div class="pane" style="background: rgba(0,0,0,.8);">5.5</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<h1>Nested Pan recognizers</h1>
|
||||
|
||||
<p>Nested recognizers are possible with some threshold and with use of <code>requireFailure()</code>.</p>
|
||||
</div>
|
||||
|
||||
<script src="../../hammer.js"></script>
|
||||
<script>
|
||||
|
||||
var reqAnimationFrame = (function() {
|
||||
return window[Hammer.prefixed(window, "requestAnimationFrame")] || function(callback) {
|
||||
setTimeout(callback, 1000 / 60);
|
||||
}
|
||||
})();
|
||||
|
||||
function dirProp(direction, hProp, vProp) {
|
||||
return (direction & Hammer.DIRECTION_HORIZONTAL) ? hProp : vProp
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Carousel
|
||||
* @param container
|
||||
* @param direction
|
||||
* @constructor
|
||||
*/
|
||||
function HammerCarousel(container, direction) {
|
||||
this.container = container;
|
||||
this.direction = direction;
|
||||
|
||||
this.panes = Array.prototype.slice.call(this.container.children, 0);
|
||||
this.containerSize = this.container[dirProp(direction, 'offsetWidth', 'offsetHeight')];
|
||||
|
||||
this.currentIndex = 0;
|
||||
|
||||
this.hammer = new Hammer.Manager(this.container);
|
||||
this.hammer.add(new Hammer.Pan({ direction: this.direction, threshold: 10 }));
|
||||
this.hammer.on("panstart panmove panend pancancel", Hammer.bindFn(this.onPan, this));
|
||||
|
||||
this.show(this.currentIndex);
|
||||
}
|
||||
|
||||
|
||||
HammerCarousel.prototype = {
|
||||
/**
|
||||
* show a pane
|
||||
* @param {Number} showIndex
|
||||
* @param {Number} [percent] percentage visible
|
||||
* @param {Boolean} [animate]
|
||||
*/
|
||||
show: function(showIndex, percent, animate){
|
||||
showIndex = Math.max(0, Math.min(showIndex, this.panes.length - 1));
|
||||
percent = percent || 0;
|
||||
|
||||
var className = this.container.className;
|
||||
if(animate) {
|
||||
if(className.indexOf('animate') === -1) {
|
||||
this.container.className += ' animate';
|
||||
}
|
||||
} else {
|
||||
if(className.indexOf('animate') !== -1) {
|
||||
this.container.className = className.replace('animate', '').trim();
|
||||
}
|
||||
}
|
||||
|
||||
var paneIndex, pos, translate;
|
||||
for (paneIndex = 0; paneIndex < this.panes.length; paneIndex++) {
|
||||
pos = (this.containerSize / 100) * (((paneIndex - showIndex) * 100) + percent);
|
||||
if(this.direction & Hammer.DIRECTION_HORIZONTAL) {
|
||||
translate = 'translate3d(' + pos + 'px, 0, 0)';
|
||||
} else {
|
||||
translate = 'translate3d(0, ' + pos + 'px, 0)'
|
||||
}
|
||||
this.panes[paneIndex].style.transform = translate;
|
||||
this.panes[paneIndex].style.mozTransform = translate;
|
||||
this.panes[paneIndex].style.webkitTransform = translate;
|
||||
}
|
||||
|
||||
this.currentIndex = showIndex;
|
||||
},
|
||||
|
||||
/**
|
||||
* handle pan
|
||||
* @param {Object} ev
|
||||
*/
|
||||
onPan : function (ev) {
|
||||
var delta = dirProp(this.direction, ev.deltaX, ev.deltaY);
|
||||
var percent = (100 / this.containerSize) * delta;
|
||||
var animate = false;
|
||||
|
||||
if (ev.type == 'panend' || ev.type == 'pancancel') {
|
||||
if (Math.abs(percent) > 20 && ev.type == 'panend') {
|
||||
this.currentIndex += (percent < 0) ? 1 : -1;
|
||||
}
|
||||
percent = 0;
|
||||
animate = true;
|
||||
}
|
||||
|
||||
this.show(this.currentIndex, percent, animate);
|
||||
}
|
||||
};
|
||||
|
||||
// the horizontal pane scroller
|
||||
var outer = new HammerCarousel(document.querySelector(".panes.wrapper"), Hammer.DIRECTION_HORIZONTAL);
|
||||
|
||||
// each pane should contain a vertical pane scroller
|
||||
Hammer.each(document.querySelectorAll(".pane .panes"), function(container) {
|
||||
// setup the inner scroller
|
||||
var inner = new HammerCarousel(container, Hammer.DIRECTION_VERTICAL);
|
||||
|
||||
// only recognize the inner pan when the outer is failing.
|
||||
// they both have a threshold of some px
|
||||
outer.hammer.get('pan').requireFailure(inner.hammer.get('pan'));
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,100 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
|
||||
<link rel="stylesheet" href="assets/style.css">
|
||||
<title>Hammer.js</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
<div id="maps" style="height: 500px; margin-bottom: 20px;"></div>
|
||||
|
||||
<h1>Gestures simulator</h1>
|
||||
<p>Used for unit-testing Hammer.js. To test it on the Google Maps view, you should open your
|
||||
<a href="https://developer.chrome.com/devtools/docs/mobile-emulation#emulate-touch-events">
|
||||
Inspector and emulate a touch-screen.</a>
|
||||
Or just open it on your touch-device.</p>
|
||||
<p>Currently, it only triggers touchEvents.</p>
|
||||
</div>
|
||||
|
||||
<script src="../../node_modules/hammer-simulator/index.js"></script>
|
||||
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
|
||||
<script>
|
||||
|
||||
Simulator.events.touch.fakeSupport();
|
||||
|
||||
var el, map;
|
||||
var container = document.getElementById('maps');
|
||||
var program = [
|
||||
['pan', ['deltaX','deltaY']],
|
||||
['pinch', ['scale']],
|
||||
['tap', ['pos']],
|
||||
['swipe', ['deltaX','deltaY']],
|
||||
['pinch', ['pos','scale']],
|
||||
['pan', ['pos']],
|
||||
['rotate', ['pos','rotation']],
|
||||
['doubleTap', ['pos']],
|
||||
['pinchRotate', ['pos','scale','rotation']],
|
||||
];
|
||||
|
||||
function randomRange(min, max) {
|
||||
return Math.random() * (max - min) + min;
|
||||
}
|
||||
|
||||
function randomRangeInt(min, max) {
|
||||
return Math.round(randomRange(min, max));
|
||||
}
|
||||
|
||||
function gestureOption(name) {
|
||||
var max = map.getDiv().offsetWidth * .9;
|
||||
switch(name) {
|
||||
case 'deltaY':
|
||||
case 'deltaX':
|
||||
return randomRangeInt(10, max * .5);
|
||||
case 'pos':
|
||||
return [randomRangeInt(10, max), randomRangeInt(10, max)];
|
||||
case 'scale':
|
||||
return randomRange(.2, 2);
|
||||
case 'rotation':
|
||||
return randomRange(-180, 180);
|
||||
}
|
||||
}
|
||||
|
||||
function walkProgram(done) {
|
||||
var clone = [].concat(program);
|
||||
(function next() {
|
||||
if(clone.length) {
|
||||
var entry = clone.shift();
|
||||
var options = {};
|
||||
for(var i=0; i<entry[1].length; i++) {
|
||||
options[entry[1][i]] = gestureOption(entry[1][i]);
|
||||
}
|
||||
Simulator.gestures[entry[0]](el, options, next);
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
}());
|
||||
}
|
||||
|
||||
function startSimulator() {
|
||||
walkProgram(startSimulator);
|
||||
}
|
||||
|
||||
(function setupGoogleMaps() {
|
||||
map = new google.maps.Map(container, {
|
||||
zoom: 14,
|
||||
center: new google.maps.LatLng(51.98, 5.91)
|
||||
});
|
||||
|
||||
// collect the target element
|
||||
google.maps.event.addListenerOnce(map, 'idle', function(){
|
||||
el = container.childNodes[0].childNodes[0];
|
||||
startSimulator();
|
||||
});
|
||||
})();
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
118
LittleShop/wwwroot/lib/hammerjs/tests/manual/simulator.html
Normal file
118
LittleShop/wwwroot/lib/hammerjs/tests/manual/simulator.html
Normal file
@@ -0,0 +1,118 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
|
||||
<link rel="stylesheet" href="assets/style.css">
|
||||
<title>Hammer.js</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<div id="hit" class="bg4" style="padding: 30px; height: 300px; position: relative;">
|
||||
</div>
|
||||
|
||||
<pre id="debug" style="overflow:hidden; background: #eee; padding: 15px;"></pre>
|
||||
|
||||
<pre id="log" style="overflow:hidden;"></pre>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="../../node_modules/hammer-simulator/index.js"></script>
|
||||
<script src="../../hammer.js"></script>
|
||||
<script>
|
||||
|
||||
var program = [
|
||||
['pan', ['deltaX','deltaY']],
|
||||
['pinch', ['scale']],
|
||||
['tap', ['pos']],
|
||||
['swipe', ['deltaX','deltaY']],
|
||||
['pinch', ['pos','scale']],
|
||||
['pan', ['pos']],
|
||||
['rotate', ['pos','rotation']],
|
||||
['doubleTap', ['pos']],
|
||||
['pinchRotate', ['pos','scale','rotation']],
|
||||
];
|
||||
|
||||
function randomRange(min, max) {
|
||||
return Math.random() * (max - min) + min;
|
||||
}
|
||||
|
||||
function randomRangeInt(min, max) {
|
||||
return Math.round(randomRange(min, max));
|
||||
}
|
||||
|
||||
function gestureOption(name) {
|
||||
var max = el.offsetWidth * .9;
|
||||
switch(name) {
|
||||
case 'deltaY':
|
||||
case 'deltaX':
|
||||
return randomRangeInt(10, max * .5);
|
||||
case 'pos':
|
||||
return [randomRangeInt(10, max), randomRangeInt(10, max)];
|
||||
case 'scale':
|
||||
return randomRange(.2, 2);
|
||||
case 'rotation':
|
||||
return randomRange(-180, 180);
|
||||
}
|
||||
}
|
||||
|
||||
function walkProgram(done) {
|
||||
var clone = [].concat(program);
|
||||
(function next() {
|
||||
if(clone.length) {
|
||||
var entry = clone.shift();
|
||||
var options = {};
|
||||
for(var i=0; i<entry[1].length; i++) {
|
||||
options[entry[1][i]] = gestureOption(entry[1][i]);
|
||||
}
|
||||
setTimeout(function() {
|
||||
log.innerHTML = '';
|
||||
Simulator.gestures[entry[0]](el, options, next);
|
||||
}, 1000);
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
}());
|
||||
}
|
||||
|
||||
function startSimulator() {
|
||||
walkProgram(startSimulator);
|
||||
}
|
||||
|
||||
|
||||
var el = document.querySelector("#hit");
|
||||
var log = document.querySelector("#log");
|
||||
var debug = document.querySelector("#debug");
|
||||
|
||||
var mc = new Hammer(el);
|
||||
mc.get('pinch').set({ enable: true, threshold:.1 });
|
||||
mc.get('rotate').set({ enable: true });
|
||||
mc.on("swipe pan multipan press pinch rotate tap doubletap", logGesture);
|
||||
|
||||
function logGesture(ev) {
|
||||
log.textContent = ev.toDirString();
|
||||
}
|
||||
|
||||
Object.prototype.toDirString = function() {
|
||||
var output = [];
|
||||
for(var key in this) {
|
||||
if(this.hasOwnProperty(key)) {
|
||||
var value = this[key];
|
||||
if(Array.isArray(value)) {
|
||||
value = "Array("+ value.length +"):"+ value;
|
||||
} else if(value instanceof HTMLElement) {
|
||||
value = value +" ("+ value.outerHTML.substring(0, 50) +"...)";
|
||||
}
|
||||
output.push(key +": "+ value);
|
||||
}
|
||||
}
|
||||
return output.join("\n")
|
||||
};
|
||||
|
||||
startSimulator();
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,91 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<link rel="stylesheet" href="assets/style.css">
|
||||
<title>Hammer.js</title>
|
||||
|
||||
<style>
|
||||
.tester {
|
||||
margin: 20px 0;
|
||||
padding: 10px;
|
||||
height: 200px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scroll-space {
|
||||
height: 9000px;
|
||||
}
|
||||
|
||||
#native, #no-native {
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
font-size: 1.1em;
|
||||
padding: 10px 20px;
|
||||
display: none;
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.show {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
<p>Hammer provides a <a href="../../src/touchaction.js">kind of polyfill</a>
|
||||
for the browsers that don't support the <a href="http://www.w3.org/TR/pointerevents/#the-touch-action-css-property">touch-action</a> property.</p>
|
||||
|
||||
<div id="native" class="green">Your browser has support for the touch-action property!</div>
|
||||
<div id="no-native" class="red">Your browser doesn't support the touch-action property,
|
||||
so we use the polyfill.</div>
|
||||
|
||||
<h2>touch-action: auto</h2>
|
||||
<p>Should prevent nothing.</p>
|
||||
<div class="tester azure" id="auto"></div>
|
||||
|
||||
<h2>touch-action: pan-y</h2>
|
||||
<p>Should prevent scrolling on horizontal movement. This is set by default when creating a Hammer instance.</p>
|
||||
<div class="tester azure" id="pan-y"></div>
|
||||
|
||||
<h2>touch-action: pan-x</h2>
|
||||
<p>Should prevent scrolling on vertical movement.</p>
|
||||
<div class="tester azure" id="pan-x"></div>
|
||||
|
||||
<h2>touch-action: pan-x pan-y</h2>
|
||||
<p>Should <strong>not</strong> prevent any scrolling on any movement. Horizontal and vertical scrolling handled by the browser directly.</p>
|
||||
<div class="tester azure" id="pan-x-pan-y"></div>
|
||||
|
||||
<h2>touch-action: none</h2>
|
||||
<p>Should prevent all.</p>
|
||||
<div class="tester azure" id="none"></div>
|
||||
</div>
|
||||
<script src="../../hammer.js"></script>
|
||||
<script>
|
||||
var support = Hammer.prefixed(document.body.style, 'touchAction');
|
||||
document.getElementById(support ? 'native' : 'no-native').className += ' show';
|
||||
|
||||
var touchActions = ['auto', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'];
|
||||
Hammer.each(touchActions, function(touchAction) {
|
||||
var el = document.getElementById(touchAction.replace(" ", "-"));
|
||||
|
||||
var mc = Hammer(el, {
|
||||
touchAction: touchAction
|
||||
});
|
||||
mc.get('pan').set({ direction: Hammer.DIRECTION_ALL });
|
||||
mc.get('pinch').set({ enable: true });
|
||||
mc.get('rotate').set({ enable: true });
|
||||
|
||||
mc.on("pan swipe rotate pinch tap doubletap press", function(ev) {
|
||||
el.textContent = ev.type +" "+ el.textContent;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="scroll-space"></div>
|
||||
<p>hi.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
211
LittleShop/wwwroot/lib/hammerjs/tests/manual/visual.html
Normal file
211
LittleShop/wwwroot/lib/hammerjs/tests/manual/visual.html
Normal file
@@ -0,0 +1,211 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
|
||||
<link rel="stylesheet" href="assets/style.css">
|
||||
<title>Hammer.js</title>
|
||||
|
||||
<style>
|
||||
|
||||
html, body {
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
-webkit-perspective: 500;
|
||||
-moz-perspective: 500;
|
||||
perspective: 500;
|
||||
}
|
||||
|
||||
.animate {
|
||||
-webkit-transition: all .3s;
|
||||
-moz-transition: all .3s;
|
||||
transition: all .3s;
|
||||
}
|
||||
|
||||
#hit {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#log {
|
||||
position: absolute;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="log"></div>
|
||||
<div id="hit" style="background: #42d692; width: 150px; height: 150px;"></div>
|
||||
|
||||
|
||||
<script src="../../hammer.js"></script>
|
||||
<script>
|
||||
|
||||
var reqAnimationFrame = (function () {
|
||||
return window[Hammer.prefixed(window, 'requestAnimationFrame')] || function (callback) {
|
||||
window.setTimeout(callback, 1000 / 60);
|
||||
};
|
||||
})();
|
||||
|
||||
var log = document.querySelector("#log");
|
||||
var el = document.querySelector("#hit");
|
||||
|
||||
var START_X = Math.round((window.innerWidth - el.offsetWidth) / 2);
|
||||
var START_Y = Math.round((window.innerHeight - el.offsetHeight) / 2);
|
||||
|
||||
var ticking = false;
|
||||
var transform;
|
||||
var timer;
|
||||
|
||||
var mc = new Hammer.Manager(el);
|
||||
|
||||
mc.add(new Hammer.Pan({ threshold: 0, pointers: 0 }));
|
||||
|
||||
mc.add(new Hammer.Swipe()).recognizeWith(mc.get('pan'));
|
||||
mc.add(new Hammer.Rotate({ threshold: 0 })).recognizeWith(mc.get('pan'));
|
||||
mc.add(new Hammer.Pinch({ threshold: 0 })).recognizeWith([mc.get('pan'), mc.get('rotate')]);
|
||||
|
||||
mc.add(new Hammer.Tap({ event: 'doubletap', taps: 2 }));
|
||||
mc.add(new Hammer.Tap());
|
||||
|
||||
mc.on("panstart panmove", onPan);
|
||||
mc.on("rotatestart rotatemove", onRotate);
|
||||
mc.on("pinchstart pinchmove", onPinch);
|
||||
mc.on("swipe", onSwipe);
|
||||
mc.on("tap", onTap);
|
||||
mc.on("doubletap", onDoubleTap);
|
||||
|
||||
mc.on("hammer.input", function(ev) {
|
||||
if(ev.isFinal) {
|
||||
resetElement();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function resetElement() {
|
||||
el.className = 'animate';
|
||||
transform = {
|
||||
translate: { x: START_X, y: START_Y },
|
||||
scale: 1,
|
||||
angle: 0,
|
||||
rx: 0,
|
||||
ry: 0,
|
||||
rz: 0
|
||||
};
|
||||
|
||||
requestElementUpdate();
|
||||
|
||||
if (log.textContent.length > 2000) {
|
||||
log.textContent = log.textContent.substring(0, 2000) + "...";
|
||||
}
|
||||
}
|
||||
|
||||
function updateElementTransform() {
|
||||
var value = [
|
||||
'translate3d(' + transform.translate.x + 'px, ' + transform.translate.y + 'px, 0)',
|
||||
'scale(' + transform.scale + ', ' + transform.scale + ')',
|
||||
'rotate3d('+ transform.rx +','+ transform.ry +','+ transform.rz +','+ transform.angle + 'deg)'
|
||||
];
|
||||
|
||||
value = value.join(" ");
|
||||
el.textContent = value;
|
||||
el.style.webkitTransform = value;
|
||||
el.style.mozTransform = value;
|
||||
el.style.transform = value;
|
||||
ticking = false;
|
||||
}
|
||||
|
||||
function requestElementUpdate() {
|
||||
if(!ticking) {
|
||||
reqAnimationFrame(updateElementTransform);
|
||||
ticking = true;
|
||||
}
|
||||
}
|
||||
|
||||
function logEvent(str) {
|
||||
//log.insertBefore(document.createTextNode(str +"\n"), log.firstChild);
|
||||
}
|
||||
|
||||
function onPan(ev) {
|
||||
el.className = '';
|
||||
transform.translate = {
|
||||
x: START_X + ev.deltaX,
|
||||
y: START_Y + ev.deltaY
|
||||
};
|
||||
|
||||
requestElementUpdate();
|
||||
logEvent(ev.type);
|
||||
}
|
||||
|
||||
var initScale = 1;
|
||||
function onPinch(ev) {
|
||||
if(ev.type == 'pinchstart') {
|
||||
initScale = transform.scale || 1;
|
||||
}
|
||||
|
||||
el.className = '';
|
||||
transform.scale = initScale * ev.scale;
|
||||
|
||||
requestElementUpdate();
|
||||
logEvent(ev.type);
|
||||
}
|
||||
|
||||
var initAngle = 0;
|
||||
function onRotate(ev) {
|
||||
if(ev.type == 'rotatestart') {
|
||||
initAngle = transform.angle || 0;
|
||||
}
|
||||
|
||||
el.className = '';
|
||||
transform.rz = 1;
|
||||
transform.angle = initAngle + ev.rotation;
|
||||
requestElementUpdate();
|
||||
logEvent(ev.type);
|
||||
}
|
||||
|
||||
function onSwipe(ev) {
|
||||
var angle = 50;
|
||||
transform.ry = (ev.direction & Hammer.DIRECTION_HORIZONTAL) ? 1 : 0;
|
||||
transform.rx = (ev.direction & Hammer.DIRECTION_VERTICAL) ? 1 : 0;
|
||||
transform.angle = (ev.direction & (Hammer.DIRECTION_RIGHT | Hammer.DIRECTION_UP)) ? angle : -angle;
|
||||
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(function () {
|
||||
resetElement();
|
||||
}, 300);
|
||||
requestElementUpdate();
|
||||
logEvent(ev.type);
|
||||
}
|
||||
|
||||
function onTap(ev) {
|
||||
transform.rx = 1;
|
||||
transform.angle = 25;
|
||||
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(function () {
|
||||
resetElement();
|
||||
}, 200);
|
||||
requestElementUpdate();
|
||||
logEvent(ev.type);
|
||||
}
|
||||
|
||||
function onDoubleTap(ev) {
|
||||
transform.rx = 1;
|
||||
transform.angle = 80;
|
||||
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(function () {
|
||||
resetElement();
|
||||
}, 500);
|
||||
requestElementUpdate();
|
||||
logEvent(ev.type);
|
||||
}
|
||||
|
||||
resetElement();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
5447
LittleShop/wwwroot/lib/hammerjs/tests/unit/assets/blanket.js
Normal file
5447
LittleShop/wwwroot/lib/hammerjs/tests/unit/assets/blanket.js
Normal file
File diff suppressed because one or more lines are too long
4
LittleShop/wwwroot/lib/hammerjs/tests/unit/assets/jquery.min.js
vendored
Normal file
4
LittleShop/wwwroot/lib/hammerjs/tests/unit/assets/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
7157
LittleShop/wwwroot/lib/hammerjs/tests/unit/assets/lodash.compat.js
Normal file
7157
LittleShop/wwwroot/lib/hammerjs/tests/unit/assets/lodash.compat.js
Normal file
File diff suppressed because it is too large
Load Diff
237
LittleShop/wwwroot/lib/hammerjs/tests/unit/assets/qunit.css
Normal file
237
LittleShop/wwwroot/lib/hammerjs/tests/unit/assets/qunit.css
Normal file
@@ -0,0 +1,237 @@
|
||||
/*!
|
||||
* QUnit 1.14.0
|
||||
* http://qunitjs.com/
|
||||
*
|
||||
* Copyright 2013 jQuery Foundation and other contributors
|
||||
* Released under the MIT license
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* Date: 2014-01-31T16:40Z
|
||||
*/
|
||||
|
||||
/** Font Family and Sizes */
|
||||
|
||||
#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
|
||||
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
|
||||
#qunit-tests { font-size: smaller; }
|
||||
|
||||
|
||||
/** Resets */
|
||||
|
||||
#qunit-tests, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
/** Header */
|
||||
|
||||
#qunit-header {
|
||||
padding: 0.5em 0 0.5em 1em;
|
||||
|
||||
color: #8699A4;
|
||||
background-color: #0D3349;
|
||||
|
||||
font-size: 1.5em;
|
||||
line-height: 1em;
|
||||
font-weight: 400;
|
||||
|
||||
border-radius: 5px 5px 0 0;
|
||||
}
|
||||
|
||||
#qunit-header a {
|
||||
text-decoration: none;
|
||||
color: #C2CCD1;
|
||||
}
|
||||
|
||||
#qunit-header a:hover,
|
||||
#qunit-header a:focus {
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
#qunit-testrunner-toolbar label {
|
||||
display: inline-block;
|
||||
padding: 0 0.5em 0 0.1em;
|
||||
}
|
||||
|
||||
#qunit-banner {
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
#qunit-testrunner-toolbar {
|
||||
padding: 0.5em 0 0.5em 2em;
|
||||
color: #5E740B;
|
||||
background-color: #EEE;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#qunit-userAgent {
|
||||
padding: 0.5em 0 0.5em 2.5em;
|
||||
background-color: #2B81AF;
|
||||
color: #FFF;
|
||||
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
|
||||
}
|
||||
|
||||
#qunit-modulefilter-container {
|
||||
float: right;
|
||||
}
|
||||
|
||||
/** Tests: Pass/Fail */
|
||||
|
||||
#qunit-tests {
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
#qunit-tests li {
|
||||
padding: 0.4em 0.5em 0.4em 2.5em;
|
||||
border-bottom: 1px solid #FFF;
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#qunit-tests li strong {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#qunit-tests li a {
|
||||
padding: 0.5em;
|
||||
color: #C2CCD1;
|
||||
text-decoration: none;
|
||||
}
|
||||
#qunit-tests li a:hover,
|
||||
#qunit-tests li a:focus {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#qunit-tests li .runtime {
|
||||
float: right;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.qunit-assert-list {
|
||||
margin-top: 0.5em;
|
||||
padding: 0.5em;
|
||||
|
||||
background-color: #FFF;
|
||||
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.qunit-collapsed {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#qunit-tests table {
|
||||
border-collapse: collapse;
|
||||
margin-top: 0.2em;
|
||||
}
|
||||
|
||||
#qunit-tests th {
|
||||
text-align: right;
|
||||
vertical-align: top;
|
||||
padding: 0 0.5em 0 0;
|
||||
}
|
||||
|
||||
#qunit-tests td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#qunit-tests pre {
|
||||
margin: 0;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
#qunit-tests del {
|
||||
background-color: #E0F2BE;
|
||||
color: #374E0C;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#qunit-tests ins {
|
||||
background-color: #FFCACA;
|
||||
color: #500;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/*** Test Counts */
|
||||
|
||||
#qunit-tests b.counts { color: #000; }
|
||||
#qunit-tests b.passed { color: #5E740B; }
|
||||
#qunit-tests b.failed { color: #710909; }
|
||||
|
||||
#qunit-tests li li {
|
||||
padding: 5px;
|
||||
background-color: #FFF;
|
||||
border-bottom: none;
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
/*** Passing Styles */
|
||||
|
||||
#qunit-tests li li.pass {
|
||||
color: #3C510C;
|
||||
background-color: #FFF;
|
||||
border-left: 10px solid #C6E746;
|
||||
}
|
||||
|
||||
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
|
||||
#qunit-tests .pass .test-name { color: #366097; }
|
||||
|
||||
#qunit-tests .pass .test-actual,
|
||||
#qunit-tests .pass .test-expected { color: #999; }
|
||||
|
||||
#qunit-banner.qunit-pass { background-color: #C6E746; }
|
||||
|
||||
/*** Failing Styles */
|
||||
|
||||
#qunit-tests li li.fail {
|
||||
color: #710909;
|
||||
background-color: #FFF;
|
||||
border-left: 10px solid #EE5757;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
#qunit-tests > li:last-child {
|
||||
border-radius: 0 0 5px 5px;
|
||||
}
|
||||
|
||||
#qunit-tests .fail { color: #000; background-color: #EE5757; }
|
||||
#qunit-tests .fail .test-name,
|
||||
#qunit-tests .fail .module-name { color: #000; }
|
||||
|
||||
#qunit-tests .fail .test-actual { color: #EE5757; }
|
||||
#qunit-tests .fail .test-expected { color: #008000; }
|
||||
|
||||
#qunit-banner.qunit-fail { background-color: #EE5757; }
|
||||
|
||||
|
||||
/** Result */
|
||||
|
||||
#qunit-testresult {
|
||||
padding: 0.5em 0.5em 0.5em 2.5em;
|
||||
|
||||
color: #2B81AF;
|
||||
background-color: #D2E0E6;
|
||||
|
||||
border-bottom: 1px solid #FFF;
|
||||
}
|
||||
#qunit-testresult .module-name {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/** Fixture */
|
||||
|
||||
#qunit-fixture {
|
||||
position: absolute;
|
||||
top: -10000px;
|
||||
left: -10000px;
|
||||
width: 1000px;
|
||||
height: 1000px;
|
||||
}
|
||||
2288
LittleShop/wwwroot/lib/hammerjs/tests/unit/assets/qunit.js
Normal file
2288
LittleShop/wwwroot/lib/hammerjs/tests/unit/assets/qunit.js
Normal file
File diff suppressed because it is too large
Load Diff
50
LittleShop/wwwroot/lib/hammerjs/tests/unit/assets/utils.js
Normal file
50
LittleShop/wwwroot/lib/hammerjs/tests/unit/assets/utils.js
Normal file
@@ -0,0 +1,50 @@
|
||||
var utils = {
|
||||
/**
|
||||
* trigger simple dom event
|
||||
* @param obj
|
||||
* @param name
|
||||
*/
|
||||
triggerDomEvent: function(obj, name) {
|
||||
var event = document.createEvent('Event');
|
||||
event.initEvent(name, true, true);
|
||||
obj.dispatchEvent(event);
|
||||
},
|
||||
|
||||
|
||||
createTouchEvent: function(name, x, y, identifier) {
|
||||
var event = document.createEvent('Event');
|
||||
event.initEvent('touch' + name, true, true);
|
||||
|
||||
event.touches = event.targetTouches = [{
|
||||
clientX: x,
|
||||
clientY: y,
|
||||
identifier: identifier || 0
|
||||
}];
|
||||
|
||||
//https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent.changedTouches
|
||||
event.changedTouches = [{
|
||||
clientX: x,
|
||||
clientY: y,
|
||||
identifier: identifier || 0
|
||||
}];
|
||||
|
||||
return event;
|
||||
},
|
||||
|
||||
dispatchTouchEvent: function(el, name, x, y, identifier) {
|
||||
var event = utils.createTouchEvent(name, x, y, identifier);
|
||||
el.dispatchEvent(event);
|
||||
},
|
||||
|
||||
createHitArea: function(parent) {
|
||||
if (parent == null) {
|
||||
parent = document.getElementById('qunit-fixture')
|
||||
}
|
||||
var hitArea = document.createElement('div');
|
||||
hitArea.style.background = '#eee';
|
||||
hitArea.style.height = '300px';
|
||||
|
||||
parent.appendChild(hitArea);
|
||||
return hitArea;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,63 @@
|
||||
var el,
|
||||
hammer;
|
||||
|
||||
module('Pan Gesture', {
|
||||
setup: function() {
|
||||
el = document.createElement('div');
|
||||
document.body.appendChild(el);
|
||||
|
||||
hammer = new Hammer(el, {recognizers: []});
|
||||
},
|
||||
teardown: function() {
|
||||
document.body.removeChild(el);
|
||||
hammer.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
test('`panstart` and `panmove` should be recognized', function() {
|
||||
expect(2);
|
||||
|
||||
var panMoveCount = 0;
|
||||
var pan = new Hammer.Pan({threshold: 1});
|
||||
|
||||
hammer.add(pan);
|
||||
hammer.on('panstart', function() {
|
||||
ok(true);
|
||||
});
|
||||
hammer.on('panmove', function() {
|
||||
panMoveCount++;
|
||||
});
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
utils.dispatchTouchEvent(el, 'move', 70, 50);
|
||||
utils.dispatchTouchEvent(el, 'move', 90, 50);
|
||||
|
||||
equal(panMoveCount, 1);
|
||||
});
|
||||
|
||||
asyncTest('Pan event flow should be start -> left -> end', function() {
|
||||
expect(1);
|
||||
var pan = new Hammer.Pan({threshold: 1});
|
||||
hammer.add(pan);
|
||||
|
||||
var eventflow = "";
|
||||
var isCalledPanleft = false;
|
||||
hammer.on('panstart', function() {
|
||||
eventflow += "start";
|
||||
});
|
||||
hammer.on('panleft', function() {
|
||||
if(!isCalledPanleft){
|
||||
isCalledPanleft = true;
|
||||
eventflow += "left";
|
||||
}
|
||||
});
|
||||
hammer.on('panend', function() {
|
||||
eventflow += "end";
|
||||
isCalledPanleft = true;
|
||||
});
|
||||
|
||||
Simulator.gestures.pan(el, { deltaX: -100, deltaY: 0 }, function() {
|
||||
equal(eventflow,"startleftend");
|
||||
start();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
var el,
|
||||
hammer;
|
||||
|
||||
module('Pinch Gesture', {
|
||||
setup: function() {
|
||||
el = document.createElement('div');
|
||||
document.body.appendChild(el);
|
||||
|
||||
hammer = new Hammer(el, {recognizers: []});
|
||||
},
|
||||
teardown: function() {
|
||||
document.body.removeChild(el);
|
||||
hammer.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
asyncTest('Pinch event flow should be start -> in -> end', function() {
|
||||
expect(1);
|
||||
var pinch = new Hammer.Pinch({enable: true, threshold: .1});
|
||||
hammer.add(pinch);
|
||||
|
||||
var eventflow = "";
|
||||
var isFiredPinchin = false;
|
||||
hammer.on('pinchstart', function() {
|
||||
eventflow += "start";
|
||||
});
|
||||
hammer.on('pinchin', function() {
|
||||
if(!isFiredPinchin){
|
||||
isFiredPinchin = true;
|
||||
eventflow += "in";
|
||||
}
|
||||
});
|
||||
hammer.on('pinchend', function() {
|
||||
eventflow += "end";
|
||||
isFiredPinchin = false;
|
||||
});
|
||||
|
||||
Simulator.gestures.pinch(el, { duration: 500, scale: .5 }, function() {
|
||||
equal(eventflow,"startinend");
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
var el,
|
||||
hammer,
|
||||
swipeCount = 0;
|
||||
|
||||
module('Swipe Gesture', {
|
||||
setup: function() {
|
||||
el = utils.createHitArea();
|
||||
hammer = new Hammer(el, {recognizers: []});
|
||||
swipeCount = 0;
|
||||
},
|
||||
teardown: function() {
|
||||
hammer.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
test('swipe can be recognized', function() {
|
||||
expect(1);
|
||||
|
||||
var swipe = new Hammer.Swipe({threshold: 1});
|
||||
hammer.add(swipe);
|
||||
hammer.on('swipe', function() {
|
||||
ok(true);
|
||||
start();
|
||||
});
|
||||
|
||||
stop();
|
||||
|
||||
Simulator.gestures.swipe(el);
|
||||
});
|
||||
43
LittleShop/wwwroot/lib/hammerjs/tests/unit/index.html
Normal file
43
LittleShop/wwwroot/lib/hammerjs/tests/unit/index.html
Normal file
@@ -0,0 +1,43 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title>Tests</title>
|
||||
<link rel="stylesheet" href="assets/qunit.css">
|
||||
|
||||
<script src="assets/jquery.min.js"></script>
|
||||
<script src="assets/lodash.compat.js"></script>
|
||||
<script src="assets/qunit.js"></script>
|
||||
<!--[if !IE]> --><script src="assets/blanket.js"></script><!-- <![endif]-->
|
||||
<script src="assets/utils.js"></script>
|
||||
|
||||
<script src="../../node_modules/hammer-simulator/index.js"></script>
|
||||
<script>
|
||||
Simulator.setType('touch');
|
||||
Simulator.events.touch.fakeSupport();
|
||||
</script>
|
||||
|
||||
<script src="../build.js" data-cover></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="qunit"></div>
|
||||
<div id="qunit-fixture"></div>
|
||||
|
||||
<script src="test_utils.js"></script>
|
||||
<script src="test_enable.js"></script>
|
||||
<script src="test_hammer.js"></script>
|
||||
<script src="test_events.js"></script>
|
||||
<script src="test_nested_gesture_recognizers.js"></script>
|
||||
<script src="test_simultaneous_recognition.js"></script>
|
||||
<script src="test_propagation_bubble.js"></script>
|
||||
<script src="test_gestures.js"></script>
|
||||
<script src="test_multiple_taps.js"></script>
|
||||
<script src="test_require_failure.js"></script>
|
||||
|
||||
<script src="test_jquery_plugin.js"></script>
|
||||
<script src="gestures/test_pan.js"></script>
|
||||
<script src="gestures/test_pinch.js"></script>
|
||||
<script src="gestures/test_swipe.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
171
LittleShop/wwwroot/lib/hammerjs/tests/unit/test_enable.js
Normal file
171
LittleShop/wwwroot/lib/hammerjs/tests/unit/test_enable.js
Normal file
@@ -0,0 +1,171 @@
|
||||
var el,
|
||||
hammer,
|
||||
counter;
|
||||
|
||||
module('Test recognizer enable', {
|
||||
setup: function() {
|
||||
el = utils.createHitArea();
|
||||
hammer = new Hammer.Manager(el, {recognizers: []});
|
||||
counter = 0;
|
||||
},
|
||||
teardown: function() {
|
||||
hammer && hammer.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
test('should disable a recognizer through the `enable` constructor parameter', function() {
|
||||
expect(1);
|
||||
hammer.add(new Hammer.Tap({enable: false}));
|
||||
hammer.on('tap', function() {
|
||||
counter++;
|
||||
});
|
||||
|
||||
stop();
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
utils.dispatchTouchEvent(el, 'end', 50, 50);
|
||||
|
||||
setTimeout(function() {
|
||||
start();
|
||||
equal(counter, 0);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
test('should disable recognizing when the manager is disabled.', function() {
|
||||
expect(1);
|
||||
hammer.set({ enable: false });
|
||||
hammer.add(new Hammer.Tap());
|
||||
hammer.on('tap', function() {
|
||||
counter++;
|
||||
});
|
||||
|
||||
stop();
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
utils.dispatchTouchEvent(el, 'end', 50, 50);
|
||||
|
||||
setTimeout(function() {
|
||||
start();
|
||||
equal(counter, 0);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
test('should toggle a recognizer using the `set` call to the recognizer enable property', function() {
|
||||
expect(2);
|
||||
|
||||
hammer.add(new Hammer.Tap());
|
||||
hammer.on('tap', function() {
|
||||
counter++;
|
||||
});
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
utils.dispatchTouchEvent(el, 'end', 50, 50);
|
||||
equal(counter, 1);
|
||||
|
||||
hammer.get('tap').set({ enable: false });
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
utils.dispatchTouchEvent(el, 'end', 50, 50);
|
||||
equal(counter, 1);
|
||||
});
|
||||
|
||||
test('should accept the `enable` constructor parameter as function', function() {
|
||||
expect(2);
|
||||
|
||||
var canRecognizeTap = false;
|
||||
|
||||
var tap = new Hammer.Tap({
|
||||
enable: function() {
|
||||
return canRecognizeTap;
|
||||
}
|
||||
});
|
||||
|
||||
hammer.add(tap);
|
||||
hammer.on('tap', function() {
|
||||
counter++;
|
||||
});
|
||||
|
||||
stop();
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
utils.dispatchTouchEvent(el, 'end', 50, 50);
|
||||
|
||||
setTimeout(function() {
|
||||
start();
|
||||
equal(counter, 0);
|
||||
|
||||
canRecognizeTap = true;
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
utils.dispatchTouchEvent(el, 'end', 50, 50);
|
||||
|
||||
equal(counter, 1);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
test('should accept a function parameter with `set`', function() {
|
||||
expect(3);
|
||||
|
||||
hammer.add(new Hammer.Tap());
|
||||
hammer.on('tap', function() {
|
||||
counter++;
|
||||
});
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
utils.dispatchTouchEvent(el, 'end', 50, 50);
|
||||
equal(counter, 1);
|
||||
|
||||
var canRecognizeTap = false;
|
||||
hammer.get('tap').set({ enable: function() {
|
||||
return canRecognizeTap;
|
||||
}});
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
utils.dispatchTouchEvent(el, 'end', 50, 50);
|
||||
equal(counter, 1);
|
||||
|
||||
canRecognizeTap = true;
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
utils.dispatchTouchEvent(el, 'end', 50, 50);
|
||||
equal(counter, 2);
|
||||
});
|
||||
|
||||
test('should pass the recognizer and optional the input parameter to the `enable` callback', function() {
|
||||
expect(2);
|
||||
|
||||
var tap;
|
||||
|
||||
// the enable function is called initially to setup the touch-action property
|
||||
// at that moment there isnt any input
|
||||
var canEnable = function(recognizer, input) {
|
||||
equal(recognizer, tap);
|
||||
return true;
|
||||
};
|
||||
tap = new Hammer.Tap({enable: canEnable});
|
||||
hammer.add(tap);
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
});
|
||||
|
||||
test('should toggle based on other object method', function() {
|
||||
expect(2);
|
||||
|
||||
var view = {
|
||||
state: 0,
|
||||
canRecognizeTap: function(recognizer, input) {
|
||||
return this.state !== 0;
|
||||
}
|
||||
};
|
||||
|
||||
hammer.add(new Hammer.Tap({enable: function(rec, input) { return view.canRecognizeTap(rec, input); } }));
|
||||
hammer.on('tap', function() {
|
||||
counter++;
|
||||
});
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
utils.dispatchTouchEvent(el, 'end', 50, 50);
|
||||
equal(counter, 0);
|
||||
|
||||
view.state = 1;
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
utils.dispatchTouchEvent(el, 'end', 50, 50);
|
||||
equal(counter, 1);
|
||||
});
|
||||
61
LittleShop/wwwroot/lib/hammerjs/tests/unit/test_events.js
Normal file
61
LittleShop/wwwroot/lib/hammerjs/tests/unit/test_events.js
Normal file
@@ -0,0 +1,61 @@
|
||||
module('eventEmitter');
|
||||
|
||||
test('test the eventemitter', function() {
|
||||
expect(6);
|
||||
|
||||
var ee = new Hammer.Manager(utils.createHitArea());
|
||||
var inputData = {
|
||||
target: document.body,
|
||||
srcEvent: {
|
||||
preventDefault: function() {
|
||||
ok(true, 'preventDefault ref');
|
||||
},
|
||||
target: document.body
|
||||
}
|
||||
};
|
||||
|
||||
function event3Handler() {
|
||||
ok(true, 'emitted event3');
|
||||
}
|
||||
|
||||
ee.on('testEvent1', function() {
|
||||
ok(true, 'emitted event');
|
||||
});
|
||||
ee.on('testEvent2', function(ev) {
|
||||
ok(true, 'emitted event');
|
||||
ev.preventDefault();
|
||||
ok(ev.target === document.body, 'target is the body');
|
||||
});
|
||||
ee.on('testEvent3', event3Handler);
|
||||
|
||||
ee.emit('testEvent1', inputData);
|
||||
ee.emit('testEvent2', inputData);
|
||||
ee.emit('testEvent3', inputData);
|
||||
|
||||
// unbind testEvent2
|
||||
ee.off('testEvent2');
|
||||
ee.off('testEvent3', event3Handler);
|
||||
|
||||
ee.emit('testEvent1', inputData); // should trigger testEvent1 again
|
||||
ee.emit('testEvent2', inputData); // doenst trigger a thing
|
||||
ee.emit('testEvent3', inputData); // doenst trigger a thing
|
||||
|
||||
// destroy
|
||||
ee.destroy();
|
||||
|
||||
ee.emit('testEvent1', inputData); // doenst trigger a thing
|
||||
ee.emit('testEvent2', inputData); // doenst trigger a thing
|
||||
ee.emit('testEvent3', inputData); // doenst trigger a thing
|
||||
});
|
||||
|
||||
/*
|
||||
* Hammer.Manager.off method : exception handling
|
||||
*/
|
||||
test("When Hammer.Manager didn't attach an event, 'off' method is ignored", function() {
|
||||
var count = 0;
|
||||
hammer = new Hammer(el, { inputTarget: document.body });
|
||||
hammer.off("swipeleft", function(e) {
|
||||
count++;
|
||||
});
|
||||
ok(true, "nothing");
|
||||
});
|
||||
208
LittleShop/wwwroot/lib/hammerjs/tests/unit/test_gestures.js
Normal file
208
LittleShop/wwwroot/lib/hammerjs/tests/unit/test_gestures.js
Normal file
@@ -0,0 +1,208 @@
|
||||
// TODO: this tests fails because tapRecognizer changes
|
||||
// it could be that tapRecognizer setup its BEGAN state and
|
||||
// disable the other gesture recognition
|
||||
var el, hammer, events;
|
||||
var allGestureEvents = [
|
||||
'tap doubletap press',
|
||||
'pinch pinchin pinchout pinchstart pinchmove pinchend pinchcancel',
|
||||
'rotate rotatestart rotatemove rotateend rotatecancel',
|
||||
'pan panstart panmove panup pandown panleft panright panend pancancel',
|
||||
'swipe swipeleft swiperight swipeup swipedown'
|
||||
].join(' ');
|
||||
|
||||
module('Gesture recognition', {
|
||||
setup: function() {
|
||||
el = utils.createHitArea();
|
||||
hammer = new Hammer(el);
|
||||
hammer.get('pinch')
|
||||
.set({ // some threshold, since the simulator doesnt stays at scale:1 when rotating
|
||||
enable: true,
|
||||
threshold: .1
|
||||
});
|
||||
|
||||
hammer.get('rotate')
|
||||
.set({ enable: true });
|
||||
|
||||
hammer.on(allGestureEvents, function(ev) {
|
||||
events[ev.type] = true;
|
||||
});
|
||||
events = {};
|
||||
},
|
||||
teardown: function() {
|
||||
hammer && hammer.destroy();
|
||||
events = null;
|
||||
}
|
||||
});
|
||||
|
||||
asyncTest('recognize pan', function() {
|
||||
expect(1);
|
||||
|
||||
Simulator.gestures.pan(el, { duration: 500, deltaX: 100, deltaY: 0 }, function() {
|
||||
start();
|
||||
deepEqual(events, {
|
||||
pan: true,
|
||||
panstart: true,
|
||||
panmove: true,
|
||||
panright: true,
|
||||
panend: true
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('recognize press', function() {
|
||||
expect(1);
|
||||
|
||||
Simulator.gestures.press(el, null, function() {
|
||||
start();
|
||||
deepEqual(events, {
|
||||
press: true
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('recognize swipe', function() {
|
||||
expect(1);
|
||||
|
||||
Simulator.gestures.swipe(el, { duration: 300, deltaX: 400, deltaY: 0 }, function() {
|
||||
start();
|
||||
deepEqual(events, {
|
||||
pan: true,
|
||||
panstart: true,
|
||||
panmove: true,
|
||||
panright: true,
|
||||
panend: true,
|
||||
swipe: true,
|
||||
swiperight: true
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('recognize pinch', function() {
|
||||
expect(1);
|
||||
|
||||
Simulator.gestures.pinch(el, { duration: 500, scale: .5 }, function() {
|
||||
start();
|
||||
deepEqual(events, {
|
||||
pinch: true,
|
||||
pinchstart: true,
|
||||
pinchmove: true,
|
||||
pinchend: true,
|
||||
pinchin: true
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('recognize children multitouch pinch', function() {
|
||||
expect(1);
|
||||
|
||||
var el1 = utils.createHitArea(el),
|
||||
el2 = utils.createHitArea(el);
|
||||
|
||||
Simulator.gestures.pinch([el1, el2], { duration: 500, scale: .5 }, function() {
|
||||
start();
|
||||
deepEqual(events, {
|
||||
pinch: true,
|
||||
pinchstart: true,
|
||||
pinchmove: true,
|
||||
pinchend: true,
|
||||
pinchin: true
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('recognize parent-child multitouch pinch', function() {
|
||||
expect(1);
|
||||
|
||||
var el1 = utils.createHitArea(el);
|
||||
|
||||
Simulator.gestures.pinch([el, el1], { duration: 100, scale: .5 }, function() {
|
||||
start();
|
||||
deepEqual(events, {
|
||||
pinch: true,
|
||||
pinchstart: true,
|
||||
pinchmove: true,
|
||||
pinchend: true,
|
||||
pinchin: true
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('recognize rotate', function() {
|
||||
expect(1);
|
||||
|
||||
Simulator.gestures.rotate(el, { duration: 500, scale: 1 }, function() {
|
||||
start();
|
||||
deepEqual(events, {
|
||||
rotate: true,
|
||||
rotatestart: true,
|
||||
rotatemove: true,
|
||||
rotateend: true
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('recognize multitouch rotate', function() {
|
||||
expect(1);
|
||||
|
||||
var el1 = utils.createHitArea(el);
|
||||
|
||||
Simulator.gestures.rotate([el, el1], { duration: 500, scale: 1 }, function() {
|
||||
start();
|
||||
deepEqual(events, {
|
||||
rotate: true,
|
||||
rotatestart: true,
|
||||
rotatemove: true,
|
||||
rotateend: true
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('recognize rotate and pinch simultaneous', function() {
|
||||
expect(1);
|
||||
|
||||
Simulator.gestures.pinchRotate(el, { duration: 500, scale: 2 }, function() {
|
||||
start();
|
||||
deepEqual(events, {
|
||||
rotate: true,
|
||||
rotatestart: true,
|
||||
rotatemove: true,
|
||||
rotateend: true,
|
||||
pinch: true,
|
||||
pinchstart: true,
|
||||
pinchmove: true,
|
||||
pinchend: true,
|
||||
pinchout: true
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('don\'t recognize pan and swipe when moving down, when only horizontal is allowed', function() {
|
||||
expect(1);
|
||||
|
||||
Simulator.gestures.swipe(el, { duration: 250, deltaX: 0, deltaZ: 200 }, function() {
|
||||
start();
|
||||
deepEqual(events, { });
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('don\'t recognize press if duration is too short.', function() {
|
||||
expect(1);
|
||||
|
||||
Simulator.gestures.press(el, { duration: 240 });
|
||||
|
||||
setTimeout(function() {
|
||||
start();
|
||||
deepEqual(events, { tap: true }, 'Tap gesture has been recognized.');
|
||||
}, 275);
|
||||
});
|
||||
|
||||
asyncTest('don\'t recognize tap if duration is too long.', function() {
|
||||
expect(1);
|
||||
|
||||
Simulator.gestures.tap(el, { duration: 255 });
|
||||
|
||||
setTimeout(function() {
|
||||
start();
|
||||
deepEqual(events, { press: true }, 'Press gesture has been recognized.');
|
||||
}, 275);
|
||||
});
|
||||
187
LittleShop/wwwroot/lib/hammerjs/tests/unit/test_hammer.js
Normal file
187
LittleShop/wwwroot/lib/hammerjs/tests/unit/test_hammer.js
Normal file
@@ -0,0 +1,187 @@
|
||||
var el, el2,
|
||||
hammer, hammer2;
|
||||
|
||||
module('Tests', {
|
||||
setup: function() {
|
||||
el = utils.createHitArea();
|
||||
el2 = utils.createHitArea();
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
if (hammer) {
|
||||
hammer.destroy();
|
||||
hammer = null;
|
||||
}
|
||||
if (hammer2) {
|
||||
hammer2.destroy();
|
||||
hammer2 = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('hammer shortcut', function() {
|
||||
expect(2);
|
||||
|
||||
Hammer.defaults.touchAction = 'pan-y';
|
||||
hammer = Hammer(el);
|
||||
|
||||
ok(hammer instanceof Hammer.Manager, 'returns an instance of Manager');
|
||||
ok(hammer.touchAction.actions == Hammer.defaults.touchAction, 'set the default touchAction');
|
||||
});
|
||||
|
||||
test('hammer shortcut with options', function() {
|
||||
expect(2);
|
||||
|
||||
hammer = Hammer(el, {
|
||||
touchAction: 'none'
|
||||
});
|
||||
ok(hammer instanceof Hammer.Manager, 'returns an instance of Manager');
|
||||
ok(hammer.touchAction.actions == 'none', 'set the default touchAction');
|
||||
});
|
||||
|
||||
/* Creating a hammer instance does not work on the same way
|
||||
* when using Hammer or Hammer.Manager.
|
||||
*
|
||||
* This can confuse developers who read tests to use the library when doc is missing.
|
||||
*/
|
||||
test('Hammer and Hammer.Manager constructors work exactly on the same way.', function() {
|
||||
expect(2);
|
||||
|
||||
hammer = new Hammer(el, {});
|
||||
equal(Hammer.defaults.preset.length, hammer.recognizers.length);
|
||||
|
||||
hammer2 = new Hammer.Manager(el, {});
|
||||
equal(0, hammer2.recognizers.length);
|
||||
});
|
||||
|
||||
/* DOC to disable default recognizers should be added.
|
||||
*
|
||||
* - Hammer(el). IMO: Currently, well done.
|
||||
* - Hammer(el, {}) . IMO: should disable default recognizers
|
||||
* - Hammer(el, {recognizers: null}). IMO: now, it fails.
|
||||
* - Hammer(el, {recognizers: []}). It works, but it is likely not intuitive.
|
||||
*/
|
||||
test('A Hammer instance can be setup to not having default recognizers.', function() {
|
||||
expect(1);
|
||||
|
||||
hammer = new Hammer(el, { recognizers: false });
|
||||
equal(0, hammer.recognizers.length);
|
||||
});
|
||||
|
||||
/* The case was when I added a custom tap event which was added to the default
|
||||
* recognizers, and my custom tap gesture wasn't working (I do not know exactly the reason),
|
||||
* but removing the default recognizers solved the issue.
|
||||
*/
|
||||
test('Adding the same recognizer type should remove the old recognizer', function() {
|
||||
expect(4);
|
||||
|
||||
hammer = new Hammer(el);
|
||||
|
||||
ok(!!hammer.get('tap'));
|
||||
equal(7, hammer.recognizers.length);
|
||||
|
||||
var newTap = new Hammer.Tap({time: 1337});
|
||||
hammer.add(newTap);
|
||||
|
||||
equal(7, hammer.recognizers.length);
|
||||
equal(1337, hammer.get('tap').options.time);
|
||||
});
|
||||
|
||||
/*
|
||||
* Swipe gesture:
|
||||
* - in this tests, it does not update input.velocity ( always 0)
|
||||
* - does not fire swipeleft or swiperight events
|
||||
*/
|
||||
asyncTest('Swiping to the left should fire swipeleft event', function() {
|
||||
expect(2);
|
||||
|
||||
hammer = new Hammer(el, {recognizers: []});
|
||||
hammer.add(new Hammer.Swipe());
|
||||
hammer.on('swipe swipeleft', function() {
|
||||
ok(true);
|
||||
});
|
||||
|
||||
Simulator.gestures.swipe(el, {pos: [300, 300], deltaY: 0, deltaX: -200}, function() {
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
* Input target change
|
||||
*/
|
||||
asyncTest('Should detect input while on other element', function() {
|
||||
expect(1);
|
||||
|
||||
hammer = new Hammer(el, { inputTarget: document.body });
|
||||
hammer.on('tap', function() {
|
||||
ok(true);
|
||||
});
|
||||
|
||||
Simulator.gestures.tap(document.body, null, function() {
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
/* Hammer.Manager constructor accepts a "recognizers" option in which each
|
||||
* element is an array representation of a Recognizer.
|
||||
*/
|
||||
test('Hammer.Manager accepts recognizers as arrays.', function() {
|
||||
expect(4);
|
||||
|
||||
hammer = new Hammer.Manager(el, {
|
||||
recognizers: [
|
||||
[Hammer.Swipe],
|
||||
[Hammer.Pinch],
|
||||
[Hammer.Rotate],
|
||||
[Hammer.Pan, { direction: Hammer.DIRECTION_UP }, ['swipe', 'pinch'], ['rotate']]
|
||||
]
|
||||
});
|
||||
equal(4, hammer.recognizers.length);
|
||||
|
||||
var recognizerActual = hammer.recognizers[3];
|
||||
equal(recognizerActual.options.direction, Hammer.DIRECTION_UP);
|
||||
equal(2, Object.keys(recognizerActual.simultaneous).length);
|
||||
equal(1, recognizerActual.requireFail.length);
|
||||
});
|
||||
|
||||
/*
|
||||
* Removing a recognizer which cannot be found would errantly remove the last recognizer in the
|
||||
* manager's list.
|
||||
*/
|
||||
test('Remove non-existent recognizer.', function() {
|
||||
expect(1);
|
||||
|
||||
hammer = new Hammer(el, {recognizers: []});
|
||||
hammer.add(new Hammer.Swipe());
|
||||
hammer.remove('tap');
|
||||
|
||||
equal(1, hammer.recognizers.length);
|
||||
});
|
||||
|
||||
test('check whether Hammer.defaults.cssProps is restored', function() {
|
||||
var beforeCssProps = {
|
||||
userSelect: 'text',
|
||||
touchSelect: 'grippers',
|
||||
touchCallout: 'default',
|
||||
contentZooming: 'chained',
|
||||
userDrag: 'element',
|
||||
tapHighlightColor: 'rgba(0, 1, 0, 0)'
|
||||
};
|
||||
var prop;
|
||||
Hammer.each(Hammer.defaults.cssProps, function(value, name) {
|
||||
prop = Hammer.prefixed(el.style, name);
|
||||
if (prop) {
|
||||
el.style[prop] = beforeCssProps[name];
|
||||
}
|
||||
});
|
||||
|
||||
hammer = Hammer(el);
|
||||
hammer.destroy();
|
||||
hammer = null;
|
||||
Hammer.each(Hammer.defaults.cssProps, function(value, name) {
|
||||
prop = Hammer.prefixed(el.style, name);
|
||||
if (prop) {
|
||||
equal(el.style[prop], beforeCssProps[name], "check if " + name + " is restored");
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,59 @@
|
||||
var el, hammer, events;
|
||||
|
||||
var jQueryPluginPath = '../../node_modules/jquery-hammerjs/jquery.hammer.js';
|
||||
|
||||
module('jQuery plugin', {
|
||||
setup: function() {
|
||||
el = utils.createHitArea();
|
||||
events = {};
|
||||
},
|
||||
teardown: function() {
|
||||
hammer && hammer.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
asyncTest('trigger pan with jQuery', function() {
|
||||
expect(2);
|
||||
|
||||
$.getScript(jQueryPluginPath, function() {
|
||||
jQuery(el).hammer();
|
||||
jQuery(el).bind('panstart pan panmove panright panend', function(ev) {
|
||||
if (ev.gesture) {
|
||||
events[ev.type] = true;
|
||||
}
|
||||
});
|
||||
|
||||
Simulator.gestures.pan(el, { deltaX: 50, deltaY: 0 }, function() {
|
||||
start();
|
||||
deepEqual(events, {
|
||||
pan: true,
|
||||
panstart: true,
|
||||
panmove: true,
|
||||
panright: true,
|
||||
panend: true
|
||||
});
|
||||
|
||||
ok(jQuery(el).data('hammer') instanceof Hammer.Manager, 'data attribute refers to the instance');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('trigger pan without jQuery should still work', function() {
|
||||
expect(1);
|
||||
|
||||
var hammer = Hammer(el);
|
||||
hammer.on('panstart pan panmove panright panend', function(ev) {
|
||||
events[ev.type] = true;
|
||||
});
|
||||
|
||||
Simulator.gestures.pan(el, { deltaX: 50, deltaY: 0 }, function() {
|
||||
start();
|
||||
deepEqual(events, {
|
||||
pan: true,
|
||||
panstart: true,
|
||||
panmove: true,
|
||||
panright: true,
|
||||
panend: true
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,90 @@
|
||||
var el, hammer;
|
||||
|
||||
var tripleTapCount = 0,
|
||||
doubleTapCount = 0,
|
||||
tapCount = 0;
|
||||
|
||||
module('Tap delay', {
|
||||
setup: function() {
|
||||
el = utils.createHitArea();
|
||||
hammer = new Hammer(el, {recognizers: []});
|
||||
|
||||
var tap = new Hammer.Tap();
|
||||
var doubleTap = new Hammer.Tap({event: 'doubleTap', taps: 2 });
|
||||
var tripleTap = new Hammer.Tap({event: 'tripleTap', taps: 3 });
|
||||
|
||||
hammer.add([tripleTap, doubleTap, tap]);
|
||||
|
||||
tripleTap.recognizeWith([doubleTap, tap]);
|
||||
doubleTap.recognizeWith(tap);
|
||||
|
||||
doubleTap.requireFailure(tripleTap);
|
||||
tap.requireFailure([tripleTap, doubleTap]);
|
||||
|
||||
tripleTapCount = 0;
|
||||
doubleTapCount = 0;
|
||||
tapCount = 0;
|
||||
|
||||
hammer.on('tap', function() {
|
||||
tapCount++;
|
||||
});
|
||||
hammer.on('doubleTap', function() {
|
||||
doubleTapCount++;
|
||||
});
|
||||
hammer.on('tripleTap', function() {
|
||||
tripleTapCount++;
|
||||
});
|
||||
},
|
||||
teardown: function() {
|
||||
hammer.destroy();
|
||||
}
|
||||
});
|
||||
asyncTest('When a tripleTap is fired, doubleTap and Tap should not be recognized', function() {
|
||||
expect(3);
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
utils.dispatchTouchEvent(el, 'end', 50, 50);
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
utils.dispatchTouchEvent(el, 'end', 50, 50);
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
utils.dispatchTouchEvent(el, 'end', 50, 50);
|
||||
|
||||
setTimeout(function() {
|
||||
start();
|
||||
equal(tripleTapCount, 1, 'one tripletap event');
|
||||
equal(doubleTapCount, 0, 'no doubletap event');
|
||||
equal(tapCount, 0, 'no singletap event');
|
||||
}, 350);
|
||||
});
|
||||
asyncTest('When a doubleTap is fired, tripleTap and Tap should not be recognized', function() {
|
||||
expect(3);
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
utils.dispatchTouchEvent(el, 'end', 50, 50);
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
utils.dispatchTouchEvent(el, 'end', 50, 50);
|
||||
|
||||
setTimeout(function() {
|
||||
start();
|
||||
equal(tripleTapCount, 0);
|
||||
equal(doubleTapCount, 1);
|
||||
equal(tapCount, 0);
|
||||
}, 350);
|
||||
});
|
||||
|
||||
asyncTest('When a tap is fired, tripleTap and doubleTap should not be recognized', function() {
|
||||
expect(3);
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
utils.dispatchTouchEvent(el, 'end', 50, 50);
|
||||
|
||||
setTimeout(function() {
|
||||
start();
|
||||
equal(tripleTapCount, 0);
|
||||
equal(doubleTapCount, 0);
|
||||
equal(tapCount, 1);
|
||||
}, 350);
|
||||
});
|
||||
@@ -0,0 +1,167 @@
|
||||
var parent,
|
||||
child,
|
||||
hammerChild,
|
||||
hammerParent;
|
||||
|
||||
module('Nested gesture recognizers (Tap Child + Pan Parent)', {
|
||||
setup: function() {
|
||||
parent = document.createElement('div');
|
||||
child = document.createElement('div');
|
||||
|
||||
document.getElementById('qunit-fixture').appendChild(parent);
|
||||
parent.appendChild(child);
|
||||
|
||||
hammerParent = new Hammer.Manager(parent, {
|
||||
touchAction: 'none'
|
||||
});
|
||||
hammerChild = new Hammer.Manager(child, {
|
||||
touchAction: 'none'
|
||||
});
|
||||
|
||||
hammerChild.add(new Hammer.Tap());
|
||||
hammerParent.add(new Hammer.Pan({threshold: 5, pointers: 1}));
|
||||
},
|
||||
teardown: function() {
|
||||
hammerChild.destroy();
|
||||
hammerParent.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
test('Tap on the child', function() {
|
||||
expect(1);
|
||||
|
||||
hammerChild.on('tap', function() {
|
||||
ok(true);
|
||||
});
|
||||
hammerParent.on('tap', function() {
|
||||
throw new Error('tap should not fire on parent');
|
||||
});
|
||||
|
||||
utils.dispatchTouchEvent(child, 'start', 0, 10);
|
||||
utils.dispatchTouchEvent(child, 'end', 0, 10);
|
||||
});
|
||||
|
||||
test('Panning on the child should fire parent pan and should not fire child tap event', function() {
|
||||
expect(1);
|
||||
|
||||
hammerChild.on('tap', function() {
|
||||
throw new Error('tap should not fire on parent');
|
||||
});
|
||||
hammerParent.on('panend', function() {
|
||||
ok(true);
|
||||
});
|
||||
|
||||
utils.dispatchTouchEvent(child, 'start', 10, 0);
|
||||
utils.dispatchTouchEvent(child, 'move', 20, 0);
|
||||
utils.dispatchTouchEvent(child, 'end', 30, 0);
|
||||
|
||||
});
|
||||
|
||||
/*
|
||||
// test (optional pointers validation)
|
||||
test('Panning with one finger down on child, other on parent', function () {
|
||||
expect(1);
|
||||
|
||||
var event,
|
||||
touches;
|
||||
|
||||
hammerParent.on('panend', function () {
|
||||
ok(true);
|
||||
});
|
||||
|
||||
// one finger one child
|
||||
utils.dispatchTouchEvent(child, 'start', 10, 0, 0);
|
||||
utils.dispatchTouchEvent(parent, 'start', 12, 0, 1);
|
||||
|
||||
touches = [
|
||||
{clientX: 20, clientY: 0, identifier: 0 },
|
||||
{clientX: 20, clientY: 0, identifier: 1 }
|
||||
];
|
||||
|
||||
event = document.createEvent('Event');
|
||||
event.initEvent('touchmove', true, true);
|
||||
event.touches = touches;
|
||||
event.changedTouches = touches;
|
||||
|
||||
parent.dispatchEvent(event);
|
||||
|
||||
touches = [
|
||||
{clientX: 30, clientY: 0, identifier: 0 },
|
||||
{clientX: 30, clientY: 0, identifier: 1 }
|
||||
];
|
||||
|
||||
event = document.createEvent('Event');
|
||||
event.initEvent('touchend', true, true);
|
||||
event.touches = touches;
|
||||
event.changedTouches = touches;
|
||||
|
||||
parent.dispatchEvent(event);
|
||||
});
|
||||
*/
|
||||
|
||||
var pressPeriod = 600;
|
||||
module('Nested gesture recognizers (Press Child + Pan Parent)', {
|
||||
setup: function() {
|
||||
parent = document.createElement('div');
|
||||
child = document.createElement('div');
|
||||
|
||||
document.getElementById('qunit-fixture').appendChild(parent);
|
||||
parent.appendChild(child);
|
||||
|
||||
hammerParent = new Hammer.Manager(parent, {
|
||||
touchAction: 'none'
|
||||
});
|
||||
hammerChild = new Hammer.Manager(child, {
|
||||
touchAction: 'none'
|
||||
});
|
||||
|
||||
hammerChild.add(new Hammer.Press({time: pressPeriod}));
|
||||
hammerParent.add(new Hammer.Pan({threshold: 5, pointers: 1}));
|
||||
},
|
||||
teardown: function() {
|
||||
hammerChild.destroy();
|
||||
hammerParent.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
test('Press on the child', function() {
|
||||
expect(1);
|
||||
|
||||
hammerChild.on('press', function() {
|
||||
ok(true);
|
||||
});
|
||||
hammerParent.on('press', function() {
|
||||
throw new Error('press should not fire on parent');
|
||||
});
|
||||
|
||||
utils.dispatchTouchEvent(child, 'start', 0, 10);
|
||||
|
||||
stop();
|
||||
|
||||
setTimeout(function() {
|
||||
start();
|
||||
}, pressPeriod);
|
||||
});
|
||||
|
||||
test('When Press is followed by Pan on the same element, both gestures are recognized', function() {
|
||||
expect(2);
|
||||
hammerChild.on('press', function() {
|
||||
ok(true);
|
||||
});
|
||||
hammerParent.on('panend', function() {
|
||||
ok(true);
|
||||
});
|
||||
|
||||
utils.dispatchTouchEvent(child, 'start', 0, 10);
|
||||
stop();
|
||||
|
||||
setTimeout(function() {
|
||||
start();
|
||||
|
||||
utils.dispatchTouchEvent(child, 'move', 10, 10);
|
||||
utils.dispatchTouchEvent(child, 'move', 20, 10);
|
||||
utils.dispatchTouchEvent(child, 'move', 30, 10);
|
||||
utils.dispatchTouchEvent(child, 'end', 30, 10);
|
||||
|
||||
}, pressPeriod);
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
var parent,
|
||||
child,
|
||||
hammerChild,
|
||||
hammerParent;
|
||||
|
||||
module('Propagation (Tap in Child and Parent)', {
|
||||
setup: function() {
|
||||
parent = document.createElement('div');
|
||||
child = document.createElement('div');
|
||||
|
||||
document.getElementById('qunit-fixture').appendChild(parent);
|
||||
parent.appendChild(child);
|
||||
|
||||
hammerParent = new Hammer.Manager(parent);
|
||||
hammerChild = new Hammer.Manager(child);
|
||||
|
||||
hammerChild.add(new Hammer.Tap());
|
||||
hammerParent.add(new Hammer.Tap());
|
||||
},
|
||||
teardown: function() {
|
||||
hammerChild.destroy();
|
||||
hammerParent.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
test('Tap on the child, fires also the tap event to the parent', function() {
|
||||
expect(2);
|
||||
|
||||
hammerChild.on('tap', function() {
|
||||
ok(true);
|
||||
});
|
||||
hammerParent.on('tap', function() {
|
||||
ok(true);
|
||||
});
|
||||
|
||||
utils.dispatchTouchEvent(child, 'start', 0, 10);
|
||||
utils.dispatchTouchEvent(child, 'end', 0, 10);
|
||||
});
|
||||
|
||||
test('When tap on the child and the child stops the input event propagation, the tap event does not get fired in the parent', function() {
|
||||
expect(1);
|
||||
|
||||
hammerChild.on('tap', function() {
|
||||
ok(true);
|
||||
});
|
||||
hammerParent.on('tap', function() {
|
||||
throw new Error('parent tap gesture should not be recognized');
|
||||
});
|
||||
|
||||
child.addEventListener('touchend', function(ev) {
|
||||
ev.stopPropagation();
|
||||
});
|
||||
|
||||
utils.dispatchTouchEvent(child, 'start', 0, 10);
|
||||
utils.dispatchTouchEvent(child, 'end', 0, 10);
|
||||
});
|
||||
@@ -0,0 +1,111 @@
|
||||
var el,
|
||||
hammer,
|
||||
pressPeriod = 200,
|
||||
pressThreshold = 20,
|
||||
pressCount = 0,
|
||||
panStartCount = 0,
|
||||
swipeCount = 0;
|
||||
|
||||
module('Require Failure ( Swipe & Press )', {
|
||||
setup: function() {
|
||||
el = utils.createHitArea();
|
||||
hammer = new Hammer(el, {recognizers: []});
|
||||
|
||||
var swipe = new Hammer.Swipe({threshold: 1});
|
||||
var press = new Hammer.Press({time: pressPeriod, threshold: pressThreshold});
|
||||
|
||||
hammer.add(swipe);
|
||||
hammer.add(press);
|
||||
|
||||
swipe.recognizeWith(press);
|
||||
press.requireFailure(swipe);
|
||||
|
||||
pressCount = 0;
|
||||
swipeCount = 0;
|
||||
hammer.on('press', function() {
|
||||
pressCount++;
|
||||
});
|
||||
hammer.on('swipe', function() {
|
||||
swipeCount++;
|
||||
});
|
||||
},
|
||||
teardown: function() {
|
||||
hammer.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
asyncTest('When swipe does not recognize the gesture, a press gesture can be fired', function() {
|
||||
expect(1);
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
|
||||
setTimeout(function() {
|
||||
start();
|
||||
equal(pressCount, 1);
|
||||
}, pressPeriod + 100);
|
||||
});
|
||||
|
||||
asyncTest('When swipe does recognize the gesture, a press gesture cannot be fired', function() {
|
||||
expect(2);
|
||||
|
||||
Simulator.gestures.swipe(el, null, function() {
|
||||
start();
|
||||
|
||||
ok(swipeCount > 0, 'swipe gesture should be recognizing');
|
||||
equal(pressCount, 0, 'press gesture should not be recognized because swipe gesture is recognizing');
|
||||
});
|
||||
});
|
||||
module('Require Failure ( Pan & Press )', {
|
||||
setup: function() {
|
||||
el = document.createElement('div');
|
||||
document.body.appendChild(el);
|
||||
|
||||
hammer = new Hammer(el, {recognizers: []});
|
||||
|
||||
var pan = new Hammer.Pan({threshold: 1});
|
||||
var press = new Hammer.Press({time: pressPeriod, threshold: pressThreshold});
|
||||
|
||||
hammer.add([pan, press]);
|
||||
|
||||
pan.recognizeWith(press);
|
||||
press.requireFailure(pan);
|
||||
|
||||
pressCount = 0;
|
||||
panStartCount = 0;
|
||||
hammer.on('press', function() {
|
||||
pressCount++;
|
||||
});
|
||||
hammer.on('panstart', function() {
|
||||
panStartCount++;
|
||||
});
|
||||
},
|
||||
teardown: function() {
|
||||
document.body.removeChild(el);
|
||||
hammer.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
asyncTest('When pan does not recognize the gesture, a press gesture can be fired', function() {
|
||||
expect(1);
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
|
||||
setTimeout(function() {
|
||||
start();
|
||||
equal(pressCount, 1);
|
||||
}, pressPeriod + 100);
|
||||
});
|
||||
|
||||
asyncTest('When pan recognizes the gesture, a press gesture cannot be fired', function() {
|
||||
expect(2);
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 50, 50);
|
||||
utils.dispatchTouchEvent(el, 'move', 50 + pressThreshold / 4, 50);
|
||||
|
||||
setTimeout(function() {
|
||||
start();
|
||||
|
||||
ok(panStartCount > 0, 'pan gesture should be recognizing');
|
||||
equal(pressCount, 0, 'press gesture should not be recognized because pan gesture is recognizing');
|
||||
}, pressPeriod + 100);
|
||||
});
|
||||
@@ -0,0 +1,234 @@
|
||||
var el,
|
||||
hammer;
|
||||
|
||||
module('Simultaenous recognition', {
|
||||
setup: function() {
|
||||
el = utils.createHitArea()
|
||||
},
|
||||
teardown: function() {
|
||||
hammer && hammer.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
asyncTest('should pinch and pan simultaneously be recognized when enabled', function() {
|
||||
expect(4);
|
||||
|
||||
var panCount = 0,
|
||||
pinchCount = 0;
|
||||
|
||||
hammer = new Hammer.Manager(el, {
|
||||
touchAction: 'none'
|
||||
});
|
||||
|
||||
hammer.add(new Hammer.Pan({threshold: 5, pointers: 2}));
|
||||
|
||||
var pinch = new Hammer.Pinch({ threshold: 0, pointers: 2});
|
||||
hammer.add(pinch);
|
||||
pinch.recognizeWith(hammer.get('pan'));
|
||||
|
||||
hammer.on('panend', function() {
|
||||
panCount++;
|
||||
});
|
||||
hammer.on('pinchend', function() {
|
||||
pinchCount++;
|
||||
});
|
||||
|
||||
var executeGesture = function(cb) {
|
||||
var event, touches;
|
||||
|
||||
touches = [
|
||||
{clientX: 0, clientY: 10, identifier: 0, target: el },
|
||||
{clientX: 10, clientY: 10, identifier: 1, target: el }
|
||||
];
|
||||
|
||||
event = document.createEvent('Event');
|
||||
event.initEvent('touchstart', true, true);
|
||||
event.touches = touches;
|
||||
event.targetTouches = touches;
|
||||
event.changedTouches = touches;
|
||||
el.dispatchEvent(event);
|
||||
|
||||
setTimeout(function() {
|
||||
touches = [
|
||||
{clientX: 10, clientY: 20, identifier: 0, target: el },
|
||||
{clientX: 20, clientY: 20, identifier: 1, target: el }
|
||||
];
|
||||
|
||||
event = document.createEvent('Event');
|
||||
event.initEvent('touchmove', true, true);
|
||||
event.touches = touches;
|
||||
event.targetTouches = touches;
|
||||
event.changedTouches = touches;
|
||||
|
||||
el.dispatchEvent(event);
|
||||
}, 100);
|
||||
|
||||
setTimeout(function() {
|
||||
touches = [
|
||||
{clientX: 20, clientY: 30, identifier: 0, target: el },
|
||||
{clientX: 40, clientY: 30, identifier: 1, target: el }
|
||||
];
|
||||
|
||||
event = document.createEvent('Event');
|
||||
event.initEvent('touchmove', true, true);
|
||||
event.touches = touches;
|
||||
event.targetTouches = touches;
|
||||
event.changedTouches = touches;
|
||||
el.dispatchEvent(event);
|
||||
|
||||
event = document.createEvent('Event');
|
||||
event.initEvent('touchend', true, true);
|
||||
event.touches = touches;
|
||||
event.targetTouches = touches;
|
||||
event.changedTouches = touches;
|
||||
el.dispatchEvent(event);
|
||||
|
||||
cb();
|
||||
}, 200);
|
||||
};
|
||||
|
||||
// 2 gesture will be recognized
|
||||
executeGesture(function() {
|
||||
equal(panCount, 1);
|
||||
equal(pinchCount, 1);
|
||||
|
||||
pinch.dropRecognizeWith(hammer.get('pan'));
|
||||
|
||||
// only the pan gesture will be recognized
|
||||
executeGesture(function() {
|
||||
equal(panCount, 2);
|
||||
equal(pinchCount, 1);
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('the first gesture should block the following gestures (Tap & DoubleTap)', function() {
|
||||
expect(4);
|
||||
|
||||
var tapCount = 0,
|
||||
doubleTapCount = 0;
|
||||
|
||||
hammer = new Hammer.Manager(el, {
|
||||
touchAction: 'none'
|
||||
});
|
||||
|
||||
var tap = new Hammer.Tap();
|
||||
var doubleTap = new Hammer.Tap({event: 'doubletap', taps: 2});
|
||||
|
||||
hammer.add(tap);
|
||||
hammer.add(doubleTap);
|
||||
|
||||
hammer.on('tap', function() {
|
||||
tapCount++;
|
||||
});
|
||||
hammer.on('doubletap', function() {
|
||||
doubleTapCount++;
|
||||
});
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 0, 10);
|
||||
utils.dispatchTouchEvent(el, 'end', 0, 10);
|
||||
utils.dispatchTouchEvent(el, 'start', 0, 10);
|
||||
utils.dispatchTouchEvent(el, 'end', 0, 10);
|
||||
|
||||
equal(tapCount, 2, 'on a double tap gesture, the tap gesture is recognized twice');
|
||||
equal(doubleTapCount, 0, 'double tap gesture is not recognized because the prior tap gesture does not recognize it simultaneously');
|
||||
|
||||
doubleTap.recognizeWith(hammer.get('tap'));
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 0, 10);
|
||||
utils.dispatchTouchEvent(el, 'end', 0, 10);
|
||||
utils.dispatchTouchEvent(el, 'start', 0, 10);
|
||||
utils.dispatchTouchEvent(el, 'end', 0, 10);
|
||||
|
||||
equal(tapCount, 4);
|
||||
equal(doubleTapCount, 1, 'when the tap gesture is configured to work simultaneously, tap & doubleTap can be recognized simultaneously');
|
||||
});
|
||||
|
||||
test('when disabled, the first gesture should not block gestures (Tap & DoubleTap )', function() {
|
||||
expect(4);
|
||||
|
||||
var tapCount = 0,
|
||||
doubleTapCount = 0;
|
||||
|
||||
hammer = new Hammer.Manager(el, {
|
||||
touchAction: 'none'
|
||||
});
|
||||
|
||||
var tap = new Hammer.Tap();
|
||||
var doubleTap = new Hammer.Tap({event: 'doubletap', taps: 2});
|
||||
|
||||
hammer.add(tap);
|
||||
hammer.add(doubleTap);
|
||||
|
||||
hammer.on('tap', function() {
|
||||
tapCount++;
|
||||
});
|
||||
hammer.on('doubletap', function() {
|
||||
doubleTapCount++;
|
||||
});
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 0, 10);
|
||||
utils.dispatchTouchEvent(el, 'end', 0, 10);
|
||||
utils.dispatchTouchEvent(el, 'start', 0, 10);
|
||||
utils.dispatchTouchEvent(el, 'end', 0, 10);
|
||||
|
||||
equal(tapCount, 2, 'on a double tap gesture, the tap gesture is recognized twice');
|
||||
equal(doubleTapCount, 0, 'double tap gesture is not recognized because the prior tap gesture does not recognize it simultaneously');
|
||||
|
||||
hammer.get('tap').set({ enable: false });
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 0, 10);
|
||||
utils.dispatchTouchEvent(el, 'end', 0, 10);
|
||||
utils.dispatchTouchEvent(el, 'start', 0, 10);
|
||||
utils.dispatchTouchEvent(el, 'end', 0, 10);
|
||||
|
||||
equal(tapCount, 2, 'tap gesture should not be recognized when the recognizer is disabled');
|
||||
equal(doubleTapCount, 1, 'when the tap gesture is disabled, doubleTap can be recognized');
|
||||
});
|
||||
|
||||
test('the first gesture should block the following gestures (DoubleTap & Tap)', function() {
|
||||
expect(4);
|
||||
|
||||
var tapCount = 0,
|
||||
doubleTapCount = 0;
|
||||
|
||||
hammer = new Hammer.Manager(el, {
|
||||
touchAction: 'none'
|
||||
});
|
||||
|
||||
var tap = new Hammer.Tap();
|
||||
var doubleTap = new Hammer.Tap({event: 'doubletap', taps: 2});
|
||||
|
||||
hammer.add(doubleTap);
|
||||
hammer.add(tap);
|
||||
|
||||
hammer.on('tap', function() {
|
||||
tapCount++;
|
||||
});
|
||||
hammer.on('doubletap', function() {
|
||||
doubleTapCount++;
|
||||
});
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 0, 10);
|
||||
utils.dispatchTouchEvent(el, 'end', 0, 10);
|
||||
utils.dispatchTouchEvent(el, 'start', 0, 10);
|
||||
utils.dispatchTouchEvent(el, 'end', 0, 10);
|
||||
|
||||
equal(doubleTapCount, 1, 'double tap is recognized');
|
||||
equal(tapCount, 1, 'tap is detected, the doubletap is only catched by the doubletap recognizer');
|
||||
|
||||
// doubletap and tap together
|
||||
doubleTap.recognizeWith(hammer.get('tap'));
|
||||
doubleTapCount = 0;
|
||||
tapCount = 0;
|
||||
|
||||
utils.dispatchTouchEvent(el, 'start', 0, 10);
|
||||
utils.dispatchTouchEvent(el, 'end', 0, 10);
|
||||
utils.dispatchTouchEvent(el, 'start', 0, 10);
|
||||
utils.dispatchTouchEvent(el, 'end', 0, 10);
|
||||
|
||||
equal(doubleTapCount, 1);
|
||||
equal(tapCount, 2, 'when the tap gesture is configured to work simultaneously, tap & doubleTap can be recognized simultaneously');
|
||||
});
|
||||
164
LittleShop/wwwroot/lib/hammerjs/tests/unit/test_utils.js
Normal file
164
LittleShop/wwwroot/lib/hammerjs/tests/unit/test_utils.js
Normal file
@@ -0,0 +1,164 @@
|
||||
module('utils');
|
||||
|
||||
// for the tests, all hammer properties and methods of Hammer are exposed to window.$H
|
||||
|
||||
test('get/set prefixed util', function() {
|
||||
ok(_.isUndefined($H.prefixed(window, 'FakeProperty')), 'non existent property returns undefined');
|
||||
|
||||
window.webkitFakeProperty = 1337;
|
||||
ok($H.prefixed(window, 'FakeProperty') == 'webkitFakeProperty', 'existent prefixed property returns the prefixed name');
|
||||
|
||||
delete window.webkitFakeProperty;
|
||||
});
|
||||
|
||||
test('fnBind', function() {
|
||||
var context = { a: true };
|
||||
|
||||
$H.bindFn(function(b) {
|
||||
ok(this.a === true, 'bindFn scope');
|
||||
ok(b === 123, 'bindFn argument');
|
||||
}, context)(123);
|
||||
});
|
||||
|
||||
test('Inherit objects', function() {
|
||||
function Base() {
|
||||
this.name = true;
|
||||
}
|
||||
|
||||
function Child() {
|
||||
Base.call(this);
|
||||
}
|
||||
|
||||
$H.inherit(Child, Base, {
|
||||
newMethod: function() {
|
||||
}
|
||||
});
|
||||
|
||||
var inst = new Child();
|
||||
|
||||
ok(inst.name == true, 'child has extended from base');
|
||||
ok(inst.newMethod, 'child has a new method');
|
||||
ok(Child.prototype.newMethod, 'child has a new prototype method');
|
||||
ok(inst instanceof Child, 'is instanceof Child');
|
||||
ok(inst instanceof Base, 'is instanceof Base');
|
||||
ok(inst._super === Base.prototype, '_super is ref to prototype of Base');
|
||||
});
|
||||
|
||||
test('toArray', function() {
|
||||
ok(_.isArray($H.toArray({ 0: true, 1: 'second', length: 2 })), 'converted an array-like object to an array');
|
||||
ok(_.isArray($H.toArray([true, true])), 'array stays an array');
|
||||
});
|
||||
|
||||
test('inArray', function() {
|
||||
ok($H.inArray([1, 2, 3, 4, 'hammer'], 'hammer') === 4, 'found item and returned the index');
|
||||
ok($H.inArray([1, 2, 3, 4, 'hammer'], 'notfound') === -1, 'not found an item and returned -1');
|
||||
ok($H.inArray([
|
||||
{id: 2},
|
||||
{id: 24}
|
||||
], '24', 'id') === 1, 'find by key and return the index');
|
||||
ok($H.inArray([
|
||||
{id: 2},
|
||||
{id: 24}
|
||||
], '22', 'id') === -1, 'not found by key and return -1');
|
||||
});
|
||||
|
||||
test('splitStr', function() {
|
||||
deepEqual($H.splitStr(' a b c d '), ['a', 'b', 'c', 'd'], 'str split valid');
|
||||
});
|
||||
|
||||
test('uniqueArray', function() {
|
||||
deepEqual($H.uniqueArray([
|
||||
{id: 1},
|
||||
{id: 2},
|
||||
{id: 2}
|
||||
], 'id'), [
|
||||
{id: 1},
|
||||
{id: 2}
|
||||
], 'remove duplicate ids')
|
||||
});
|
||||
|
||||
test('boolOrFn', function() {
|
||||
equal($H.boolOrFn(true), true, 'Passing an boolean');
|
||||
equal($H.boolOrFn(false), false, 'Passing an boolean');
|
||||
equal($H.boolOrFn(function() {
|
||||
return true;
|
||||
}), true, 'Passing an boolean');
|
||||
equal($H.boolOrFn(1), true, 'Passing an integer');
|
||||
});
|
||||
|
||||
test('hasParent', function() {
|
||||
var parent = document.createElement('div'),
|
||||
child = document.createElement('div');
|
||||
|
||||
document.body.appendChild(parent);
|
||||
parent.appendChild(child);
|
||||
|
||||
equal($H.hasParent(child, parent), true, 'Found parent');
|
||||
equal($H.hasParent(parent, child), false, 'Not in parent');
|
||||
|
||||
document.body.removeChild(parent);
|
||||
});
|
||||
|
||||
test('each', function() {
|
||||
var object = { hi: true };
|
||||
var array = ['a', 'b', 'c'];
|
||||
var loop;
|
||||
|
||||
loop = false;
|
||||
$H.each(object, function(value, key) {
|
||||
if (key == 'hi' && value === true) {
|
||||
loop = true;
|
||||
}
|
||||
});
|
||||
ok(loop, 'object loop');
|
||||
|
||||
loop = 0;
|
||||
$H.each(array, function(value, key) {
|
||||
if (value) {
|
||||
loop++;
|
||||
}
|
||||
});
|
||||
ok(loop == 3, 'array loop');
|
||||
|
||||
loop = 0;
|
||||
array.forEach = null;
|
||||
$H.each(array, function(value, key) {
|
||||
if (value) {
|
||||
loop++;
|
||||
}
|
||||
});
|
||||
ok(loop == 3, 'array loop without Array.forEach');
|
||||
});
|
||||
|
||||
test('assign', function() {
|
||||
expect(2);
|
||||
deepEqual(
|
||||
$H.assign(
|
||||
{a: 1, b: 3},
|
||||
{b: 2, c: 3}
|
||||
),
|
||||
{a: 1, b: 2, c: 3},
|
||||
'Simple extend'
|
||||
);
|
||||
|
||||
var src = { foo: true };
|
||||
var dest = $H.assign({}, src);
|
||||
src.foo = false;
|
||||
deepEqual(dest, {foo: true}, 'Clone reference');
|
||||
});
|
||||
|
||||
test('test add/removeEventListener', function() {
|
||||
function handleEvent() {
|
||||
ok(true, 'triggered event');
|
||||
}
|
||||
|
||||
expect(2);
|
||||
|
||||
$H.addEventListeners(window, 'testEvent1 testEvent2 ', handleEvent);
|
||||
utils.triggerDomEvent(window, 'testEvent1');
|
||||
utils.triggerDomEvent(window, 'testEvent2');
|
||||
|
||||
$H.removeEventListeners(window, ' testEvent1 testEvent2 ', handleEvent);
|
||||
utils.triggerDomEvent(window, 'testEvent1');
|
||||
utils.triggerDomEvent(window, 'testEvent2');
|
||||
});
|
||||
Reference in New Issue
Block a user