1
0
Fork 0
mirror of https://github.com/DanielnetoDotCom/YouPHPTube synced 2025-10-03 09:49:28 +02:00
Also check the lang in case insensitive
This commit is contained in:
Daniel 2022-03-14 14:28:38 -03:00
parent 33e7f7384e
commit 2a9630258f
22658 changed files with 3562773 additions and 3562767 deletions

6
node_modules/wow.js/.npmignore generated vendored
View file

@ -1,4 +1,4 @@
.DS_Store
.grunt/
node_modules/
.DS_Store
.grunt/
node_modules/
_SpecRunner.html

6
node_modules/wow.js/.travis.yml generated vendored
View file

@ -1,3 +1,3 @@
language: node_js
node_js:
- 6
language: node_js
node_js:
- 6

188
node_modules/wow.js/Gruntfile.js generated vendored
View file

@ -1,94 +1,94 @@
/*global module:false*/
module.exports = function(grunt) {
require('load-grunt-tasks')(grunt);
mainTasks = [
'eslint', 'babel', 'coffee', 'growl:coffee', 'uglify', 'jasmine',
'growl:jasmine',
]
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
eslint: {
target: ['src/WOW.js']
},
uglify: {
dist: {
files: {
'dist/wow.min.js': 'dist/wow.js'
}
},
options: {
banner : '/*! <%= pkg.title %> wow.js - v<%= pkg.version %> - ' +
'<%= grunt.template.today("yyyy-mm-dd") %>\n' +
'<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
'* Copyright (c) <%= grunt.template.today("yyyy") %> Thomas Grainger;' +
' Licensed <%= pkg.license %> */',
report: 'gzip'
}
},
babel : {
options : {
presets: ['es2015', 'stage-1'],
plugins: [
'add-module-exports',
"transform-es2015-modules-umd"
]
},
dist: {
files: {
'dist/wow.js': 'src/WOW.js'
}
}
},
coffee : {
specs : {
files: [{
expand: true,
cwd: 'spec/coffeescripts/',
src: '*.coffee',
dest: 'spec/javascripts/',
ext: '.js'
}]
},
helpers : {
files: [{
expand: true,
cwd: 'spec/coffeescripts/helpers/',
src: '*.coffee',
dest: 'spec/javascripts/helpers/',
ext: '.js'
}]
}
},
jasmine : {
src : ['spec/javascripts/libs/*.js', 'dist/wow.min.js'],
options : {
specs : 'spec/javascripts/**/*.js',
helpers : 'spec/javascripts/helpers/**/*.js'
}
},
watch : {
files: [
'src/*',
'spec/coffeescripts/**/*.coffee'
],
tasks: mainTasks
},
growl : {
coffee : {
title : 'CoffeeScript',
message : 'Compiled successfully'
},
jasmine : {
title : 'Jasmine',
message : 'Tests passed successfully'
}
}
});
grunt.registerTask('default', mainTasks);
// Travis CI task.
grunt.registerTask('travis', ['eslint', 'babel', 'coffee', 'uglify', 'jasmine']);
};
/*global module:false*/
module.exports = function(grunt) {
require('load-grunt-tasks')(grunt);
mainTasks = [
'eslint', 'babel', 'coffee', 'growl:coffee', 'uglify', 'jasmine',
'growl:jasmine',
]
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
eslint: {
target: ['src/WOW.js']
},
uglify: {
dist: {
files: {
'dist/wow.min.js': 'dist/wow.js'
}
},
options: {
banner : '/*! <%= pkg.title %> wow.js - v<%= pkg.version %> - ' +
'<%= grunt.template.today("yyyy-mm-dd") %>\n' +
'<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
'* Copyright (c) <%= grunt.template.today("yyyy") %> Thomas Grainger;' +
' Licensed <%= pkg.license %> */',
report: 'gzip'
}
},
babel : {
options : {
presets: ['es2015', 'stage-1'],
plugins: [
'add-module-exports',
"transform-es2015-modules-umd"
]
},
dist: {
files: {
'dist/wow.js': 'src/WOW.js'
}
}
},
coffee : {
specs : {
files: [{
expand: true,
cwd: 'spec/coffeescripts/',
src: '*.coffee',
dest: 'spec/javascripts/',
ext: '.js'
}]
},
helpers : {
files: [{
expand: true,
cwd: 'spec/coffeescripts/helpers/',
src: '*.coffee',
dest: 'spec/javascripts/helpers/',
ext: '.js'
}]
}
},
jasmine : {
src : ['spec/javascripts/libs/*.js', 'dist/wow.min.js'],
options : {
specs : 'spec/javascripts/**/*.js',
helpers : 'spec/javascripts/helpers/**/*.js'
}
},
watch : {
files: [
'src/*',
'spec/coffeescripts/**/*.coffee'
],
tasks: mainTasks
},
growl : {
coffee : {
title : 'CoffeeScript',
message : 'Compiled successfully'
},
jasmine : {
title : 'Jasmine',
message : 'Tests passed successfully'
}
}
});
grunt.registerTask('default', mainTasks);
// Travis CI task.
grunt.registerTask('travis', ['eslint', 'babel', 'coffee', 'uglify', 'jasmine']);
};

68
node_modules/wow.js/LICENSE generated vendored
View file

@ -1,34 +1,34 @@
The MIT License (MIT)
Copyright (c) 2016 Thomas Grainger.
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.
Portions of this wow.js Software may utilize the following copyrighted material, the use of which is hereby acknowledged.
WOW: https://github.com/matthieua/WOW/tree/20848c410fe32d161c2330e1d261b59512094f81
Copyright (C) 2014; Matthieu Aussaguel
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.
The MIT License (MIT)
Copyright (c) 2016 Thomas Grainger.
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.
Portions of this wow.js Software may utilize the following copyrighted material, the use of which is hereby acknowledged.
WOW: https://github.com/matthieua/WOW/tree/20848c410fe32d161c2330e1d261b59512094f81
Copyright (C) 2014; Matthieu Aussaguel
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.

280
node_modules/wow.js/README.md generated vendored
View file

@ -1,140 +1,140 @@
# WOW.js [![Build Status](https://secure.travis-ci.org/graingert/WOW.svg?branch=master)](http://travis-ci.org/graingert/WOW)
Reveal CSS animation as you scroll down a page.
By default, you can use it to trigger [animate.css](https://github.com/daneden/animate.css) animations.
But you can easily change the settings to your favorite animation library.
Advantages:
- 100% MIT Licensed, not GPL keep your code yours.
- Naturally Caffeine free
- Smaller than other JavaScript parallax plugins, like Scrollorama (they do fantastic things, but can be too heavy for simple needs)
- Super simple to install, and works with animate.css, so if you already use it, that will be very fast to setup
- Fast execution and lightweight code: the browser will like it ;-)
- You can change the settings - [see below](#advanced-usage)
### [LIVE DEMO ➫](https://graingert.co.uk/WOW/)
## Live examples
- [MaterialUp](http://www.materialup.com)
- [Fliplingo](https://www.fliplingo.com)
- [Streamline Icons](http://www.streamlineicons.com)
- [Microsoft Stories](http://www.microsoft.com/en-us/news/stories/garage/)
## Documentation
It just take seconds to install and use WOW.js!
[Read the documentation ➫](https://graingert.co.uk/WOW/docs.html)
### Dependencies
- [animate.css](https://github.com/daneden/animate.css)
### Installation
- Bower
```bash
bower install wow-mit
```
- NPM
```bash
npm install wow.js
```
### Basic usage
- HTML
```html
<section class="wow slideInLeft"></section>
<section class="wow slideInRight"></section>
```
- JavaScript
```javascript
new WOW().init();
```
### Advanced usage
- HTML
```html
<section class="wow slideInLeft" data-wow-duration="2s" data-wow-delay="5s"></section>
<section class="wow slideInRight" data-wow-offset="10" data-wow-iteration="10"></section>
```
- JavaScript
```javascript
var wow = new WOW(
{
boxClass: 'wow', // animated element css class (default is wow)
animateClass: 'animated', // animation css class (default is animated)
offset: 0, // distance to the element when triggering the animation (default is 0)
mobile: true, // trigger animations on mobile devices (default is true)
live: true, // act on asynchronously loaded content (default is true)
callback: function(box) {
// the callback is fired every time an animation is started
// the argument that is passed in is the DOM node being animated
},
scrollContainer: null // optional scroll container selector, otherwise use window
}
);
wow.init();
```
### Asynchronous content support
In IE 10+, Chrome 18+ and Firefox 14+, animations will be automatically
triggered for any DOM nodes you add after calling `wow.init()`. If you do not
like that, you can disable this by setting `live` to `false`.
If you want to support older browsers (e.g. IE9+), as a fallback, you can call
the `wow.sync()` method after you have added new DOM elements to animate (but
`live` should still be set to `true`). Calling `wow.sync()` has no side
effects.
## Contribute
The library is transpiled using Babel, please update `wow.js` file.
We use grunt to compile and minify the library:
Install needed libraries
```
npm install
```
Get the compilation running in the background
```
grunt watch
```
Enjoy!
## Bug tracker
If you find a bug, please report it [here on Github](https://github.com/graingert/WOW/issues)!
## Developer
Originally Developed by Matthieu Aussaguel, [mynameismatthieu.com](http://mynameismatthieu.com)
Forked to remain under the MIT license by Thomas Grainger, https://graingert.co.uk
+ [Github Profile](//github.com/graingert)
## Contributors
Thanks to everyone who has contributed to the project so far:
- Attila Oláh - [@attilaolah](//twitter.com/attilaolah) - [Github Profile](//github.com/attilaolah)
- [and many others](//github.com/graingert/WOW/graphs/contributors)
Initiated and designed by [Vincent Le Moign](//www.webalys.com/), [@webalys](//twitter.com/webalys)
# WOW.js [![Build Status](https://secure.travis-ci.org/graingert/WOW.svg?branch=master)](http://travis-ci.org/graingert/WOW)
Reveal CSS animation as you scroll down a page.
By default, you can use it to trigger [animate.css](https://github.com/daneden/animate.css) animations.
But you can easily change the settings to your favorite animation library.
Advantages:
- 100% MIT Licensed, not GPL keep your code yours.
- Naturally Caffeine free
- Smaller than other JavaScript parallax plugins, like Scrollorama (they do fantastic things, but can be too heavy for simple needs)
- Super simple to install, and works with animate.css, so if you already use it, that will be very fast to setup
- Fast execution and lightweight code: the browser will like it ;-)
- You can change the settings - [see below](#advanced-usage)
### [LIVE DEMO ➫](https://graingert.co.uk/WOW/)
## Live examples
- [MaterialUp](http://www.materialup.com)
- [Fliplingo](https://www.fliplingo.com)
- [Streamline Icons](http://www.streamlineicons.com)
- [Microsoft Stories](http://www.microsoft.com/en-us/news/stories/garage/)
## Documentation
It just take seconds to install and use WOW.js!
[Read the documentation ➫](https://graingert.co.uk/WOW/docs.html)
### Dependencies
- [animate.css](https://github.com/daneden/animate.css)
### Installation
- Bower
```bash
bower install wow-mit
```
- NPM
```bash
npm install wow.js
```
### Basic usage
- HTML
```html
<section class="wow slideInLeft"></section>
<section class="wow slideInRight"></section>
```
- JavaScript
```javascript
new WOW().init();
```
### Advanced usage
- HTML
```html
<section class="wow slideInLeft" data-wow-duration="2s" data-wow-delay="5s"></section>
<section class="wow slideInRight" data-wow-offset="10" data-wow-iteration="10"></section>
```
- JavaScript
```javascript
var wow = new WOW(
{
boxClass: 'wow', // animated element css class (default is wow)
animateClass: 'animated', // animation css class (default is animated)
offset: 0, // distance to the element when triggering the animation (default is 0)
mobile: true, // trigger animations on mobile devices (default is true)
live: true, // act on asynchronously loaded content (default is true)
callback: function(box) {
// the callback is fired every time an animation is started
// the argument that is passed in is the DOM node being animated
},
scrollContainer: null // optional scroll container selector, otherwise use window
}
);
wow.init();
```
### Asynchronous content support
In IE 10+, Chrome 18+ and Firefox 14+, animations will be automatically
triggered for any DOM nodes you add after calling `wow.init()`. If you do not
like that, you can disable this by setting `live` to `false`.
If you want to support older browsers (e.g. IE9+), as a fallback, you can call
the `wow.sync()` method after you have added new DOM elements to animate (but
`live` should still be set to `true`). Calling `wow.sync()` has no side
effects.
## Contribute
The library is transpiled using Babel, please update `wow.js` file.
We use grunt to compile and minify the library:
Install needed libraries
```
npm install
```
Get the compilation running in the background
```
grunt watch
```
Enjoy!
## Bug tracker
If you find a bug, please report it [here on Github](https://github.com/graingert/WOW/issues)!
## Developer
Originally Developed by Matthieu Aussaguel, [mynameismatthieu.com](http://mynameismatthieu.com)
Forked to remain under the MIT license by Thomas Grainger, https://graingert.co.uk
+ [Github Profile](//github.com/graingert)
## Contributors
Thanks to everyone who has contributed to the project so far:
- Attila Oláh - [@attilaolah](//twitter.com/attilaolah) - [Github Profile](//github.com/attilaolah)
- [and many others](//github.com/graingert/WOW/graphs/contributors)
Initiated and designed by [Vincent Le Moign](//www.webalys.com/), [@webalys](//twitter.com/webalys)

50
node_modules/wow.js/bower.json generated vendored
View file

@ -1,25 +1,25 @@
{
"name": "wow",
"homepage": "https://github.com/graingert/WOW",
"authors": [
"Matthieu Aussaguel <matthieu.aussaguel@gmail.com>"
],
"authors": [
"Thomas Grainger <wow.js@graingert.co.uk>"
],
"description": "Reveal CSS animation as you scroll down a page.",
"main": "dist/wow.js",
"keywords": [
"scroll",
"animation",
"reveal"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}
{
"name": "wow",
"homepage": "https://github.com/graingert/WOW",
"authors": [
"Matthieu Aussaguel <matthieu.aussaguel@gmail.com>"
],
"authors": [
"Thomas Grainger <wow.js@graingert.co.uk>"
],
"description": "Reveal CSS animation as you scroll down a page.",
"main": "dist/wow.js",
"keywords": [
"scroll",
"animation",
"reveal"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}

File diff suppressed because it is too large Load diff

72
node_modules/wow.js/css/site.css generated vendored
View file

@ -1,36 +1,36 @@
h1 {
font-size: 72px;
line-height: 1.5;
color: #2c3e50;
font-weight: 100;
}
#container {
width: 980px;
margin: 0 auto;
}
section {
height: 300px;
margin: 60px 0;
}
.section--purple {
background-color: #9b59b6;
}
.section--blue {
background-color: #3498db;
}
.section--green {
background-color: #2ecc71;
}
#main {
text-align: center;
}
#more {
margin: 20px auto 48px;
}
h1 {
font-size: 72px;
line-height: 1.5;
color: #2c3e50;
font-weight: 100;
}
#container {
width: 980px;
margin: 0 auto;
}
section {
height: 300px;
margin: 60px 0;
}
.section--purple {
background-color: #9b59b6;
}
.section--blue {
background-color: #3498db;
}
.section--green {
background-color: #2ecc71;
}
#main {
text-align: center;
}
#more {
margin: 20px auto 48px;
}

104
node_modules/wow.js/demo.html generated vendored
View file

@ -1,52 +1,52 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>WOW</title>
<link rel="stylesheet" href="css/libs/animate.css">
<link rel="stylesheet" href="css/site.css">
<style>
.wow:first-child {
visibility: hidden;
}
</style>
<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div id="container">
<header>
<h1>WOW.js</h1>
</header>
<div id="main">
<section class="wow fadeInDown" style="background-color: #f1c40f;"></section>
<section class="wow pulse" style="background-color: #e74c3c;" data-wow-iteration="infinite" data-wow-duration="1500ms"></section>
<section class="section--purple wow slideInRight" data-wow-delay="2s"></section>
<section class="section--blue wow bounceInLeft" data-wow-offset="300"></section>
<section class="section--green wow slideInLeft" data-wow-duration="4s"></section>
<button id="moar">LOAD MOAR!!</button>
</div>
</div>
<script src="dist/wow.js"></script>
<script>
wow = new WOW(
{
animateClass: 'animated',
offset: 100,
callback: function(box) {
console.log("WOW: animating <" + box.tagName.toLowerCase() + ">")
}
}
);
wow.init();
document.getElementById('moar').onclick = function() {
var section = document.createElement('section');
section.className = 'section--purple wow fadeInDown';
this.parentNode.insertBefore(section, this);
};
</script>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>WOW</title>
<link rel="stylesheet" href="css/libs/animate.css">
<link rel="stylesheet" href="css/site.css">
<style>
.wow:first-child {
visibility: hidden;
}
</style>
<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<div id="container">
<header>
<h1>WOW.js</h1>
</header>
<div id="main">
<section class="wow fadeInDown" style="background-color: #f1c40f;"></section>
<section class="wow pulse" style="background-color: #e74c3c;" data-wow-iteration="infinite" data-wow-duration="1500ms"></section>
<section class="section--purple wow slideInRight" data-wow-delay="2s"></section>
<section class="section--blue wow bounceInLeft" data-wow-offset="300"></section>
<section class="section--green wow slideInLeft" data-wow-duration="4s"></section>
<button id="moar">LOAD MOAR!!</button>
</div>
</div>
<script src="dist/wow.js"></script>
<script>
wow = new WOW(
{
animateClass: 'animated',
offset: 100,
callback: function(box) {
console.log("WOW: animating <" + box.tagName.toLowerCase() + ">")
}
}
);
wow.init();
document.getElementById('moar').onclick = function() {
var section = document.createElement('section');
section.className = 'section--purple wow fadeInDown';
this.parentNode.insertBefore(section, this);
};
</script>
</body>
</html>

1066
node_modules/wow.js/dist/wow.js generated vendored

File diff suppressed because it is too large Load diff

View file

@ -1,334 +1,334 @@
describe 'WOW', ->
# Supress warnings:
window.console =
warn: ->
# Time to wait after each scroll event:
# (This should be >= the interval used by the plugin.)
timeout = 100
# Height of the PhantomJS window:
winHeight = 300
describe 'smoke test', ->
it 'exists', ->
expect WOW
.toBeDefined()
it "has an 'init' method", ->
expect new WOW().init
.toBeDefined()
describe 'simple test environment', ->
beforeEach ->
loadFixtures 'simple.html'
it 'emulates window height', ->
expect document.documentElement.clientHeight
.toBe winHeight
it 'has boxes set up for testing', ->
boxHeight = 200
boxCount = $ '#simple'
.children().length
# Check each box height
expect $('#simple').height()
.toBe boxHeight*boxCount
expect $('#simple-1').height()
.toBe boxHeight
expect $('#simple-2').height()
.toBe boxHeight
expect $('#simple-3').height()
.toBe boxHeight
expect $('#simple-4').height()
.toBe boxHeight
expect $('#simple-5').height()
.toBe boxHeight
# Check each box offset
offset = $('#simple').offset().top
expect $('#simple-1').offset().top
.toBe offset + boxHeight*0
expect $('#simple-2').offset().top
.toBe offset + boxHeight*1
expect $('#simple-3').offset().top
.toBe offset + boxHeight*2
expect $('#simple-4').offset().top
.toBe offset + boxHeight*3
expect $('#simple-5').offset().top
.toBe offset + boxHeight*4
style = $('#simple-5')[0].style
expect style.background
.toBe 'yellow'
expect style.color
.toBe 'red'
describe 'library behaviour', ->
wow = null
beforeEach (done) ->
loadFixtures 'simple.html'
(wow = new WOW).init()
setTimeout ->
done()
, timeout
it 'animates elements that are fully visible on the page', ->
expect $ '#simple-1'
.toHaveClass 'animated'
expect $('#simple-1').css 'visibility'
.toBe 'visible'
it "does not touch elements that don't have the marker class", ->
expect $ '#simple-2'
.not.toHaveClass 'animated'
expect $('#simple-2').css 'visibility'
.toBe 'visible'
it 'does not animate elements not yet visible on the page', ->
expect $ '#simple-3'
.not.toHaveClass 'animated'
expect $('#simple-3').css 'visibility'
.not.toBe 'visible'
expect $ '#simple-4'
.not.toHaveClass 'animated'
expect $('#simple-4').css 'visibility'
.not.toBe 'visible'
it 'animates elements after scrolling down and they become visible', (done) ->
# Scroll down so that 150px of #simple-3 becomes visible.
window.scrollTo 0, $('#simple-3').offset().top - winHeight + 150
setTimeout ->
expect $ '#simple-3'
.toHaveClass 'animated'
expect $('#simple-3').css 'visibility'
.toBe 'visible'
expect $ '#simple-4'
.not.toHaveClass 'animated'
expect $('#simple-4').css 'visibility'
.not.toBe 'visible'
# Scroll down so that 150px of #simple-4 becomes visible.
window.scrollTo 0, $('#simple-4').offset().top - winHeight + 150
setTimeout ->
expect $ '#simple-4'
.toHaveClass 'animated'
expect $('#simple-4').css 'visibility'
.toBe 'visible'
done()
, timeout
, timeout
it 'does not tamper with the style attribute', (done) ->
# Scroll down so that 150px of #simple-5 becomes visible.
window.scrollTo 0, $('#simple-5').offset().top - winHeight + 150
setTimeout ->
expect $ '#simple-5'
.toHaveClass 'animated'
expect $('#simple-5').css 'visibility'
.toBe 'visible'
expect $('#simple-5')[0].style.background
.toBe 'yellow'
expect $('#simple-5')[0].style.color
.toBe 'red'
done()
, timeout
it 'works with asynchronously loaded content', (done) ->
$ '#simple'
.append $ '<div/>',
id: 'simple-6'
class: 'wow'
wow.sync()
# Scroll down so that 150px of #simple-6 becomes visible.
window.scrollTo 0, $('#simple-6').offset().top - winHeight + 150
setTimeout ->
expect $ '#simple-6'
.toHaveClass 'animated'
expect $('#simple-6').css 'visibility'
.toBe 'visible'
done()
, timeout
it 'works with asynchronously loaded nested content', (done) ->
$ '#simple'
.append $ '<div/>'
.children()
.first()
.append $ '<div/>',
id: 'simple-7'
class: 'wow'
wow.sync()
# Scroll down so that 150px of #simple-7 becomes visible.
window.scrollTo 0, $('#simple-7').offset().top - winHeight + 150
setTimeout ->
expect $ '#simple-7'
.toHaveClass 'animated'
expect $('#simple-7').css 'visibility'
.toBe 'visible'
done()
, timeout
describe 'custom test environment', ->
beforeEach ->
loadFixtures 'custom.html'
it 'emulates window height', ->
expect document.documentElement.clientHeight
.toBe winHeight
it 'has boxes set up for testing', ->
# Check each box height
expect $('#custom').height()
.toBe 800
expect $('#custom-1').height()
.toBe 200
expect $('#custom-2').height()
.toBe 200
expect $('#custom-3').height()
.toBe 200
expect $('#custom-4').height()
.toBe 200
# Check each box offset
offset = $('#custom').offset().top
expect $('#custom-1').offset().top
.toBe offset + 200*0
expect $('#custom-2').offset().top
.toBe offset + 200*1
expect $('#custom-3').offset().top
.toBe offset + 200*2
expect $('#custom-4').offset().top
.toBe offset + 200*3
describe 'library behaviour with custom settings', ->
called = false
beforeEach (done) ->
called = false
loadFixtures 'custom.html'
new WOW
boxClass: 'block'
animateClass: 'fancy'
offset: 10
callback: ->
called = true
.init()
# Trigger custom event on dom object, event name is boxClass value
$('.block').on 'block', ->
$(this).addClass('triggered')
setTimeout ->
done()
, timeout
it "creates two instances of the WOW.js with different configs", ->
wow1 = new WOW
boxClass: 'block1'
animateClass: 'fancy1'
offset: 10
wow2 = new WOW
boxClass: 'block2'
animateClass: 'fancy2'
offset: 20
expect wow1.config.boxClass
.toBe "block1"
expect wow1.config.animateClass
.toBe "fancy1"
expect wow1.config.offset
.toBe 10
it "does not touch elements that don't have the marker class", (done) ->
# Scroll down so that 15px of #custom-1 becomes visible.
window.scrollTo 0, $('#custom-1').offset().top - winHeight + 15
setTimeout ->
expect $ '#custom-1'
.not.toHaveClass 'fancy'
done()
, timeout
it "animates elements that are partially visible on the page based on the 'offset' config", (done) ->
setTimeout ->
# Scroll down so that 5px of #custom-2 becomes visible.
window.scrollTo 0, $('#custom-2').offset().top - winHeight + 5
expect $ '#custom-2'
.not.toHaveClass 'fancy'
window.scrollTo 0, $('#custom-2').offset().top - winHeight + 15
setTimeout ->
# Scroll down so that 15px of #custom-2 becomes visible.
expect $ '#custom-2'
.toHaveClass 'fancy'
expect $('#custom-2').css 'visibility'
.toBe 'visible'
done()
, timeout
, timeout
it 'does not animate elements not yet visible on the page', ->
expect $ '#custom-3'
.not.toHaveClass 'fancy'
expect $ '#custom-4'
.not.toHaveClass 'fancy'
it 'animates elements after scrolling down and they become visible', (done) ->
# Scroll down so that 150px of #custom-3 becomes visible.
window.scrollTo 0, $('#custom-3').offset().top - winHeight + 150
setTimeout ->
expect $ '#custom-3'
.toHaveClass 'fancy'
expect $('#custom-3').css 'visibility'
.toBe 'visible'
expect $('#custom-3')[0].style.webkitAnimationIterationCount
.toBe '2'
expect $ '#custom-4'
.not.toHaveClass 'fancy'
# Scroll down so that 150px of #custom-4 becomes visible.
window.scrollTo 0, $('#custom-4').offset().top - winHeight + 150
setTimeout ->
expect $ '#custom-4'
.toHaveClass 'fancy'
expect $('#custom-4').css 'visibility'
.toBe 'visible'
expect $('#custom-4')[0].style.webkitAnimationIterationCount
.toBe 'infinite'
expect $('#custom-4')[0].style.webkitAnimationDuration
.toBe '2s'
expect $('#custom-4')[0].style.webkitAnimationDelay
.toBe '1s'
done()
, timeout
, timeout
it "fires the callback", (done) ->
called = false # reset
# Scroll down so that 150px of #custom-3 becomes visible.
window.scrollTo 0, $('#custom-3').offset().top - winHeight + 150
setTimeout ->
expect called
.toBe true
done()
, timeout
it 'fires the callback on the visible element', (done) ->
# Scroll down so that 150px of #custom-3 becomes visible.
window.scrollTo 0, $('#custom-3').offset().top - winHeight + 150
setTimeout ->
expect $ '#custom-3'
.toHaveClass 'triggered'
expect $ '#custom-4'
.not.toHaveClass 'triggered'
# Scroll down so that 150px of #custom-4 becomes visible.
window.scrollTo 0, $('#custom-4').offset().top - winHeight + 150
setTimeout ->
expect $ '#custom-3'
.toHaveClass 'triggered'
expect $ '#custom-4'
.toHaveClass 'triggered'
done()
, timeout
, timeout
describe 'WOW', ->
# Supress warnings:
window.console =
warn: ->
# Time to wait after each scroll event:
# (This should be >= the interval used by the plugin.)
timeout = 100
# Height of the PhantomJS window:
winHeight = 300
describe 'smoke test', ->
it 'exists', ->
expect WOW
.toBeDefined()
it "has an 'init' method", ->
expect new WOW().init
.toBeDefined()
describe 'simple test environment', ->
beforeEach ->
loadFixtures 'simple.html'
it 'emulates window height', ->
expect document.documentElement.clientHeight
.toBe winHeight
it 'has boxes set up for testing', ->
boxHeight = 200
boxCount = $ '#simple'
.children().length
# Check each box height
expect $('#simple').height()
.toBe boxHeight*boxCount
expect $('#simple-1').height()
.toBe boxHeight
expect $('#simple-2').height()
.toBe boxHeight
expect $('#simple-3').height()
.toBe boxHeight
expect $('#simple-4').height()
.toBe boxHeight
expect $('#simple-5').height()
.toBe boxHeight
# Check each box offset
offset = $('#simple').offset().top
expect $('#simple-1').offset().top
.toBe offset + boxHeight*0
expect $('#simple-2').offset().top
.toBe offset + boxHeight*1
expect $('#simple-3').offset().top
.toBe offset + boxHeight*2
expect $('#simple-4').offset().top
.toBe offset + boxHeight*3
expect $('#simple-5').offset().top
.toBe offset + boxHeight*4
style = $('#simple-5')[0].style
expect style.background
.toBe 'yellow'
expect style.color
.toBe 'red'
describe 'library behaviour', ->
wow = null
beforeEach (done) ->
loadFixtures 'simple.html'
(wow = new WOW).init()
setTimeout ->
done()
, timeout
it 'animates elements that are fully visible on the page', ->
expect $ '#simple-1'
.toHaveClass 'animated'
expect $('#simple-1').css 'visibility'
.toBe 'visible'
it "does not touch elements that don't have the marker class", ->
expect $ '#simple-2'
.not.toHaveClass 'animated'
expect $('#simple-2').css 'visibility'
.toBe 'visible'
it 'does not animate elements not yet visible on the page', ->
expect $ '#simple-3'
.not.toHaveClass 'animated'
expect $('#simple-3').css 'visibility'
.not.toBe 'visible'
expect $ '#simple-4'
.not.toHaveClass 'animated'
expect $('#simple-4').css 'visibility'
.not.toBe 'visible'
it 'animates elements after scrolling down and they become visible', (done) ->
# Scroll down so that 150px of #simple-3 becomes visible.
window.scrollTo 0, $('#simple-3').offset().top - winHeight + 150
setTimeout ->
expect $ '#simple-3'
.toHaveClass 'animated'
expect $('#simple-3').css 'visibility'
.toBe 'visible'
expect $ '#simple-4'
.not.toHaveClass 'animated'
expect $('#simple-4').css 'visibility'
.not.toBe 'visible'
# Scroll down so that 150px of #simple-4 becomes visible.
window.scrollTo 0, $('#simple-4').offset().top - winHeight + 150
setTimeout ->
expect $ '#simple-4'
.toHaveClass 'animated'
expect $('#simple-4').css 'visibility'
.toBe 'visible'
done()
, timeout
, timeout
it 'does not tamper with the style attribute', (done) ->
# Scroll down so that 150px of #simple-5 becomes visible.
window.scrollTo 0, $('#simple-5').offset().top - winHeight + 150
setTimeout ->
expect $ '#simple-5'
.toHaveClass 'animated'
expect $('#simple-5').css 'visibility'
.toBe 'visible'
expect $('#simple-5')[0].style.background
.toBe 'yellow'
expect $('#simple-5')[0].style.color
.toBe 'red'
done()
, timeout
it 'works with asynchronously loaded content', (done) ->
$ '#simple'
.append $ '<div/>',
id: 'simple-6'
class: 'wow'
wow.sync()
# Scroll down so that 150px of #simple-6 becomes visible.
window.scrollTo 0, $('#simple-6').offset().top - winHeight + 150
setTimeout ->
expect $ '#simple-6'
.toHaveClass 'animated'
expect $('#simple-6').css 'visibility'
.toBe 'visible'
done()
, timeout
it 'works with asynchronously loaded nested content', (done) ->
$ '#simple'
.append $ '<div/>'
.children()
.first()
.append $ '<div/>',
id: 'simple-7'
class: 'wow'
wow.sync()
# Scroll down so that 150px of #simple-7 becomes visible.
window.scrollTo 0, $('#simple-7').offset().top - winHeight + 150
setTimeout ->
expect $ '#simple-7'
.toHaveClass 'animated'
expect $('#simple-7').css 'visibility'
.toBe 'visible'
done()
, timeout
describe 'custom test environment', ->
beforeEach ->
loadFixtures 'custom.html'
it 'emulates window height', ->
expect document.documentElement.clientHeight
.toBe winHeight
it 'has boxes set up for testing', ->
# Check each box height
expect $('#custom').height()
.toBe 800
expect $('#custom-1').height()
.toBe 200
expect $('#custom-2').height()
.toBe 200
expect $('#custom-3').height()
.toBe 200
expect $('#custom-4').height()
.toBe 200
# Check each box offset
offset = $('#custom').offset().top
expect $('#custom-1').offset().top
.toBe offset + 200*0
expect $('#custom-2').offset().top
.toBe offset + 200*1
expect $('#custom-3').offset().top
.toBe offset + 200*2
expect $('#custom-4').offset().top
.toBe offset + 200*3
describe 'library behaviour with custom settings', ->
called = false
beforeEach (done) ->
called = false
loadFixtures 'custom.html'
new WOW
boxClass: 'block'
animateClass: 'fancy'
offset: 10
callback: ->
called = true
.init()
# Trigger custom event on dom object, event name is boxClass value
$('.block').on 'block', ->
$(this).addClass('triggered')
setTimeout ->
done()
, timeout
it "creates two instances of the WOW.js with different configs", ->
wow1 = new WOW
boxClass: 'block1'
animateClass: 'fancy1'
offset: 10
wow2 = new WOW
boxClass: 'block2'
animateClass: 'fancy2'
offset: 20
expect wow1.config.boxClass
.toBe "block1"
expect wow1.config.animateClass
.toBe "fancy1"
expect wow1.config.offset
.toBe 10
it "does not touch elements that don't have the marker class", (done) ->
# Scroll down so that 15px of #custom-1 becomes visible.
window.scrollTo 0, $('#custom-1').offset().top - winHeight + 15
setTimeout ->
expect $ '#custom-1'
.not.toHaveClass 'fancy'
done()
, timeout
it "animates elements that are partially visible on the page based on the 'offset' config", (done) ->
setTimeout ->
# Scroll down so that 5px of #custom-2 becomes visible.
window.scrollTo 0, $('#custom-2').offset().top - winHeight + 5
expect $ '#custom-2'
.not.toHaveClass 'fancy'
window.scrollTo 0, $('#custom-2').offset().top - winHeight + 15
setTimeout ->
# Scroll down so that 15px of #custom-2 becomes visible.
expect $ '#custom-2'
.toHaveClass 'fancy'
expect $('#custom-2').css 'visibility'
.toBe 'visible'
done()
, timeout
, timeout
it 'does not animate elements not yet visible on the page', ->
expect $ '#custom-3'
.not.toHaveClass 'fancy'
expect $ '#custom-4'
.not.toHaveClass 'fancy'
it 'animates elements after scrolling down and they become visible', (done) ->
# Scroll down so that 150px of #custom-3 becomes visible.
window.scrollTo 0, $('#custom-3').offset().top - winHeight + 150
setTimeout ->
expect $ '#custom-3'
.toHaveClass 'fancy'
expect $('#custom-3').css 'visibility'
.toBe 'visible'
expect $('#custom-3')[0].style.webkitAnimationIterationCount
.toBe '2'
expect $ '#custom-4'
.not.toHaveClass 'fancy'
# Scroll down so that 150px of #custom-4 becomes visible.
window.scrollTo 0, $('#custom-4').offset().top - winHeight + 150
setTimeout ->
expect $ '#custom-4'
.toHaveClass 'fancy'
expect $('#custom-4').css 'visibility'
.toBe 'visible'
expect $('#custom-4')[0].style.webkitAnimationIterationCount
.toBe 'infinite'
expect $('#custom-4')[0].style.webkitAnimationDuration
.toBe '2s'
expect $('#custom-4')[0].style.webkitAnimationDelay
.toBe '1s'
done()
, timeout
, timeout
it "fires the callback", (done) ->
called = false # reset
# Scroll down so that 150px of #custom-3 becomes visible.
window.scrollTo 0, $('#custom-3').offset().top - winHeight + 150
setTimeout ->
expect called
.toBe true
done()
, timeout
it 'fires the callback on the visible element', (done) ->
# Scroll down so that 150px of #custom-3 becomes visible.
window.scrollTo 0, $('#custom-3').offset().top - winHeight + 150
setTimeout ->
expect $ '#custom-3'
.toHaveClass 'triggered'
expect $ '#custom-4'
.not.toHaveClass 'triggered'
# Scroll down so that 150px of #custom-4 becomes visible.
window.scrollTo 0, $('#custom-4').offset().top - winHeight + 150
setTimeout ->
expect $ '#custom-3'
.toHaveClass 'triggered'
expect $ '#custom-4'
.toHaveClass 'triggered'
done()
, timeout
, timeout

View file

@ -1,4 +1,4 @@
(function() {
beforeEach(function() {});
}).call(this);
(function() {
beforeEach(function() {});
}).call(this);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,244 +1,244 @@
(function() {
describe('WOW', function() {
var timeout, winHeight;
window.console = {
warn: function() {}
};
timeout = 100;
winHeight = 300;
describe('smoke test', function() {
it('exists', function() {
return expect(WOW).toBeDefined();
});
return it("has an 'init' method", function() {
return expect(new WOW().init).toBeDefined();
});
});
describe('simple test environment', function() {
beforeEach(function() {
return loadFixtures('simple.html');
});
it('emulates window height', function() {
return expect(document.documentElement.clientHeight).toBe(winHeight);
});
return it('has boxes set up for testing', function() {
var boxCount, boxHeight, offset, style;
boxHeight = 200;
boxCount = $('#simple').children().length;
expect($('#simple').height()).toBe(boxHeight * boxCount);
expect($('#simple-1').height()).toBe(boxHeight);
expect($('#simple-2').height()).toBe(boxHeight);
expect($('#simple-3').height()).toBe(boxHeight);
expect($('#simple-4').height()).toBe(boxHeight);
expect($('#simple-5').height()).toBe(boxHeight);
offset = $('#simple').offset().top;
expect($('#simple-1').offset().top).toBe(offset + boxHeight * 0);
expect($('#simple-2').offset().top).toBe(offset + boxHeight * 1);
expect($('#simple-3').offset().top).toBe(offset + boxHeight * 2);
expect($('#simple-4').offset().top).toBe(offset + boxHeight * 3);
expect($('#simple-5').offset().top).toBe(offset + boxHeight * 4);
style = $('#simple-5')[0].style;
expect(style.background).toBe('yellow');
return expect(style.color).toBe('red');
});
});
describe('library behaviour', function() {
var wow;
wow = null;
beforeEach(function(done) {
loadFixtures('simple.html');
(wow = new WOW).init();
return setTimeout(function() {
return done();
}, timeout);
});
it('animates elements that are fully visible on the page', function() {
expect($('#simple-1')).toHaveClass('animated');
return expect($('#simple-1').css('visibility')).toBe('visible');
});
it("does not touch elements that don't have the marker class", function() {
expect($('#simple-2')).not.toHaveClass('animated');
return expect($('#simple-2').css('visibility')).toBe('visible');
});
it('does not animate elements not yet visible on the page', function() {
expect($('#simple-3')).not.toHaveClass('animated');
expect($('#simple-3').css('visibility')).not.toBe('visible');
expect($('#simple-4')).not.toHaveClass('animated');
return expect($('#simple-4').css('visibility')).not.toBe('visible');
});
it('animates elements after scrolling down and they become visible', function(done) {
window.scrollTo(0, $('#simple-3').offset().top - winHeight + 150);
return setTimeout(function() {
expect($('#simple-3')).toHaveClass('animated');
expect($('#simple-3').css('visibility')).toBe('visible');
expect($('#simple-4')).not.toHaveClass('animated');
expect($('#simple-4').css('visibility')).not.toBe('visible');
window.scrollTo(0, $('#simple-4').offset().top - winHeight + 150);
return setTimeout(function() {
expect($('#simple-4')).toHaveClass('animated');
expect($('#simple-4').css('visibility')).toBe('visible');
return done();
}, timeout);
}, timeout);
});
it('does not tamper with the style attribute', function(done) {
window.scrollTo(0, $('#simple-5').offset().top - winHeight + 150);
return setTimeout(function() {
expect($('#simple-5')).toHaveClass('animated');
expect($('#simple-5').css('visibility')).toBe('visible');
expect($('#simple-5')[0].style.background).toBe('yellow');
expect($('#simple-5')[0].style.color).toBe('red');
return done();
}, timeout);
});
it('works with asynchronously loaded content', function(done) {
$('#simple').append($('<div/>', {
id: 'simple-6',
"class": 'wow'
}));
wow.sync();
window.scrollTo(0, $('#simple-6').offset().top - winHeight + 150);
return setTimeout(function() {
expect($('#simple-6')).toHaveClass('animated');
expect($('#simple-6').css('visibility')).toBe('visible');
return done();
}, timeout);
});
return it('works with asynchronously loaded nested content', function(done) {
$('#simple').append($('<div/>')).children().first().append($('<div/>', {
id: 'simple-7',
"class": 'wow'
}));
wow.sync();
window.scrollTo(0, $('#simple-7').offset().top - winHeight + 150);
return setTimeout(function() {
expect($('#simple-7')).toHaveClass('animated');
expect($('#simple-7').css('visibility')).toBe('visible');
return done();
}, timeout);
});
});
describe('custom test environment', function() {
beforeEach(function() {
return loadFixtures('custom.html');
});
it('emulates window height', function() {
return expect(document.documentElement.clientHeight).toBe(winHeight);
});
return it('has boxes set up for testing', function() {
var offset;
expect($('#custom').height()).toBe(800);
expect($('#custom-1').height()).toBe(200);
expect($('#custom-2').height()).toBe(200);
expect($('#custom-3').height()).toBe(200);
expect($('#custom-4').height()).toBe(200);
offset = $('#custom').offset().top;
expect($('#custom-1').offset().top).toBe(offset + 200 * 0);
expect($('#custom-2').offset().top).toBe(offset + 200 * 1);
expect($('#custom-3').offset().top).toBe(offset + 200 * 2);
return expect($('#custom-4').offset().top).toBe(offset + 200 * 3);
});
});
return describe('library behaviour with custom settings', function() {
var called;
called = false;
beforeEach(function(done) {
called = false;
loadFixtures('custom.html');
new WOW({
boxClass: 'block',
animateClass: 'fancy',
offset: 10,
callback: function() {
return called = true;
}
}).init();
$('.block').on('block', function() {
return $(this).addClass('triggered');
});
return setTimeout(function() {
return done();
}, timeout);
});
it("creates two instances of the WOW.js with different configs", function() {
var wow1, wow2;
wow1 = new WOW({
boxClass: 'block1',
animateClass: 'fancy1',
offset: 10
});
wow2 = new WOW({
boxClass: 'block2',
animateClass: 'fancy2',
offset: 20
});
expect(wow1.config.boxClass).toBe("block1");
expect(wow1.config.animateClass).toBe("fancy1");
return expect(wow1.config.offset).toBe(10);
});
it("does not touch elements that don't have the marker class", function(done) {
window.scrollTo(0, $('#custom-1').offset().top - winHeight + 15);
return setTimeout(function() {
expect($('#custom-1')).not.toHaveClass('fancy');
return done();
}, timeout);
});
it("animates elements that are partially visible on the page based on the 'offset' config", function(done) {
return setTimeout(function() {
window.scrollTo(0, $('#custom-2').offset().top - winHeight + 5);
expect($('#custom-2')).not.toHaveClass('fancy');
window.scrollTo(0, $('#custom-2').offset().top - winHeight + 15);
return setTimeout(function() {
expect($('#custom-2')).toHaveClass('fancy');
expect($('#custom-2').css('visibility')).toBe('visible');
return done();
}, timeout);
}, timeout);
});
it('does not animate elements not yet visible on the page', function() {
expect($('#custom-3')).not.toHaveClass('fancy');
return expect($('#custom-4')).not.toHaveClass('fancy');
});
it('animates elements after scrolling down and they become visible', function(done) {
window.scrollTo(0, $('#custom-3').offset().top - winHeight + 150);
return setTimeout(function() {
expect($('#custom-3')).toHaveClass('fancy');
expect($('#custom-3').css('visibility')).toBe('visible');
expect($('#custom-3')[0].style.webkitAnimationIterationCount).toBe('2');
expect($('#custom-4')).not.toHaveClass('fancy');
window.scrollTo(0, $('#custom-4').offset().top - winHeight + 150);
return setTimeout(function() {
expect($('#custom-4')).toHaveClass('fancy');
expect($('#custom-4').css('visibility')).toBe('visible');
expect($('#custom-4')[0].style.webkitAnimationIterationCount).toBe('infinite');
expect($('#custom-4')[0].style.webkitAnimationDuration).toBe('2s');
expect($('#custom-4')[0].style.webkitAnimationDelay).toBe('1s');
return done();
}, timeout);
}, timeout);
});
it("fires the callback", function(done) {
called = false;
window.scrollTo(0, $('#custom-3').offset().top - winHeight + 150);
return setTimeout(function() {
expect(called).toBe(true);
return done();
}, timeout);
});
return it('fires the callback on the visible element', function(done) {
window.scrollTo(0, $('#custom-3').offset().top - winHeight + 150);
return setTimeout(function() {
expect($('#custom-3')).toHaveClass('triggered');
expect($('#custom-4')).not.toHaveClass('triggered');
window.scrollTo(0, $('#custom-4').offset().top - winHeight + 150);
return setTimeout(function() {
expect($('#custom-3')).toHaveClass('triggered');
expect($('#custom-4')).toHaveClass('triggered');
return done();
}, timeout);
}, timeout);
});
});
});
}).call(this);
(function() {
describe('WOW', function() {
var timeout, winHeight;
window.console = {
warn: function() {}
};
timeout = 100;
winHeight = 300;
describe('smoke test', function() {
it('exists', function() {
return expect(WOW).toBeDefined();
});
return it("has an 'init' method", function() {
return expect(new WOW().init).toBeDefined();
});
});
describe('simple test environment', function() {
beforeEach(function() {
return loadFixtures('simple.html');
});
it('emulates window height', function() {
return expect(document.documentElement.clientHeight).toBe(winHeight);
});
return it('has boxes set up for testing', function() {
var boxCount, boxHeight, offset, style;
boxHeight = 200;
boxCount = $('#simple').children().length;
expect($('#simple').height()).toBe(boxHeight * boxCount);
expect($('#simple-1').height()).toBe(boxHeight);
expect($('#simple-2').height()).toBe(boxHeight);
expect($('#simple-3').height()).toBe(boxHeight);
expect($('#simple-4').height()).toBe(boxHeight);
expect($('#simple-5').height()).toBe(boxHeight);
offset = $('#simple').offset().top;
expect($('#simple-1').offset().top).toBe(offset + boxHeight * 0);
expect($('#simple-2').offset().top).toBe(offset + boxHeight * 1);
expect($('#simple-3').offset().top).toBe(offset + boxHeight * 2);
expect($('#simple-4').offset().top).toBe(offset + boxHeight * 3);
expect($('#simple-5').offset().top).toBe(offset + boxHeight * 4);
style = $('#simple-5')[0].style;
expect(style.background).toBe('yellow');
return expect(style.color).toBe('red');
});
});
describe('library behaviour', function() {
var wow;
wow = null;
beforeEach(function(done) {
loadFixtures('simple.html');
(wow = new WOW).init();
return setTimeout(function() {
return done();
}, timeout);
});
it('animates elements that are fully visible on the page', function() {
expect($('#simple-1')).toHaveClass('animated');
return expect($('#simple-1').css('visibility')).toBe('visible');
});
it("does not touch elements that don't have the marker class", function() {
expect($('#simple-2')).not.toHaveClass('animated');
return expect($('#simple-2').css('visibility')).toBe('visible');
});
it('does not animate elements not yet visible on the page', function() {
expect($('#simple-3')).not.toHaveClass('animated');
expect($('#simple-3').css('visibility')).not.toBe('visible');
expect($('#simple-4')).not.toHaveClass('animated');
return expect($('#simple-4').css('visibility')).not.toBe('visible');
});
it('animates elements after scrolling down and they become visible', function(done) {
window.scrollTo(0, $('#simple-3').offset().top - winHeight + 150);
return setTimeout(function() {
expect($('#simple-3')).toHaveClass('animated');
expect($('#simple-3').css('visibility')).toBe('visible');
expect($('#simple-4')).not.toHaveClass('animated');
expect($('#simple-4').css('visibility')).not.toBe('visible');
window.scrollTo(0, $('#simple-4').offset().top - winHeight + 150);
return setTimeout(function() {
expect($('#simple-4')).toHaveClass('animated');
expect($('#simple-4').css('visibility')).toBe('visible');
return done();
}, timeout);
}, timeout);
});
it('does not tamper with the style attribute', function(done) {
window.scrollTo(0, $('#simple-5').offset().top - winHeight + 150);
return setTimeout(function() {
expect($('#simple-5')).toHaveClass('animated');
expect($('#simple-5').css('visibility')).toBe('visible');
expect($('#simple-5')[0].style.background).toBe('yellow');
expect($('#simple-5')[0].style.color).toBe('red');
return done();
}, timeout);
});
it('works with asynchronously loaded content', function(done) {
$('#simple').append($('<div/>', {
id: 'simple-6',
"class": 'wow'
}));
wow.sync();
window.scrollTo(0, $('#simple-6').offset().top - winHeight + 150);
return setTimeout(function() {
expect($('#simple-6')).toHaveClass('animated');
expect($('#simple-6').css('visibility')).toBe('visible');
return done();
}, timeout);
});
return it('works with asynchronously loaded nested content', function(done) {
$('#simple').append($('<div/>')).children().first().append($('<div/>', {
id: 'simple-7',
"class": 'wow'
}));
wow.sync();
window.scrollTo(0, $('#simple-7').offset().top - winHeight + 150);
return setTimeout(function() {
expect($('#simple-7')).toHaveClass('animated');
expect($('#simple-7').css('visibility')).toBe('visible');
return done();
}, timeout);
});
});
describe('custom test environment', function() {
beforeEach(function() {
return loadFixtures('custom.html');
});
it('emulates window height', function() {
return expect(document.documentElement.clientHeight).toBe(winHeight);
});
return it('has boxes set up for testing', function() {
var offset;
expect($('#custom').height()).toBe(800);
expect($('#custom-1').height()).toBe(200);
expect($('#custom-2').height()).toBe(200);
expect($('#custom-3').height()).toBe(200);
expect($('#custom-4').height()).toBe(200);
offset = $('#custom').offset().top;
expect($('#custom-1').offset().top).toBe(offset + 200 * 0);
expect($('#custom-2').offset().top).toBe(offset + 200 * 1);
expect($('#custom-3').offset().top).toBe(offset + 200 * 2);
return expect($('#custom-4').offset().top).toBe(offset + 200 * 3);
});
});
return describe('library behaviour with custom settings', function() {
var called;
called = false;
beforeEach(function(done) {
called = false;
loadFixtures('custom.html');
new WOW({
boxClass: 'block',
animateClass: 'fancy',
offset: 10,
callback: function() {
return called = true;
}
}).init();
$('.block').on('block', function() {
return $(this).addClass('triggered');
});
return setTimeout(function() {
return done();
}, timeout);
});
it("creates two instances of the WOW.js with different configs", function() {
var wow1, wow2;
wow1 = new WOW({
boxClass: 'block1',
animateClass: 'fancy1',
offset: 10
});
wow2 = new WOW({
boxClass: 'block2',
animateClass: 'fancy2',
offset: 20
});
expect(wow1.config.boxClass).toBe("block1");
expect(wow1.config.animateClass).toBe("fancy1");
return expect(wow1.config.offset).toBe(10);
});
it("does not touch elements that don't have the marker class", function(done) {
window.scrollTo(0, $('#custom-1').offset().top - winHeight + 15);
return setTimeout(function() {
expect($('#custom-1')).not.toHaveClass('fancy');
return done();
}, timeout);
});
it("animates elements that are partially visible on the page based on the 'offset' config", function(done) {
return setTimeout(function() {
window.scrollTo(0, $('#custom-2').offset().top - winHeight + 5);
expect($('#custom-2')).not.toHaveClass('fancy');
window.scrollTo(0, $('#custom-2').offset().top - winHeight + 15);
return setTimeout(function() {
expect($('#custom-2')).toHaveClass('fancy');
expect($('#custom-2').css('visibility')).toBe('visible');
return done();
}, timeout);
}, timeout);
});
it('does not animate elements not yet visible on the page', function() {
expect($('#custom-3')).not.toHaveClass('fancy');
return expect($('#custom-4')).not.toHaveClass('fancy');
});
it('animates elements after scrolling down and they become visible', function(done) {
window.scrollTo(0, $('#custom-3').offset().top - winHeight + 150);
return setTimeout(function() {
expect($('#custom-3')).toHaveClass('fancy');
expect($('#custom-3').css('visibility')).toBe('visible');
expect($('#custom-3')[0].style.webkitAnimationIterationCount).toBe('2');
expect($('#custom-4')).not.toHaveClass('fancy');
window.scrollTo(0, $('#custom-4').offset().top - winHeight + 150);
return setTimeout(function() {
expect($('#custom-4')).toHaveClass('fancy');
expect($('#custom-4').css('visibility')).toBe('visible');
expect($('#custom-4')[0].style.webkitAnimationIterationCount).toBe('infinite');
expect($('#custom-4')[0].style.webkitAnimationDuration).toBe('2s');
expect($('#custom-4')[0].style.webkitAnimationDelay).toBe('1s');
return done();
}, timeout);
}, timeout);
});
it("fires the callback", function(done) {
called = false;
window.scrollTo(0, $('#custom-3').offset().top - winHeight + 150);
return setTimeout(function() {
expect(called).toBe(true);
return done();
}, timeout);
});
return it('fires the callback on the visible element', function(done) {
window.scrollTo(0, $('#custom-3').offset().top - winHeight + 150);
return setTimeout(function() {
expect($('#custom-3')).toHaveClass('triggered');
expect($('#custom-4')).not.toHaveClass('triggered');
window.scrollTo(0, $('#custom-4').offset().top - winHeight + 150);
return setTimeout(function() {
expect($('#custom-3')).toHaveClass('triggered');
expect($('#custom-4')).toHaveClass('triggered');
return done();
}, timeout);
}, timeout);
});
});
});
}).call(this);

View file

@ -1,15 +1,15 @@
{
"parser": "babel-eslint",
"extends": "airbnb-base",
"rules": {
"arrow-parens": [2, "as-needed"],
"curly": [2, "all"],
"no-param-reassign": 0,
"no-restricted-syntax": [
2,
"DebuggerStatement",
"LabeledStatement",
"WithStatement"
]
}
}
{
"parser": "babel-eslint",
"extends": "airbnb-base",
"rules": {
"arrow-parens": [2, "as-needed"],
"curly": [2, "all"],
"no-param-reassign": 0,
"no-restricted-syntax": [
2,
"DebuggerStatement",
"LabeledStatement",
"WithStatement"
]
}
}

824
node_modules/wow.js/src/WOW.js generated vendored
View file

@ -1,412 +1,412 @@
function isIn(needle, haystack) {
return haystack.indexOf(needle) >= 0;
}
function extend(custom, defaults) {
for (const key in defaults) {
if (custom[key] == null) {
const value = defaults[key];
custom[key] = value;
}
}
return custom;
}
function isMobile(agent) {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(agent);
}
function createEvent(event, bubble = false, cancel = false, detail = null) {
let customEvent;
if (document.createEvent != null) { // W3C DOM
customEvent = document.createEvent('CustomEvent');
customEvent.initCustomEvent(event, bubble, cancel, detail);
} else if (document.createEventObject != null) { // IE DOM < 9
customEvent = document.createEventObject();
customEvent.eventType = event;
} else {
customEvent.eventName = event;
}
return customEvent;
}
function emitEvent(elem, event) {
if (elem.dispatchEvent != null) { // W3C DOM
elem.dispatchEvent(event);
} else if (event in (elem != null)) {
elem[event]();
} else if (`on${event}` in (elem != null)) {
elem[`on${event}`]();
}
}
function addEvent(elem, event, fn) {
if (elem.addEventListener != null) { // W3C DOM
elem.addEventListener(event, fn, false);
} else if (elem.attachEvent != null) { // IE DOM
elem.attachEvent(`on${event}`, fn);
} else { // fallback
elem[event] = fn;
}
}
function removeEvent(elem, event, fn) {
if (elem.removeEventListener != null) { // W3C DOM
elem.removeEventListener(event, fn, false);
} else if (elem.detachEvent != null) { // IE DOM
elem.detachEvent(`on${event}`, fn);
} else { // fallback
delete elem[event];
}
}
function getInnerHeight() {
if ('innerHeight' in window) {
return window.innerHeight;
}
return document.documentElement.clientHeight;
}
// Minimalistic WeakMap shim, just in case.
const WeakMap = window.WeakMap || window.MozWeakMap ||
class WeakMap {
constructor() {
this.keys = [];
this.values = [];
}
get(key) {
for (let i = 0; i < this.keys.length; i++) {
const item = this.keys[i];
if (item === key) {
return this.values[i];
}
}
return undefined;
}
set(key, value) {
for (let i = 0; i < this.keys.length; i++) {
const item = this.keys[i];
if (item === key) {
this.values[i] = value;
return this;
}
}
this.keys.push(key);
this.values.push(value);
return this;
}
};
// Dummy MutationObserver, to avoid raising exceptions.
const MutationObserver =
window.MutationObserver || window.WebkitMutationObserver ||
window.MozMutationObserver ||
class MutationObserver {
constructor() {
if (typeof console !== 'undefined' && console !== null) {
console.warn('MutationObserver is not supported by your browser.');
console.warn(
'WOW.js cannot detect dom mutations, please call .sync() after loading new content.'
);
}
}
static notSupported = true;
observe() {}
};
// getComputedStyle shim, from http://stackoverflow.com/a/21797294
const getComputedStyle = window.getComputedStyle ||
function getComputedStyle(el) {
const getComputedStyleRX = /(\-([a-z]){1})/g;
return {
getPropertyValue(prop) {
if (prop === 'float') { prop = 'styleFloat'; }
if (getComputedStyleRX.test(prop)) {
prop.replace(getComputedStyleRX, (_, _char) => _char.toUpperCase());
}
const { currentStyle } = el;
return (currentStyle != null ? currentStyle[prop] : void 0) || null;
},
};
};
export default class WOW {
defaults = {
boxClass: 'wow',
animateClass: 'animated',
offset: 0,
mobile: true,
live: true,
callback: null,
scrollContainer: null,
};
constructor(options = {}) {
this.start = this.start.bind(this);
this.resetAnimation = this.resetAnimation.bind(this);
this.scrollHandler = this.scrollHandler.bind(this);
this.scrollCallback = this.scrollCallback.bind(this);
this.scrolled = true;
this.config = extend(options, this.defaults);
if (options.scrollContainer != null) {
this.config.scrollContainer = document.querySelector(options.scrollContainer);
}
// Map of elements to animation names:
this.animationNameCache = new WeakMap();
this.wowEvent = createEvent(this.config.boxClass);
}
init() {
this.element = window.document.documentElement;
if (isIn(document.readyState, ['interactive', 'complete'])) {
this.start();
} else {
addEvent(document, 'DOMContentLoaded', this.start);
}
this.finished = [];
}
start() {
this.stopped = false;
this.boxes = [].slice.call(this.element.querySelectorAll(`.${this.config.boxClass}`));
this.all = this.boxes.slice(0);
if (this.boxes.length) {
if (this.disabled()) {
this.resetStyle();
} else {
for (let i = 0; i < this.boxes.length; i++) {
const box = this.boxes[i];
this.applyStyle(box, true);
}
}
}
if (!this.disabled()) {
addEvent(this.config.scrollContainer || window, 'scroll', this.scrollHandler);
addEvent(window, 'resize', this.scrollHandler);
this.interval = setInterval(this.scrollCallback, 50);
}
if (this.config.live) {
const mut = new MutationObserver(records => {
for (let j = 0; j < records.length; j++) {
const record = records[j];
for (let k = 0; k < record.addedNodes.length; k++) {
const node = record.addedNodes[k];
this.doSync(node);
}
}
return undefined;
});
mut.observe(document.body, {
childList: true,
subtree: true,
});
}
}
// unbind the scroll event
stop() {
this.stopped = true;
removeEvent(this.config.scrollContainer || window, 'scroll', this.scrollHandler);
removeEvent(window, 'resize', this.scrollHandler);
if (this.interval != null) {
clearInterval(this.interval);
}
}
sync() {
if (MutationObserver.notSupported) {
this.doSync(this.element);
}
}
doSync(element) {
if (typeof element === 'undefined' || element === null) { ({ element } = this); }
if (element.nodeType !== 1) { return; }
element = element.parentNode || element;
const iterable = element.querySelectorAll(`.${this.config.boxClass}`);
for (let i = 0; i < iterable.length; i++) {
const box = iterable[i];
if (!isIn(box, this.all)) {
this.boxes.push(box);
this.all.push(box);
if (this.stopped || this.disabled()) {
this.resetStyle();
} else {
this.applyStyle(box, true);
}
this.scrolled = true;
}
}
}
// show box element
show(box) {
this.applyStyle(box);
box.className = `${box.className} ${this.config.animateClass}`;
if (this.config.callback != null) { this.config.callback(box); }
emitEvent(box, this.wowEvent);
addEvent(box, 'animationend', this.resetAnimation);
addEvent(box, 'oanimationend', this.resetAnimation);
addEvent(box, 'webkitAnimationEnd', this.resetAnimation);
addEvent(box, 'MSAnimationEnd', this.resetAnimation);
return box;
}
applyStyle(box, hidden) {
const duration = box.getAttribute('data-wow-duration');
const delay = box.getAttribute('data-wow-delay');
const iteration = box.getAttribute('data-wow-iteration');
return this.animate(() => this.customStyle(box, hidden, duration, delay, iteration));
}
animate = (function animateFactory() {
if ('requestAnimationFrame' in window) {
return callback => window.requestAnimationFrame(callback);
}
return callback => callback();
}());
resetStyle() {
for (let i = 0; i < this.boxes.length; i++) {
const box = this.boxes[i];
box.style.visibility = 'visible';
}
return undefined;
}
resetAnimation(event) {
if (event.type.toLowerCase().indexOf('animationend') >= 0) {
const target = event.target || event.srcElement;
target.className = target.className.replace(this.config.animateClass, '').trim();
}
}
customStyle(box, hidden, duration, delay, iteration) {
if (hidden) { this.cacheAnimationName(box); }
box.style.visibility = hidden ? 'hidden' : 'visible';
if (duration) { this.vendorSet(box.style, { animationDuration: duration }); }
if (delay) { this.vendorSet(box.style, { animationDelay: delay }); }
if (iteration) { this.vendorSet(box.style, { animationIterationCount: iteration }); }
this.vendorSet(box.style, { animationName: hidden ? 'none' : this.cachedAnimationName(box) });
return box;
}
vendors = ['moz', 'webkit'];
vendorSet(elem, properties) {
for (const name in properties) {
if (properties.hasOwnProperty(name)) {
const value = properties[name];
elem[`${name}`] = value;
for (let i = 0; i < this.vendors.length; i++) {
const vendor = this.vendors[i];
elem[`${vendor}${name.charAt(0).toUpperCase()}${name.substr(1)}`] = value;
}
}
}
}
vendorCSS(elem, property) {
const style = getComputedStyle(elem);
let result = style.getPropertyCSSValue(property);
for (let i = 0; i < this.vendors.length; i++) {
const vendor = this.vendors[i];
result = result || style.getPropertyCSSValue(`-${vendor}-${property}`);
}
return result;
}
animationName(box) {
let aName;
try {
aName = this.vendorCSS(box, 'animation-name').cssText;
} catch (error) { // Opera, fall back to plain property value
aName = getComputedStyle(box).getPropertyValue('animation-name');
}
if (aName === 'none') {
return ''; // SVG/Firefox, unable to get animation name?
}
return aName;
}
cacheAnimationName(box) {
// https://bugzilla.mozilla.org/show_bug.cgi?id=921834
// box.dataset is not supported for SVG elements in Firefox
return this.animationNameCache.set(box, this.animationName(box));
}
cachedAnimationName(box) {
return this.animationNameCache.get(box);
}
// fast window.scroll callback
scrollHandler() {
this.scrolled = true;
}
scrollCallback() {
if (this.scrolled) {
this.scrolled = false;
const results = [];
for (let i = 0; i < this.boxes.length; i++) {
const box = this.boxes[i];
if (box) {
if (this.isVisible(box)) {
this.show(box);
continue;
}
results.push(box);
}
}
this.boxes = results;
if (!this.boxes.length && !this.config.live) {
this.stop();
}
}
}
// Calculate element offset top
offsetTop(element) {
// SVG elements don't have an offsetTop in Firefox.
// This will use their nearest parent that has an offsetTop.
// Also, using ('offsetTop' of element) causes an exception in Firefox.
while (element.offsetTop === undefined) {
element = element.parentNode;
}
let top = element.offsetTop;
while (element.offsetParent) {
element = element.offsetParent;
top += element.offsetTop;
}
return top;
}
// check if box is visible
isVisible(box) {
const offset = box.getAttribute('data-wow-offset') || this.config.offset;
const viewTop = (
this.config.scrollContainer && this.config.scrollContainer.scrollTop
) || window.pageYOffset;
const viewBottom =
viewTop + Math.min(this.element.clientHeight, getInnerHeight()) - offset;
const top = this.offsetTop(box);
const bottom = top + box.clientHeight;
return top <= viewBottom && bottom >= viewTop;
}
disabled() {
return !this.config.mobile && isMobile(navigator.userAgent);
}
}
function isIn(needle, haystack) {
return haystack.indexOf(needle) >= 0;
}
function extend(custom, defaults) {
for (const key in defaults) {
if (custom[key] == null) {
const value = defaults[key];
custom[key] = value;
}
}
return custom;
}
function isMobile(agent) {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(agent);
}
function createEvent(event, bubble = false, cancel = false, detail = null) {
let customEvent;
if (document.createEvent != null) { // W3C DOM
customEvent = document.createEvent('CustomEvent');
customEvent.initCustomEvent(event, bubble, cancel, detail);
} else if (document.createEventObject != null) { // IE DOM < 9
customEvent = document.createEventObject();
customEvent.eventType = event;
} else {
customEvent.eventName = event;
}
return customEvent;
}
function emitEvent(elem, event) {
if (elem.dispatchEvent != null) { // W3C DOM
elem.dispatchEvent(event);
} else if (event in (elem != null)) {
elem[event]();
} else if (`on${event}` in (elem != null)) {
elem[`on${event}`]();
}
}
function addEvent(elem, event, fn) {
if (elem.addEventListener != null) { // W3C DOM
elem.addEventListener(event, fn, false);
} else if (elem.attachEvent != null) { // IE DOM
elem.attachEvent(`on${event}`, fn);
} else { // fallback
elem[event] = fn;
}
}
function removeEvent(elem, event, fn) {
if (elem.removeEventListener != null) { // W3C DOM
elem.removeEventListener(event, fn, false);
} else if (elem.detachEvent != null) { // IE DOM
elem.detachEvent(`on${event}`, fn);
} else { // fallback
delete elem[event];
}
}
function getInnerHeight() {
if ('innerHeight' in window) {
return window.innerHeight;
}
return document.documentElement.clientHeight;
}
// Minimalistic WeakMap shim, just in case.
const WeakMap = window.WeakMap || window.MozWeakMap ||
class WeakMap {
constructor() {
this.keys = [];
this.values = [];
}
get(key) {
for (let i = 0; i < this.keys.length; i++) {
const item = this.keys[i];
if (item === key) {
return this.values[i];
}
}
return undefined;
}
set(key, value) {
for (let i = 0; i < this.keys.length; i++) {
const item = this.keys[i];
if (item === key) {
this.values[i] = value;
return this;
}
}
this.keys.push(key);
this.values.push(value);
return this;
}
};
// Dummy MutationObserver, to avoid raising exceptions.
const MutationObserver =
window.MutationObserver || window.WebkitMutationObserver ||
window.MozMutationObserver ||
class MutationObserver {
constructor() {
if (typeof console !== 'undefined' && console !== null) {
console.warn('MutationObserver is not supported by your browser.');
console.warn(
'WOW.js cannot detect dom mutations, please call .sync() after loading new content.'
);
}
}
static notSupported = true;
observe() {}
};
// getComputedStyle shim, from http://stackoverflow.com/a/21797294
const getComputedStyle = window.getComputedStyle ||
function getComputedStyle(el) {
const getComputedStyleRX = /(\-([a-z]){1})/g;
return {
getPropertyValue(prop) {
if (prop === 'float') { prop = 'styleFloat'; }
if (getComputedStyleRX.test(prop)) {
prop.replace(getComputedStyleRX, (_, _char) => _char.toUpperCase());
}
const { currentStyle } = el;
return (currentStyle != null ? currentStyle[prop] : void 0) || null;
},
};
};
export default class WOW {
defaults = {
boxClass: 'wow',
animateClass: 'animated',
offset: 0,
mobile: true,
live: true,
callback: null,
scrollContainer: null,
};
constructor(options = {}) {
this.start = this.start.bind(this);
this.resetAnimation = this.resetAnimation.bind(this);
this.scrollHandler = this.scrollHandler.bind(this);
this.scrollCallback = this.scrollCallback.bind(this);
this.scrolled = true;
this.config = extend(options, this.defaults);
if (options.scrollContainer != null) {
this.config.scrollContainer = document.querySelector(options.scrollContainer);
}
// Map of elements to animation names:
this.animationNameCache = new WeakMap();
this.wowEvent = createEvent(this.config.boxClass);
}
init() {
this.element = window.document.documentElement;
if (isIn(document.readyState, ['interactive', 'complete'])) {
this.start();
} else {
addEvent(document, 'DOMContentLoaded', this.start);
}
this.finished = [];
}
start() {
this.stopped = false;
this.boxes = [].slice.call(this.element.querySelectorAll(`.${this.config.boxClass}`));
this.all = this.boxes.slice(0);
if (this.boxes.length) {
if (this.disabled()) {
this.resetStyle();
} else {
for (let i = 0; i < this.boxes.length; i++) {
const box = this.boxes[i];
this.applyStyle(box, true);
}
}
}
if (!this.disabled()) {
addEvent(this.config.scrollContainer || window, 'scroll', this.scrollHandler);
addEvent(window, 'resize', this.scrollHandler);
this.interval = setInterval(this.scrollCallback, 50);
}
if (this.config.live) {
const mut = new MutationObserver(records => {
for (let j = 0; j < records.length; j++) {
const record = records[j];
for (let k = 0; k < record.addedNodes.length; k++) {
const node = record.addedNodes[k];
this.doSync(node);
}
}
return undefined;
});
mut.observe(document.body, {
childList: true,
subtree: true,
});
}
}
// unbind the scroll event
stop() {
this.stopped = true;
removeEvent(this.config.scrollContainer || window, 'scroll', this.scrollHandler);
removeEvent(window, 'resize', this.scrollHandler);
if (this.interval != null) {
clearInterval(this.interval);
}
}
sync() {
if (MutationObserver.notSupported) {
this.doSync(this.element);
}
}
doSync(element) {
if (typeof element === 'undefined' || element === null) { ({ element } = this); }
if (element.nodeType !== 1) { return; }
element = element.parentNode || element;
const iterable = element.querySelectorAll(`.${this.config.boxClass}`);
for (let i = 0; i < iterable.length; i++) {
const box = iterable[i];
if (!isIn(box, this.all)) {
this.boxes.push(box);
this.all.push(box);
if (this.stopped || this.disabled()) {
this.resetStyle();
} else {
this.applyStyle(box, true);
}
this.scrolled = true;
}
}
}
// show box element
show(box) {
this.applyStyle(box);
box.className = `${box.className} ${this.config.animateClass}`;
if (this.config.callback != null) { this.config.callback(box); }
emitEvent(box, this.wowEvent);
addEvent(box, 'animationend', this.resetAnimation);
addEvent(box, 'oanimationend', this.resetAnimation);
addEvent(box, 'webkitAnimationEnd', this.resetAnimation);
addEvent(box, 'MSAnimationEnd', this.resetAnimation);
return box;
}
applyStyle(box, hidden) {
const duration = box.getAttribute('data-wow-duration');
const delay = box.getAttribute('data-wow-delay');
const iteration = box.getAttribute('data-wow-iteration');
return this.animate(() => this.customStyle(box, hidden, duration, delay, iteration));
}
animate = (function animateFactory() {
if ('requestAnimationFrame' in window) {
return callback => window.requestAnimationFrame(callback);
}
return callback => callback();
}());
resetStyle() {
for (let i = 0; i < this.boxes.length; i++) {
const box = this.boxes[i];
box.style.visibility = 'visible';
}
return undefined;
}
resetAnimation(event) {
if (event.type.toLowerCase().indexOf('animationend') >= 0) {
const target = event.target || event.srcElement;
target.className = target.className.replace(this.config.animateClass, '').trim();
}
}
customStyle(box, hidden, duration, delay, iteration) {
if (hidden) { this.cacheAnimationName(box); }
box.style.visibility = hidden ? 'hidden' : 'visible';
if (duration) { this.vendorSet(box.style, { animationDuration: duration }); }
if (delay) { this.vendorSet(box.style, { animationDelay: delay }); }
if (iteration) { this.vendorSet(box.style, { animationIterationCount: iteration }); }
this.vendorSet(box.style, { animationName: hidden ? 'none' : this.cachedAnimationName(box) });
return box;
}
vendors = ['moz', 'webkit'];
vendorSet(elem, properties) {
for (const name in properties) {
if (properties.hasOwnProperty(name)) {
const value = properties[name];
elem[`${name}`] = value;
for (let i = 0; i < this.vendors.length; i++) {
const vendor = this.vendors[i];
elem[`${vendor}${name.charAt(0).toUpperCase()}${name.substr(1)}`] = value;
}
}
}
}
vendorCSS(elem, property) {
const style = getComputedStyle(elem);
let result = style.getPropertyCSSValue(property);
for (let i = 0; i < this.vendors.length; i++) {
const vendor = this.vendors[i];
result = result || style.getPropertyCSSValue(`-${vendor}-${property}`);
}
return result;
}
animationName(box) {
let aName;
try {
aName = this.vendorCSS(box, 'animation-name').cssText;
} catch (error) { // Opera, fall back to plain property value
aName = getComputedStyle(box).getPropertyValue('animation-name');
}
if (aName === 'none') {
return ''; // SVG/Firefox, unable to get animation name?
}
return aName;
}
cacheAnimationName(box) {
// https://bugzilla.mozilla.org/show_bug.cgi?id=921834
// box.dataset is not supported for SVG elements in Firefox
return this.animationNameCache.set(box, this.animationName(box));
}
cachedAnimationName(box) {
return this.animationNameCache.get(box);
}
// fast window.scroll callback
scrollHandler() {
this.scrolled = true;
}
scrollCallback() {
if (this.scrolled) {
this.scrolled = false;
const results = [];
for (let i = 0; i < this.boxes.length; i++) {
const box = this.boxes[i];
if (box) {
if (this.isVisible(box)) {
this.show(box);
continue;
}
results.push(box);
}
}
this.boxes = results;
if (!this.boxes.length && !this.config.live) {
this.stop();
}
}
}
// Calculate element offset top
offsetTop(element) {
// SVG elements don't have an offsetTop in Firefox.
// This will use their nearest parent that has an offsetTop.
// Also, using ('offsetTop' of element) causes an exception in Firefox.
while (element.offsetTop === undefined) {
element = element.parentNode;
}
let top = element.offsetTop;
while (element.offsetParent) {
element = element.offsetParent;
top += element.offsetTop;
}
return top;
}
// check if box is visible
isVisible(box) {
const offset = box.getAttribute('data-wow-offset') || this.config.offset;
const viewTop = (
this.config.scrollContainer && this.config.scrollContainer.scrollTop
) || window.pageYOffset;
const viewBottom =
viewTop + Math.min(this.element.clientHeight, getInnerHeight()) - offset;
const top = this.offsetTop(box);
const bottom = top + box.clientHeight;
return top <= viewBottom && bottom >= viewTop;
}
disabled() {
return !this.config.mobile && isMobile(navigator.userAgent);
}
}