anijs-rails 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +2 -0
- data/anijs-rails.gemspec +25 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/anijs/rails.rb +8 -0
- data/lib/anijs/rails/version.rb +5 -0
- data/vendor/assets/javascripts/anijs-helper-dom.js +514 -0
- data/vendor/assets/javascripts/anijs-helper-scrollreveal.js +133 -0
- data/vendor/assets/javascripts/anijs-jquery-event-system.js +64 -0
- data/vendor/assets/javascripts/anijs-min.js +1 -0
- data/vendor/assets/javascripts/anijs.js +1493 -0
- data/vendor/assets/stylesheets/anicollection.css +4686 -0
- metadata +89 -0
@@ -0,0 +1,133 @@
|
|
1
|
+
/*!
|
2
|
+
AniJS - http://anijs.github.io
|
3
|
+
Licensed under the MIT license
|
4
|
+
|
5
|
+
Copyright (c) 2014 Dariel Noel <darielnoel@gmail.com>
|
6
|
+
|
7
|
+
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:
|
8
|
+
|
9
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
10
|
+
|
11
|
+
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.
|
12
|
+
*/
|
13
|
+
|
14
|
+
/**
|
15
|
+
* AniJS ScrollReview Helper
|
16
|
+
*/
|
17
|
+
(function() {
|
18
|
+
|
19
|
+
//Obtaining the default helper
|
20
|
+
var AniJSDefaultHelper = AniJS.getHelper();
|
21
|
+
|
22
|
+
/**
|
23
|
+
* Creating a testing scroll before function
|
24
|
+
* @method scrollReveal
|
25
|
+
* @param {} e
|
26
|
+
* @param {} animationContext
|
27
|
+
* @return
|
28
|
+
*/
|
29
|
+
AniJSDefaultHelper.scrollReveal = function(e, animationContext, params) {
|
30
|
+
var viewportRatio = 0.07;
|
31
|
+
//Current elements that will be animated
|
32
|
+
animationContextBehaviorTargetList = animationContext.behaviorTargetList;
|
33
|
+
|
34
|
+
// The revealed function will be executed just one time
|
35
|
+
if(params.length < 2 && params[0] !== 'repeat' && animationContext.after.length < 1){
|
36
|
+
animationContext.after = [AniJS.getHelper().fireOnce];
|
37
|
+
}
|
38
|
+
|
39
|
+
if(!isNaN(parseFloat(params[0]))){
|
40
|
+
viewportRatio = params[0];
|
41
|
+
}
|
42
|
+
|
43
|
+
for (var i = 0; i < animationContextBehaviorTargetList.length; i++) {
|
44
|
+
element = animationContextBehaviorTargetList[i];
|
45
|
+
|
46
|
+
//Check if the element is visible
|
47
|
+
if (ScrollRevealHelper.isElementInViewport(element, viewportRatio)) {
|
48
|
+
|
49
|
+
//The element is not animated again if it's visible
|
50
|
+
if (!element.isRevealed) {
|
51
|
+
element.isRevealed = 1;
|
52
|
+
animationContext.run();
|
53
|
+
}
|
54
|
+
|
55
|
+
} else {
|
56
|
+
element.isRevealed = 0;
|
57
|
+
}
|
58
|
+
}
|
59
|
+
};
|
60
|
+
|
61
|
+
/**
|
62
|
+
* Helper the custom EventTarget
|
63
|
+
* ! scrollReveal.js v0.1.2 (c) 2014 Julian Lloyd
|
64
|
+
* MIT License
|
65
|
+
* https://github.com/julianlloyd/scrollReveal.js
|
66
|
+
* @class ScrollRevealHelper
|
67
|
+
*/
|
68
|
+
var ScrollRevealHelper = {
|
69
|
+
|
70
|
+
//ATTRS
|
71
|
+
|
72
|
+
//TODO: This attrs should be customizable
|
73
|
+
viewportFactor: 1,
|
74
|
+
docElem: window.document.documentElement,
|
75
|
+
|
76
|
+
/**
|
77
|
+
* Return true if the element if visible in a viewport zone
|
78
|
+
* @method isElementInViewport
|
79
|
+
* @param {} el
|
80
|
+
* @param {} h
|
81
|
+
* @return LogicalExpression
|
82
|
+
*/
|
83
|
+
isElementInViewport: function(el, h) {
|
84
|
+
var scrolled = window.pageYOffset,
|
85
|
+
viewed = scrolled + this._getViewportH(),
|
86
|
+
elH = el.offsetHeight,
|
87
|
+
elTop = this._getOffset(el).top,
|
88
|
+
elBottom = elTop + elH,
|
89
|
+
h = h || 0;
|
90
|
+
|
91
|
+
return (elTop + elH * h) <= viewed && (elBottom) >= scrolled || (el.currentStyle ? el.currentStyle : window.getComputedStyle(el, null)).position == 'fixed';
|
92
|
+
},
|
93
|
+
|
94
|
+
/**
|
95
|
+
* Obtaining the viewport height
|
96
|
+
* @method _getViewportH
|
97
|
+
* @return ConditionalExpression
|
98
|
+
*/
|
99
|
+
_getViewportH: function() {
|
100
|
+
var client = this.docElem.clientHeight,
|
101
|
+
inner = window.innerHeight;
|
102
|
+
|
103
|
+
return (client < inner) ? inner : client;
|
104
|
+
},
|
105
|
+
|
106
|
+
/**
|
107
|
+
* The offset of the element
|
108
|
+
* @method _getOffset
|
109
|
+
* @param {} el
|
110
|
+
* @return ObjectExpression
|
111
|
+
*/
|
112
|
+
_getOffset: function(el) {
|
113
|
+
var offsetTop = 0,
|
114
|
+
offsetLeft = 0;
|
115
|
+
|
116
|
+
do {
|
117
|
+
if (!isNaN(el.offsetTop)) {
|
118
|
+
offsetTop += el.offsetTop;
|
119
|
+
}
|
120
|
+
if (!isNaN(el.offsetLeft)) {
|
121
|
+
offsetLeft += el.offsetLeft;
|
122
|
+
}
|
123
|
+
} while (el = el.offsetParent)
|
124
|
+
|
125
|
+
return {
|
126
|
+
top: offsetTop,
|
127
|
+
left: offsetLeft
|
128
|
+
}
|
129
|
+
}
|
130
|
+
};
|
131
|
+
window.scroll(window.scrollX, window.scrollY+1);
|
132
|
+
|
133
|
+
}(window));
|
@@ -0,0 +1,64 @@
|
|
1
|
+
/*!
|
2
|
+
AniJS - http://anijs.github.io
|
3
|
+
Licensed under the MIT license
|
4
|
+
|
5
|
+
Copyright (c) 2014 Dariel Noel <darielnoel@gmail.com>
|
6
|
+
|
7
|
+
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:
|
8
|
+
|
9
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
10
|
+
|
11
|
+
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.
|
12
|
+
*/
|
13
|
+
|
14
|
+
/**
|
15
|
+
* JQuery Event System Interface
|
16
|
+
*/
|
17
|
+
(function() {
|
18
|
+
var JQueryEventSystem = AniJS.EventSystem;
|
19
|
+
|
20
|
+
/**
|
21
|
+
* Overwriting isEventTarget method
|
22
|
+
* @method isEventTarget
|
23
|
+
* @param {} element
|
24
|
+
* @return ConditionalExpression
|
25
|
+
*/
|
26
|
+
AniJS.EventSystem.isEventTarget = function(element) {
|
27
|
+
return (element.trigger) ? 1 : 0;
|
28
|
+
};
|
29
|
+
|
30
|
+
/**
|
31
|
+
* Overwriting createEventTarget method
|
32
|
+
* @method createEventTarget
|
33
|
+
* @return CallExpression
|
34
|
+
*/
|
35
|
+
AniJS.EventSystem.createEventTarget = function() {
|
36
|
+
return $({});
|
37
|
+
};
|
38
|
+
|
39
|
+
/**
|
40
|
+
* Overwriting addEventListenerHelper method
|
41
|
+
* @method addEventListenerHelper
|
42
|
+
* @param {} eventTargetItem
|
43
|
+
* @param {} event
|
44
|
+
* @param {} listener
|
45
|
+
* @param {} other
|
46
|
+
* @return
|
47
|
+
*/
|
48
|
+
AniJS.EventSystem.addEventListenerHelper = function(eventTargetItem, event, listener, other) {
|
49
|
+
$(eventTargetItem).on(event, listener);
|
50
|
+
};
|
51
|
+
|
52
|
+
/**
|
53
|
+
* Overwriting removeEventListenerHelper method
|
54
|
+
* @method removeEventListenerHelper
|
55
|
+
* @param {} e
|
56
|
+
* @param {} arguments
|
57
|
+
* @return
|
58
|
+
*/
|
59
|
+
AniJS.EventSystem.removeEventListenerHelper = function(element, type, listener) {
|
60
|
+
$(element).off(type, listener);
|
61
|
+
};
|
62
|
+
|
63
|
+
|
64
|
+
}(window));
|
@@ -0,0 +1 @@
|
|
1
|
+
!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("AniJS-RWWD");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=function(b){var c="data-anijs",d="default",e="|",f="$",g="if",h="on",i=["do","after","before","to"],j="(\\s+|^)",k="(\\s+|$)",l="animationend",m="transitionend",n="target";b={rootDOMTravelScope:{},notifierCollection:{},init:function(){o._t={};var a=o._a();b.registerHelper(d,a),o._u=d,b.rootDOMTravelScope=document,b.Parser=o.Parser,o._v=o._p(),o._w=""},setDOMRootTravelScope:function(a){var c,d=document;try{"document"===a?c=d:(c=d.querySelector(a),c||(c=d))}catch(e){c=d}b.rootDOMTravelScope=c},run:function(){var a=[],d={};b.purgeAll(),b.notifierCollection={},a=o._o(b.rootDOMTravelScope);var e,f=a.length,g=0;for(g;f>g;g++)e=a[g],d=o._n(e.getAttribute(c)),o._c(e,d);var h=b.getNotifier("AniJSNotifier");h&&h.dispatchEvent("onRunFinished")},createAnimation:function(a,b){var c=b||"";o._c(c,a)},getHelper:function(a){var b=o._t;return b[a]||b[d]},registerHelper:function(a,b){o._t[a]=b},purge:function(a){if(a&&""!==a&&" "!==a){var c=document.querySelectorAll(a),d=c.length,e=0;for(e;d>e;e++)b.EventSystem.purgeEventTarget(c[e])}},purgeAll:function(){b.EventSystem.purgeAll()},purgeEventTarget:function(a){b.EventSystem.purgeEventTarget(a)},setClassNamesWhenAnim:function(a){o._w=" "+a},createNotifier:function(){return b.EventSystem.createEventTarget()},registerNotifier:function(a){var c=b.notifierCollection;return a.id&&a.value&&b.EventSystem.isEventTarget(a.value)?(c[a.id]=a.value,1):""},getNotifier:function(a){return b.notifierCollection[a]}};var o={};return o._a=function(){var a={removeAnim:function(a,b){a.target&&a.type&&b.nodeHelper.removeClass(a.target,b.behavior)},holdAnimClass:function(){},fireOnce:function(a,b){b.eventSystem.removeEventListenerHelper(b.eventTarget,b.event.type,b.listener)},emit:function(a,c,d){var e=d[0]||null,f="";if(null!==e){e=e.split("."),e.length>1?(f=e[0],e=e[1]):(f="",e=e[0]);var g=b.getNotifier(f)||null;null!==g&&g.dispatchEvent(e)}c.hasRunned||c.run()}};return a},o._b=function(){return new Parser},o._c=function(a,b){var c,d,e,f,g=b.length,h=0;for(h;g>h;h++)c=b[h],e=c.after,d=c.before,f=c.behavior,e&&(c.after=o.Parser.parseDoDefinition(e)),d&&(c.before=o.Parser.parseDoDefinition(d)),f&&(c.behavior=o.Parser.parseDoDefinition(f)),o._d(a,c)},o._d=function(a,c){var d,e=o._e(c),f=o._f(a,c);if(c.after&&o.Util._x(c.after)&&(d=c.after[0]),""!==e){var g,h=f.length,i=0;for(i;h>i;i++)if(g=f[i],b.EventSystem.isEventTarget(g)){var j=function(e){var f=o._g(a,c,e),g=o._h(c),h=o._j(a,c),i=o._i(a,c);""!==o._w&&(o.Util._x(g)||(g+=o._w));var k={behaviorTargetList:f,nodeHelper:o.NodeHelper,animationEndEvent:o._v,behavior:g,after:i,eventSystem:b.EventSystem,eventTarget:e.currentTarget,afterFunctionName:d,dataAniJSOwner:a,listener:j,event:e,before:h},l=new b.AnimationContext(k);l.runAll(k)};b.EventSystem.addEventListenerHelper(g,e,j,!1),b.EventSystem.registerEventHandle(g,e,j)}}},o._e=function(a){var b="",c=a.event||b;return c===l?c=o._p():c===m&&(c=o._q()),c},o._f=function(c,d){var e,f=c,g=[f],h=b.rootDOMTravelScope;if(d.eventTarget)if(e=o._notifierHelper(d.eventTarget),e.length>0)g=e;else if("document"===d.eventTarget)g=[document];else if("window"===d.eventTarget)g=[a];else if(d.eventTarget.split)try{g=h.querySelectorAll(d.eventTarget)}catch(i){g=[]}return g},o._g=function(a,c,d){var e=a,g=[e],h=b.rootDOMTravelScope,i=c.behaviorTarget;if(i)if(o.Util._x(i)){var j=this._y(a,c,i);j&&o.Util.isFunction(j[0])&&(g=j[0](d,{dataAniJSOwner:a},o._z(j)))}else if(i===n&&d.currentTarget)g=[d.currentTarget];else{i=i.split(f).join(",");try{g=h.querySelectorAll(i)}catch(k){g=[]}}return g},o._h=function(a){return this._y({},a,a.behavior)},o._i=function(a,b){var c=b.after;return o.Util._x(c)?this._y(a,b,c):o._k(a,b,c)},o._j=function(a,b){var c=b.before;return o.Util._x(c)?this._y(a,b,c):o._k(a,b,c)},o._y=function(a,b,c){var d,e=c||"";return o.Util._x(e)&&(d=o._k(a,b,e[0]),d?e[0]=d:e=e.join(" ")),e},o._k=function(a,b,c){var d=c||"",e=o._l(b);if(d&&!o.Util.isFunction(d)){var f=o._t,g=f[e];d=g&&o.Util.isFunction(g[d])?g[d]:!1}return d},o._l=function(a){var b=a.helper||o._u;return b},o._notifierHelper=function(a){{var c=[];b.notifierCollection}if(a)if(a.id&&b.EventSystem.isEventTarget(a.value))c.push(a.value),b.registerNotifier(a);else if(a.split){notifierIDList=a.split("$");var d,e=notifierIDList.length,f=1;for(f;e>f;f++)if(d=notifierIDList[f],d&&" "!==d){d=d.trim();var g=b.getNotifier(d);g||(g=b.EventSystem.createEventTarget(),b.registerNotifier({id:d,value:g})),c.push(g)}}return c},o._z=function(a){for(var b=[],c=a.length;c-->1;)b[c-1]=a[c];return b},o._n=function(a){return o.Parser.parse(a)},o._o=function(a){var b="["+c+"]";return a.querySelectorAll(b)},o._p=function(){var a=o._r(),b=[l,"oAnimationEnd",l,"webkitAnimationEnd"];return b[a]},o._q=function(){var a=o._r(),b=[m,"oTransitionEnd",m,"webkitTransitionEnd"];return b[a]},o._r=function(){for(var a=document.createElement("fe"),b="Animation",c=["animation","O"+b,"Moz"+b,"webkit"+b],d=0;d<c.length;d++)if(void 0!==a.style[c[d]])return d},b.AnimationContext=function(a){var c=this;c.init=function(a){c.behaviorTargetList=a.behaviorTargetList||[],c.nodeHelper=a.nodeHelper,c.animationEndEvent=a.animationEndEvent,c.behavior=a.behavior,c.after=a.after,c.eventSystem=a.eventSystem,c.eventTarget=a.eventTarget,c.afterFunctionName=a.afterFunctionName,c.dataAniJSOwner=a.dataAniJSOwner,c.listener=a.listener,c.event=a.event,c.before=a.before},c.doDefaultAction=function(a,b){var d,e=c,f=e.nodeHelper,g=e.animationEndEvent,h=e.after,i=e.afterFunctionName;e.eventSystem.addEventListenerHelper(a,g,function(a){a.stopPropagation(),e.eventSystem.removeEventListenerHelper(a.target,a.type,arguments.callee),h&&(o.Util.isFunction(h)?h(a,c):o.Util._x(h)&&h[0](a,c,o._z(h)))}),"holdAnimClass"!==i&&"$holdAnimClass"!==i&&(d=a._ajLastBehavior,d&&f.removeClass(a,d),a._ajLastBehavior=b),a.offsetWidth=a.offsetWidth,f.addClass(a,b)},c.doFunctionAction=function(a,b){var d=c,e=d.after,f={target:a};b[0](f,c,o._z(b)),o.Util.isFunction(e)?e(f,c):o.Util._x(e)&&e[0](f,c,o._z(e))},c.runAll=function(){var a,d,e=c,f=e.behaviorTargetList,g=f.length,h=(e.behavior,0),i=e.before,j=c.event;for(h;g>h;h++)d={behaviorTargetList:[f[h]],nodeHelper:c.nodeHelper,animationEndEvent:c.animationEndEvent,behavior:c.behavior,after:c.after,eventSystem:c.eventSystem,eventTarget:c.eventTarget,afterFunctionName:c.afterFunctionName,dataAniJSOwner:c.dataAniJSOwner,listener:c.listener,event:j},a=new b.AnimationContext(d),i?o.Util.isFunction(i)?i(j,a):o.Util._x(i)&&i[0](j,a,o._z(i)):a.run()},c.run=function(){var a=c,b=a.behavior,d=a.behaviorTargetList[0];c.hasRunned=1,o.Util._x(b)?a.doFunctionAction(d,b):a.doDefaultAction(d,b)},c.init(a)},o.Parser={parse:function(a){return this.parseDeclaration(a)},parseDeclaration:function(a){var b,c,d=[];b=a.split(";");var e=b.length,f=0;for(f;e>f;f++)c=this.parseSentence(b[f]),d.push(c);return d},parseSentence:function(a){var b,c,d={};b=a.split(",");var e=b.length,f=0;for(f;e>f;f++)c=this.parseDefinition(b[f]),d[c.key]=c.value;return d},parseDefinition:function(a){var b,c,d,e={},f="event",j="eventTarget",k=["behavior","after","before","behaviorTarget"];if(b=a.split(":"),b.length>1){if(c=b[0].trim(),b.length>2?(d=b.slice(1),d=d.join(":"),d=d.trim()):d=b[1].trim(),e.value=d,c===g)c=f;else if(c===h)c=j;else for(var l=i.length-1;l>=0;l--)c===i[l]&&(c=k[l],"after"!==c&&"before"!==c||"$"===d[0]||(d="$"+d),d=this.parseDoDefinition(d));e.key=c,e.value=d}return e},parseDoDefinition:function(a){var b=/^\$(\w+)\s*/g,c=b.exec(a),d="",f=1;if(null!==c){d=c[1],doDefinitionArray=a.split(c[0])[1],doDefinitionArray=null!==doDefinitionArray?doDefinitionArray.split(e):[],a=[],a[0]=d;for(var g=0;g<doDefinitionArray.length;g++)""!==doDefinitionArray[g]&&(a[f++]=doDefinitionArray[g].trim());return a}return a}},o.NodeHelper={addClass:function(a,b){b instanceof Array||(b=b.split(" "));for(var c=0,d=b.length;d>c;++c)b[c]&&!new RegExp(j+b[c]+k).test(a.className)&&(a.className=""===a.className?b[c]:a.className.trim()+" "+b[c])},removeClass:function(a,b){b instanceof Array||(b=b.split(" "));for(var c=0,d=b.length;d>c;++c)a.className=a.className.replace(new RegExp(j+b[c]+k)," ").trim()},hasClass:function(a,b){return b&&new RegExp(j+b+k).test(a.className)}},o.Util={isFunction:function(a){return!!(a&&a.constructor&&a.call&&a.apply)},_x:function(a){return Array.isArray(a)}},b.EventSystem={eventCollection:{},eventIdCounter:0,isEventTarget:function(a){return a.addEventListener?1:0},createEventTarget:function(){return new b.EventTarget},addEventListenerHelper:function(a,b,c){a.addEventListener(b,c,!1)},removeEventListenerHelper:function(a,b,c){a&&a.removeEventListener(b,c)},purgeAll:function(){var a,b,c=this,d=c.eventCollection,e=Object.keys(d),f=e.length,g=0;for(g;f>g;g++)a=e[g],b=d[a],b&&b.handleCollection&&b.handleCollection.length>0&&c.purgeEventTarget(b.handleCollection[0].element),delete d[a]},purgeAllNodes:function(a){var b=a.querySelectorAll("*");size=b.length;for(var c=size-1;c>=0;c--)this.purgeEventTarget(b[c])},purgeEventTarget:function(a){var b,c=this,d=a._aniJSEventID;if(d){b=c.eventCollection[d].handleCollection;var e,f=b.length,g=0;for(g;f>g;g++)e=b[g],c.removeEventListenerHelper(a,e.eventType,e.listener);c.eventCollection[d]=a._aniJSEventID=null,delete c.eventCollection[d],delete a._aniJSEventID}},registerEventHandle:function(a,b,c){var d=this,e=a._aniJSEventID,f=d.eventCollection,g={eventType:b,listener:c,element:a};if(e)f[e].handleCollection.push(g);else{var h={handleCollection:[g]};f[++d.eventIdCounter]=h,a._aniJSEventID=d.eventIdCounter}}},b.EventTarget=function(){this._listeners={}},b.EventTarget.prototype={constructor:b.EventTarget,addEventListener:function(a,b){var c=this;"undefined"==typeof c._listeners[a]&&(c._listeners[a]=[]),c._listeners[a].push(b)},dispatchEvent:function(a){var b=this;if("string"==typeof a&&(a={type:a}),a.target||(a.target=b),!a.type)throw new Error("error");if(this._listeners[a.type]instanceof Array)for(var c=b._listeners[a.type],d=0,e=c.length;e>d;d++)c[d].call(b,a)},removeEventListener:function(a,b){var c=this;if(c._listeners[a]instanceof Array)for(var d=c._listeners[a],e=0,f=d.length;f>e;e++)if(d[e]===b){d.splice(e,1);break}}},b}(c||{});return c.init(),c.run(),"function"==typeof define&&define.amd&&define("anijs",[],function(){return c}),"undefined"==typeof b&&(a.AniJS=c),c});
|
@@ -0,0 +1,1493 @@
|
|
1
|
+
/*!
|
2
|
+
AniJS - http://anijs.github.io
|
3
|
+
Licensed under the MIT license
|
4
|
+
|
5
|
+
Copyright (c) 2014 Dariel Noel <darielnoel@gmail.com>
|
6
|
+
|
7
|
+
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:
|
8
|
+
|
9
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
10
|
+
|
11
|
+
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.
|
12
|
+
*/
|
13
|
+
|
14
|
+
(function(root, factory) {
|
15
|
+
"use strict";
|
16
|
+
if (typeof module == "object" && typeof module.exports == "object") {
|
17
|
+
module.exports = root.document ?
|
18
|
+
factory(root, true) :
|
19
|
+
function(w) {
|
20
|
+
if (!w.document) {
|
21
|
+
throw new Error("AniJS-RWWD");
|
22
|
+
}
|
23
|
+
return factory(w);
|
24
|
+
};
|
25
|
+
} else {
|
26
|
+
factory(root);
|
27
|
+
}
|
28
|
+
|
29
|
+
})(typeof window !== "undefined" ? window : this, function(window, noGlobal) {
|
30
|
+
|
31
|
+
|
32
|
+
/**
|
33
|
+
* AniJS is library for write declarative animations in your static html documents
|
34
|
+
* @class AniJSit
|
35
|
+
* @constructor init
|
36
|
+
* @author @dariel_noel
|
37
|
+
*/
|
38
|
+
var AniJS = (function(AniJS) {
|
39
|
+
|
40
|
+
//Shorthands
|
41
|
+
var ANIJS_DATATAG_NAME = 'data-anijs',
|
42
|
+
DEFAULT = 'default',
|
43
|
+
BODY = 'body',
|
44
|
+
PARAMS_SEPARATOR = '|',
|
45
|
+
MULTIPLE_CLASS_SEPARATOR = '$',
|
46
|
+
EVENT_RESERVED_WORD = 'if',
|
47
|
+
EVENT_TARGET_RESERVED_WORD = 'on',
|
48
|
+
BEHAVIOR_RESERVED_WORD = ['do', 'after', 'before', 'to'],
|
49
|
+
BEHAVIOR_TARGET_RESERVED_WORD = 'to',
|
50
|
+
REGEX_BEGIN = '(\\s+|^)',
|
51
|
+
REGEX_END = '(\\s+|$)',
|
52
|
+
ANIMATION_END = 'animationend',
|
53
|
+
TRANSITION_END = 'transitionend',
|
54
|
+
TARGET = 'target';
|
55
|
+
|
56
|
+
/////////////////////////////////////////////////////////
|
57
|
+
// Public API
|
58
|
+
/////////////////////////////////////////////////////////
|
59
|
+
|
60
|
+
AniJS = {
|
61
|
+
|
62
|
+
rootDOMTravelScope: {},
|
63
|
+
|
64
|
+
notifierCollection: {},
|
65
|
+
|
66
|
+
/**
|
67
|
+
* Initializer Function
|
68
|
+
* @method init
|
69
|
+
* @return
|
70
|
+
*/
|
71
|
+
init: function() {
|
72
|
+
|
73
|
+
//ATTRS inicialization
|
74
|
+
selfish._helperCollection = {};
|
75
|
+
|
76
|
+
var defaultHelper = selfish._createDefaultHelper();
|
77
|
+
|
78
|
+
//Registering an empty helper
|
79
|
+
AniJS.registerHelper(DEFAULT, defaultHelper);
|
80
|
+
|
81
|
+
//Default Helper Index
|
82
|
+
selfish._helperDefaultIndex = DEFAULT;
|
83
|
+
|
84
|
+
AniJS.rootDOMTravelScope = document;
|
85
|
+
|
86
|
+
//Initialize the Parser Object
|
87
|
+
AniJS.Parser = selfish.Parser;
|
88
|
+
|
89
|
+
//AnimationEnd Correct Prefix Setup
|
90
|
+
selfish._animationEndEvent = selfish._animationEndPrefix();
|
91
|
+
|
92
|
+
//Add this class names when anim
|
93
|
+
selfish._classNamesWhenAnim = '';
|
94
|
+
},
|
95
|
+
|
96
|
+
/**
|
97
|
+
* You can use these to change the scope to run AniJS
|
98
|
+
* @method setDOMRootTravelScope
|
99
|
+
* @param {} selector
|
100
|
+
* @return
|
101
|
+
*/
|
102
|
+
setDOMRootTravelScope: function(selector) {
|
103
|
+
var rootDOMTravelScope,
|
104
|
+
domDocument = document;
|
105
|
+
try {
|
106
|
+
if (selector === 'document') {
|
107
|
+
rootDOMTravelScope = domDocument;
|
108
|
+
} else {
|
109
|
+
rootDOMTravelScope = domDocument.querySelector(selector);
|
110
|
+
if (!rootDOMTravelScope) {
|
111
|
+
rootDOMTravelScope = domDocument;
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
} catch (e) {
|
116
|
+
rootDOMTravelScope = domDocument;
|
117
|
+
}
|
118
|
+
AniJS.rootDOMTravelScope = rootDOMTravelScope;
|
119
|
+
},
|
120
|
+
|
121
|
+
/**
|
122
|
+
* Parse Declarations and setup Anim in a founded elements
|
123
|
+
* @method run
|
124
|
+
* @return
|
125
|
+
*/
|
126
|
+
run: function() {
|
127
|
+
var aniJSNodeCollection = [],
|
128
|
+
aniJSParsedSentenceCollection = {};
|
129
|
+
|
130
|
+
//Clear all node listener
|
131
|
+
AniJS.purgeAll();
|
132
|
+
|
133
|
+
AniJS.notifierCollection = {};
|
134
|
+
|
135
|
+
aniJSNodeCollection = selfish._findAniJSNodeCollection(AniJS.rootDOMTravelScope);
|
136
|
+
|
137
|
+
var size = aniJSNodeCollection.length,
|
138
|
+
i = 0,
|
139
|
+
item;
|
140
|
+
|
141
|
+
for (i; i < size; i++) {
|
142
|
+
item = aniJSNodeCollection[i];
|
143
|
+
|
144
|
+
//IMPROVE: The datatag name migth come from configuration
|
145
|
+
aniJSParsedSentenceCollection = selfish._getParsedAniJSSentenceCollection(item.getAttribute(ANIJS_DATATAG_NAME));
|
146
|
+
|
147
|
+
//Le seteo su animacion
|
148
|
+
selfish._setupElementAnim(item, aniJSParsedSentenceCollection);
|
149
|
+
}
|
150
|
+
|
151
|
+
//We can use this for supply the window load and DomContentLoaded in some context
|
152
|
+
var aniJSEventsNotifier = AniJS.getNotifier('AniJSNotifier');
|
153
|
+
if(aniJSEventsNotifier){
|
154
|
+
aniJSEventsNotifier.dispatchEvent('onRunFinished');
|
155
|
+
}
|
156
|
+
},
|
157
|
+
|
158
|
+
/**
|
159
|
+
* Create an animation from a aniJSParsedSentenceCollection
|
160
|
+
* @method createAnimation
|
161
|
+
* @param {} aniJSParsedSentenceCollection
|
162
|
+
* @param {} element
|
163
|
+
* @return
|
164
|
+
*/
|
165
|
+
createAnimation: function(aniJSParsedSentenceCollection, element) {
|
166
|
+
var nodeElement = element || '';
|
167
|
+
|
168
|
+
//BEAUTIFY: The params order migth be the same
|
169
|
+
selfish._setupElementAnim(nodeElement, aniJSParsedSentenceCollection);
|
170
|
+
},
|
171
|
+
|
172
|
+
/**
|
173
|
+
* Return a Helper by ID, you can use this to attach callback to the Helper
|
174
|
+
* @method getHelper
|
175
|
+
* @param {} helperID
|
176
|
+
* @return LogicalExpression
|
177
|
+
*/
|
178
|
+
getHelper: function(helperID) {
|
179
|
+
var helperCollection = selfish._helperCollection;
|
180
|
+
return helperCollection[helperID] || helperCollection[DEFAULT];
|
181
|
+
},
|
182
|
+
|
183
|
+
/**
|
184
|
+
* A helper it's a callback function container
|
185
|
+
* using this function you can register your custom Helper
|
186
|
+
* @method registerHelper
|
187
|
+
* @param {} helperName
|
188
|
+
* @param {} helperInstance
|
189
|
+
* @return
|
190
|
+
*/
|
191
|
+
registerHelper: function(helperName, helperInstance) {
|
192
|
+
selfish._helperCollection[helperName] = helperInstance;
|
193
|
+
},
|
194
|
+
|
195
|
+
/**
|
196
|
+
* Purge a NodeList By Selector
|
197
|
+
* @method purge
|
198
|
+
* @param {} selector
|
199
|
+
* @return
|
200
|
+
*/
|
201
|
+
purge: function(selector) {
|
202
|
+
//TODO: Search a regular expression for test a valid CSS selector
|
203
|
+
if (selector && selector !== '' && selector !== ' ') {
|
204
|
+
var purgeNodeCollection = document.querySelectorAll(selector),
|
205
|
+
size = purgeNodeCollection.length,
|
206
|
+
i = 0;
|
207
|
+
|
208
|
+
for (i; i < size; i++) {
|
209
|
+
AniJS.EventSystem.purgeEventTarget(purgeNodeCollection[i]);
|
210
|
+
}
|
211
|
+
}
|
212
|
+
},
|
213
|
+
|
214
|
+
/**
|
215
|
+
* Purge all register elements handle
|
216
|
+
* you can use this when you run AniJS again
|
217
|
+
* @method purgeAll
|
218
|
+
* @return
|
219
|
+
*/
|
220
|
+
purgeAll: function() {
|
221
|
+
AniJS.EventSystem.purgeAll();
|
222
|
+
},
|
223
|
+
|
224
|
+
/**
|
225
|
+
* Remove all listener from an element
|
226
|
+
* @method purgeEventTarget
|
227
|
+
* @param {} element
|
228
|
+
* @return
|
229
|
+
*/
|
230
|
+
purgeEventTarget: function(element) {
|
231
|
+
AniJS.EventSystem.purgeEventTarget(element);
|
232
|
+
},
|
233
|
+
|
234
|
+
/**
|
235
|
+
* Add default class names while Anim
|
236
|
+
* @method setClassNamesWhenAnim
|
237
|
+
* @param {} defaultClasses
|
238
|
+
* @return
|
239
|
+
*/
|
240
|
+
setClassNamesWhenAnim: function(defaultClasses) {
|
241
|
+
selfish._classNamesWhenAnim = ' ' + defaultClasses;
|
242
|
+
},
|
243
|
+
|
244
|
+
/**
|
245
|
+
* Create an EventTarget
|
246
|
+
* @method createNotifier
|
247
|
+
* @return EventTarget
|
248
|
+
*/
|
249
|
+
createNotifier: function() {
|
250
|
+
return AniJS.EventSystem.createEventTarget();
|
251
|
+
},
|
252
|
+
|
253
|
+
/**
|
254
|
+
* Put an event Notifier in the notifierCollection
|
255
|
+
* @method registerNotifier
|
256
|
+
* @param {} notifier
|
257
|
+
* @return Literal
|
258
|
+
*/
|
259
|
+
registerNotifier: function(notifier) {
|
260
|
+
var notifierCollection = AniJS.notifierCollection;
|
261
|
+
|
262
|
+
//TODO: Optimize lookups here
|
263
|
+
if (notifier.id && notifier.value && AniJS.EventSystem.isEventTarget(notifier.value)) {
|
264
|
+
notifierCollection[notifier.id] = notifier.value;
|
265
|
+
return 1;
|
266
|
+
}
|
267
|
+
|
268
|
+
return '';
|
269
|
+
},
|
270
|
+
|
271
|
+
/**
|
272
|
+
* Return an notifier instance
|
273
|
+
* @method getNotifier
|
274
|
+
* @param {} notifierID
|
275
|
+
* @return notifier
|
276
|
+
*/
|
277
|
+
getNotifier: function(notifierID) {
|
278
|
+
return AniJS.notifierCollection[notifierID];
|
279
|
+
}
|
280
|
+
|
281
|
+
};
|
282
|
+
|
283
|
+
/////////////////////////////////////////////////////////
|
284
|
+
// Private Methods an Vars
|
285
|
+
/////////////////////////////////////////////////////////
|
286
|
+
|
287
|
+
var selfish = {
|
288
|
+
|
289
|
+
};
|
290
|
+
|
291
|
+
/**
|
292
|
+
* Description
|
293
|
+
* @method _createDefaultHelper
|
294
|
+
* @return defaultHelper
|
295
|
+
*/
|
296
|
+
selfish._createDefaultHelper = function() {
|
297
|
+
//TODO: Why default helper here, migth be directly in the public API
|
298
|
+
var defaultHelper = {
|
299
|
+
/**
|
300
|
+
* Remove the animation class added when animation is created
|
301
|
+
* @method removeAnim
|
302
|
+
* @param {} e
|
303
|
+
* @param {} animationContext
|
304
|
+
* @return
|
305
|
+
*/
|
306
|
+
removeAnim: function(e, animationContext) {
|
307
|
+
if(e.target && e.type){
|
308
|
+
animationContext.nodeHelper.removeClass(e.target, animationContext.behavior);
|
309
|
+
}
|
310
|
+
},
|
311
|
+
/**
|
312
|
+
* Holds the animation class added when animation is created
|
313
|
+
* @method holdAnimClass
|
314
|
+
* @param {} e
|
315
|
+
* @param {} animationContext
|
316
|
+
* @return
|
317
|
+
*/
|
318
|
+
holdAnimClass: function(e, animationContext) {
|
319
|
+
},
|
320
|
+
|
321
|
+
fireOnce: function(e, animationContext) {
|
322
|
+
animationContext.eventSystem.removeEventListenerHelper(animationContext.eventTarget, animationContext.event.type, animationContext.listener);
|
323
|
+
},
|
324
|
+
|
325
|
+
/**
|
326
|
+
* Fire custom event
|
327
|
+
*
|
328
|
+
* Examples:
|
329
|
+
*
|
330
|
+
* Fire dummyEvent event of customNotifier
|
331
|
+
*
|
332
|
+
* if: click, do: $addClass fadeIn animated, to: #container, after: emit customNotifier.dummyEvent
|
333
|
+
* if: dummyEvent, on: $customNotifier, do: $addClass hidden, to: $children #container | div
|
334
|
+
*
|
335
|
+
*
|
336
|
+
* @author Yolier Galan Tasse <gallegogt@gmail.com>
|
337
|
+
* @since 2014-09-20
|
338
|
+
* @param {object} e The event handler
|
339
|
+
* @param {object} ctx AniJS Animation Context Object
|
340
|
+
* @param {[string]} params [description]
|
341
|
+
*/
|
342
|
+
emit: function(e, ctx, params) {
|
343
|
+
var cevent = params[0] || null,
|
344
|
+
notifier = "";
|
345
|
+
if(cevent !== null) {
|
346
|
+
cevent = cevent.split('.');
|
347
|
+
if(cevent.length > 1) {
|
348
|
+
notifier = cevent[0];
|
349
|
+
cevent = cevent[1];
|
350
|
+
} else {
|
351
|
+
notifier = "";
|
352
|
+
cevent = cevent[0];
|
353
|
+
}
|
354
|
+
var customNotifier = AniJS.getNotifier(notifier) || null;
|
355
|
+
if(customNotifier !== null)
|
356
|
+
customNotifier.dispatchEvent(cevent);
|
357
|
+
}
|
358
|
+
//Run the animation
|
359
|
+
if(!ctx.hasRunned){
|
360
|
+
ctx.run();
|
361
|
+
}
|
362
|
+
}
|
363
|
+
};
|
364
|
+
|
365
|
+
return defaultHelper;
|
366
|
+
};
|
367
|
+
|
368
|
+
/**
|
369
|
+
* Create a Parser Instance
|
370
|
+
* @method _createParser
|
371
|
+
* @return Parser
|
372
|
+
*/
|
373
|
+
selfish._createParser = function() {
|
374
|
+
//TODO: The Parser could be an static class
|
375
|
+
return new Parser();
|
376
|
+
};
|
377
|
+
|
378
|
+
/**
|
379
|
+
* Setup the animation of the some element
|
380
|
+
* @method _setupElementAnim
|
381
|
+
* @param {} element
|
382
|
+
* @param {} aniJSParsedSentenceCollection
|
383
|
+
* @return
|
384
|
+
*/
|
385
|
+
selfish._setupElementAnim = function(element, aniJSParsedSentenceCollection) {
|
386
|
+
var size = aniJSParsedSentenceCollection.length,
|
387
|
+
i = 0,
|
388
|
+
item,
|
389
|
+
before,
|
390
|
+
after,
|
391
|
+
behavior;
|
392
|
+
|
393
|
+
for (i; i < size; i++) {
|
394
|
+
item = aniJSParsedSentenceCollection[i];
|
395
|
+
after = item.after;
|
396
|
+
before = item.before;
|
397
|
+
behavior = item.behavior;
|
398
|
+
|
399
|
+
if(after){
|
400
|
+
item.after = selfish.Parser.parseDoDefinition(after);
|
401
|
+
}
|
402
|
+
if(before){
|
403
|
+
item.before = selfish.Parser.parseDoDefinition(before);
|
404
|
+
}
|
405
|
+
if(behavior){
|
406
|
+
item.behavior = selfish.Parser.parseDoDefinition(behavior);
|
407
|
+
}
|
408
|
+
selfish._setupElementSentenceAnim(element, item);
|
409
|
+
}
|
410
|
+
};
|
411
|
+
|
412
|
+
/**
|
413
|
+
* Setup the element animation from a AniJS Sentence
|
414
|
+
* @method _setupElementSentenceAnim
|
415
|
+
* @param {} element
|
416
|
+
* @param {} aniJSParsedSentence
|
417
|
+
* @return
|
418
|
+
*/
|
419
|
+
selfish._setupElementSentenceAnim = function(element, aniJSParsedSentence) {
|
420
|
+
//TODO: If the user use animationend or transitionend names to custom events the eventdispach will be not executed
|
421
|
+
var event = selfish._eventHelper(aniJSParsedSentence),
|
422
|
+
eventTargetList = selfish._eventTargetHelper(element, aniJSParsedSentence),
|
423
|
+
afterFunctionName;
|
424
|
+
|
425
|
+
if(aniJSParsedSentence.after && selfish.Util.beArray(aniJSParsedSentence.after)){
|
426
|
+
afterFunctionName = aniJSParsedSentence.after[0];
|
427
|
+
}
|
428
|
+
|
429
|
+
//Es obligatorio definir de eventTarget ATTR
|
430
|
+
if (event !== '') {
|
431
|
+
var size = eventTargetList.length,
|
432
|
+
i = 0,
|
433
|
+
eventTargetItem;
|
434
|
+
for (i; i < size; i++) {
|
435
|
+
eventTargetItem = eventTargetList[i];
|
436
|
+
if (AniJS.EventSystem.isEventTarget(eventTargetItem)) {
|
437
|
+
var listener = function(event) {
|
438
|
+
|
439
|
+
//Si cambia algun parametro dinamicamente entonces hay que enterarse
|
440
|
+
var behaviorTargetList = selfish._behaviorTargetHelper(element, aniJSParsedSentence, event),
|
441
|
+
behavior = selfish._behaviorHelper(aniJSParsedSentence),
|
442
|
+
before = selfish._beforeHelper(element, aniJSParsedSentence),
|
443
|
+
after = selfish._afterHelper(element, aniJSParsedSentence);
|
444
|
+
if (selfish._classNamesWhenAnim !== '') {
|
445
|
+
if(!selfish.Util.beArray(behavior))
|
446
|
+
behavior += selfish._classNamesWhenAnim;
|
447
|
+
}
|
448
|
+
//Creo un nuevo animation context
|
449
|
+
var animationContextConfig = {
|
450
|
+
behaviorTargetList: behaviorTargetList,
|
451
|
+
nodeHelper: selfish.NodeHelper,
|
452
|
+
animationEndEvent: selfish._animationEndEvent,
|
453
|
+
behavior: behavior,
|
454
|
+
after: after,
|
455
|
+
eventSystem: AniJS.EventSystem,
|
456
|
+
eventTarget: event.currentTarget,
|
457
|
+
afterFunctionName: afterFunctionName,
|
458
|
+
dataAniJSOwner: element,
|
459
|
+
listener: listener,
|
460
|
+
event: event,
|
461
|
+
before: before
|
462
|
+
//TODO: eventSystem should be called directly
|
463
|
+
},
|
464
|
+
|
465
|
+
animationContextInstance = new AniJS.AnimationContext(animationContextConfig);
|
466
|
+
|
467
|
+
animationContextInstance.runAll(animationContextConfig);
|
468
|
+
};
|
469
|
+
|
470
|
+
//TODO: Improve lookup here AniJS.EventSystem
|
471
|
+
AniJS.EventSystem.addEventListenerHelper(eventTargetItem, event, listener, false);
|
472
|
+
|
473
|
+
//Register event to feature handle
|
474
|
+
AniJS.EventSystem.registerEventHandle(eventTargetItem, event, listener);
|
475
|
+
}
|
476
|
+
}
|
477
|
+
}
|
478
|
+
};
|
479
|
+
|
480
|
+
/**
|
481
|
+
* Helper to setup the Event that trigger the animation from declaration
|
482
|
+
* https://developer.mozilla.org/en-US/docs/Web/Reference/Events
|
483
|
+
* http://www.w3schools.com/tags/ref_eventattributes.asp
|
484
|
+
* @method _eventHelper
|
485
|
+
* @param {} element
|
486
|
+
* @param {} aniJSParsedSentence
|
487
|
+
* @return event
|
488
|
+
*/
|
489
|
+
selfish._eventHelper = function(aniJSParsedSentence) {
|
490
|
+
var defaultValue = '',
|
491
|
+
event = aniJSParsedSentence.event || defaultValue;
|
492
|
+
|
493
|
+
//TODO: Improve to reduce this ugly logic here
|
494
|
+
if (event === ANIMATION_END) {
|
495
|
+
event = selfish._animationEndPrefix();
|
496
|
+
} else if (event === TRANSITION_END) {
|
497
|
+
event = selfish._transitionEndPrefix();
|
498
|
+
}
|
499
|
+
|
500
|
+
return event;
|
501
|
+
};
|
502
|
+
|
503
|
+
/**
|
504
|
+
* Helper to setup the Place from listen the trigger event of the animation
|
505
|
+
* If is not specified one place, se asume que es himself
|
506
|
+
* Take in account that where it's just a selector
|
507
|
+
* @method _eventTargetHelper
|
508
|
+
* @param {} element
|
509
|
+
* @param {} aniJSParsedSentence
|
510
|
+
* @return eventTargetList
|
511
|
+
*/
|
512
|
+
selfish._eventTargetHelper = function(element, aniJSParsedSentence) {
|
513
|
+
var defaultValue = element,
|
514
|
+
eventTargetList = [defaultValue],
|
515
|
+
rootDOMTravelScope = AniJS.rootDOMTravelScope,
|
516
|
+
notifierList;
|
517
|
+
|
518
|
+
//TODO: We could add other non direct DOM Objects
|
519
|
+
if (aniJSParsedSentence.eventTarget) {
|
520
|
+
|
521
|
+
notifierList = selfish._notifierHelper(aniJSParsedSentence.eventTarget);
|
522
|
+
|
523
|
+
if (notifierList.length > 0) {
|
524
|
+
eventTargetList = notifierList;
|
525
|
+
} else if (aniJSParsedSentence.eventTarget === 'document') {
|
526
|
+
eventTargetList = [document];
|
527
|
+
} else if (aniJSParsedSentence.eventTarget === 'window') {
|
528
|
+
eventTargetList = [window];
|
529
|
+
} else if (aniJSParsedSentence.eventTarget.split) {
|
530
|
+
try {
|
531
|
+
eventTargetList = rootDOMTravelScope.querySelectorAll(aniJSParsedSentence.eventTarget);
|
532
|
+
} catch (e) {
|
533
|
+
console.log('Ugly Selector Here');
|
534
|
+
eventTargetList = [];
|
535
|
+
}
|
536
|
+
}
|
537
|
+
}
|
538
|
+
//It's not a nodeList any more
|
539
|
+
return eventTargetList;
|
540
|
+
};
|
541
|
+
|
542
|
+
/**
|
543
|
+
* Helper to setup the Node can be animated
|
544
|
+
* @method _behaviorTargetHelper
|
545
|
+
* @param {} element
|
546
|
+
* @param {} aniJSParsedSentence
|
547
|
+
* @return behaviorTargetNodeList
|
548
|
+
*/
|
549
|
+
selfish._behaviorTargetHelper = function(element, aniJSParsedSentence, event) {
|
550
|
+
var defaultValue = element,
|
551
|
+
behaviorTargetNodeList = [defaultValue],
|
552
|
+
rootDOMTravelScope = AniJS.rootDOMTravelScope,
|
553
|
+
behaviorTarget = aniJSParsedSentence.behaviorTarget;
|
554
|
+
|
555
|
+
if (behaviorTarget) {
|
556
|
+
if(!selfish.Util.beArray(behaviorTarget)){
|
557
|
+
if(behaviorTarget === TARGET && event.currentTarget){
|
558
|
+
behaviorTargetNodeList = [event.currentTarget];
|
559
|
+
} else{
|
560
|
+
//Expression regular remplazar caracteres $ por comas
|
561
|
+
//TODO: Estudiar si este caracter no esta agarrado
|
562
|
+
behaviorTarget = behaviorTarget.split(MULTIPLE_CLASS_SEPARATOR).join(',');
|
563
|
+
try {
|
564
|
+
behaviorTargetNodeList = rootDOMTravelScope.querySelectorAll(behaviorTarget);
|
565
|
+
} catch (e) {
|
566
|
+
behaviorTargetNodeList = [];
|
567
|
+
}
|
568
|
+
}
|
569
|
+
} else{
|
570
|
+
var behaviorObject = this._actionHelper(element, aniJSParsedSentence, behaviorTarget);
|
571
|
+
if(behaviorObject && selfish.Util.isFunction(behaviorObject[0])){
|
572
|
+
behaviorTargetNodeList = behaviorObject[0]
|
573
|
+
(event,{dataAniJSOwner:element},
|
574
|
+
selfish._paramsHelper(behaviorObject));
|
575
|
+
}
|
576
|
+
}
|
577
|
+
}
|
578
|
+
return behaviorTargetNodeList;
|
579
|
+
};
|
580
|
+
|
581
|
+
/**
|
582
|
+
* Helper to setup the Animation type
|
583
|
+
* @method _behaviorHelper
|
584
|
+
* @param {} element
|
585
|
+
* @param {} aniJSParsedSentence
|
586
|
+
* @return defaultValue
|
587
|
+
*/
|
588
|
+
selfish._behaviorHelper = function(aniJSParsedSentence) {
|
589
|
+
return this._actionHelper({}, aniJSParsedSentence, aniJSParsedSentence.behavior);
|
590
|
+
};
|
591
|
+
|
592
|
+
/**
|
593
|
+
* Helper to setup the after callback function
|
594
|
+
* @method _afterHelper
|
595
|
+
* @param {} element
|
596
|
+
* @param {} aniJSParsedSentence
|
597
|
+
* @return defaultValue
|
598
|
+
*/
|
599
|
+
selfish._afterHelper = function(element, aniJSParsedSentence) {
|
600
|
+
var defaultValue = aniJSParsedSentence.after;
|
601
|
+
// return defaultValue;
|
602
|
+
if(!selfish.Util.beArray(defaultValue))
|
603
|
+
return selfish._callbackHelper(element, aniJSParsedSentence, defaultValue);
|
604
|
+
return this._actionHelper(element, aniJSParsedSentence, defaultValue);
|
605
|
+
};
|
606
|
+
|
607
|
+
/**
|
608
|
+
* Helper to setup the after callback function
|
609
|
+
* @method _afterHelper
|
610
|
+
* @param {} element
|
611
|
+
* @param {} aniJSParsedSentence
|
612
|
+
* @return defaultValue
|
613
|
+
*/
|
614
|
+
selfish._beforeHelper = function(element, aniJSParsedSentence) {
|
615
|
+
var defaultValue = aniJSParsedSentence.before;
|
616
|
+
if(!selfish.Util.beArray(defaultValue))
|
617
|
+
return selfish._callbackHelper(element, aniJSParsedSentence, defaultValue);
|
618
|
+
return this._actionHelper(element, aniJSParsedSentence, defaultValue);
|
619
|
+
};
|
620
|
+
/**
|
621
|
+
* The executed actions helper
|
622
|
+
* @author Dariel Noel <darielnoel@gmail.com>
|
623
|
+
* @since 2014-09-10
|
624
|
+
* @param {[type]} element [description]
|
625
|
+
* @param {[type]} aniJSParsedSentence [description]
|
626
|
+
* @param {[type]} action [description]
|
627
|
+
* @return {[type]} [description]
|
628
|
+
*/
|
629
|
+
selfish._actionHelper = function(element, aniJSParsedSentence, action) {
|
630
|
+
var defaultValue = action || '',
|
631
|
+
executeFunction;
|
632
|
+
if(selfish.Util.beArray(defaultValue)) {
|
633
|
+
executeFunction = selfish._callbackHelper(element, aniJSParsedSentence, defaultValue[0]);
|
634
|
+
if(executeFunction) {
|
635
|
+
defaultValue[0] = executeFunction;
|
636
|
+
} else {
|
637
|
+
defaultValue = defaultValue.join(' ');
|
638
|
+
}
|
639
|
+
|
640
|
+
}
|
641
|
+
return defaultValue;
|
642
|
+
};
|
643
|
+
|
644
|
+
/**
|
645
|
+
* Helper for before and after helpers refactoring
|
646
|
+
* @method _callbackHelper
|
647
|
+
* @param {} element
|
648
|
+
* @param {} aniJSParsedSentence
|
649
|
+
* @param {} callbackFunction
|
650
|
+
* @return defaultValue
|
651
|
+
*/
|
652
|
+
selfish._callbackHelper = function(element, aniJSParsedSentence, callbackFunction) {
|
653
|
+
var defaultValue = callbackFunction || '',
|
654
|
+
helper = selfish._helperHelper(aniJSParsedSentence);
|
655
|
+
|
656
|
+
if (defaultValue) {
|
657
|
+
if (!selfish.Util.isFunction(defaultValue)) {
|
658
|
+
var helperCollection = selfish._helperCollection,
|
659
|
+
helperInstance = helperCollection[helper];
|
660
|
+
|
661
|
+
if (helperInstance && selfish.Util.isFunction(helperInstance[defaultValue])) {
|
662
|
+
defaultValue = helperInstance[defaultValue];
|
663
|
+
} else {
|
664
|
+
defaultValue = false;
|
665
|
+
}
|
666
|
+
}
|
667
|
+
}
|
668
|
+
|
669
|
+
return defaultValue;
|
670
|
+
};
|
671
|
+
|
672
|
+
/**
|
673
|
+
* Helper to setup the helper of the animation
|
674
|
+
* @method _helperHelper
|
675
|
+
* @param {} element
|
676
|
+
* @param {} aniJSParsedSentence
|
677
|
+
* @return defaultValue
|
678
|
+
*/
|
679
|
+
selfish._helperHelper = function(aniJSParsedSentence) {
|
680
|
+
var defaultValue = aniJSParsedSentence.helper || selfish._helperDefaultIndex;
|
681
|
+
return defaultValue;
|
682
|
+
};
|
683
|
+
|
684
|
+
/**
|
685
|
+
* Helper to setup the notifier
|
686
|
+
* @method _notifierHelper
|
687
|
+
* @param {} eventTargetDefinition
|
688
|
+
* @return defaultValue
|
689
|
+
*/
|
690
|
+
selfish._notifierHelper = function(eventTargetDefinition) {
|
691
|
+
var defaultValue = [],
|
692
|
+
notifierCollection = AniJS.notifierCollection;
|
693
|
+
|
694
|
+
if (eventTargetDefinition) {
|
695
|
+
//{id: notifierID, value:notifierObject}
|
696
|
+
if (eventTargetDefinition.id && AniJS.EventSystem.isEventTarget(eventTargetDefinition.value)) {
|
697
|
+
//TODO: In the near future could be an object list
|
698
|
+
defaultValue.push(eventTargetDefinition.value);
|
699
|
+
|
700
|
+
AniJS.registerNotifier(eventTargetDefinition);
|
701
|
+
} else if (eventTargetDefinition.split) {
|
702
|
+
//Picar por signo de peso y obtener la lista de id de events Notifiers
|
703
|
+
notifierIDList = eventTargetDefinition.split('$');
|
704
|
+
var size = notifierIDList.length,
|
705
|
+
i = 1,
|
706
|
+
notifierID;
|
707
|
+
|
708
|
+
for (i; i < size; i++) {
|
709
|
+
notifierID = notifierIDList[i];
|
710
|
+
if (notifierID && notifierID !== ' ') {
|
711
|
+
//limpiarle los espacios alante y atras (trim)
|
712
|
+
notifierID = notifierID.trim();
|
713
|
+
|
714
|
+
//TODO: Big Refactoring here
|
715
|
+
var value = AniJS.getNotifier(notifierID);
|
716
|
+
if (!value) {
|
717
|
+
value = AniJS.EventSystem.createEventTarget();
|
718
|
+
AniJS.registerNotifier({
|
719
|
+
id: notifierID,
|
720
|
+
value: value
|
721
|
+
});
|
722
|
+
}
|
723
|
+
defaultValue.push(value);
|
724
|
+
}
|
725
|
+
}
|
726
|
+
}
|
727
|
+
}
|
728
|
+
|
729
|
+
return defaultValue;
|
730
|
+
};
|
731
|
+
|
732
|
+
selfish._paramsHelper = function(paramsArray){
|
733
|
+
var arr = [],
|
734
|
+
i = paramsArray.length;
|
735
|
+
while(i-- > 1) arr[i - 1] = paramsArray[i];
|
736
|
+
return arr;
|
737
|
+
};
|
738
|
+
|
739
|
+
/**
|
740
|
+
* Parse an String Declaration
|
741
|
+
* @method _getParsedAniJSSentenceCollection
|
742
|
+
* @param {} stringDeclaration
|
743
|
+
* @return CallExpression
|
744
|
+
*/
|
745
|
+
selfish._getParsedAniJSSentenceCollection = function(stringDeclaration) {
|
746
|
+
return selfish.Parser.parse(stringDeclaration);
|
747
|
+
};
|
748
|
+
|
749
|
+
/**
|
750
|
+
* Select all DOM nodes that have a AniJS declaration
|
751
|
+
* @method _findAniJSNodeCollection
|
752
|
+
* @param {} rootDOMTravelScope
|
753
|
+
* @return CallExpression
|
754
|
+
*/
|
755
|
+
selfish._findAniJSNodeCollection = function(rootDOMTravelScope) {
|
756
|
+
//IMPROVE: Might a configuration option
|
757
|
+
var aniJSDataTagName = '[' + ANIJS_DATATAG_NAME + ']';
|
758
|
+
return rootDOMTravelScope.querySelectorAll(aniJSDataTagName);
|
759
|
+
};
|
760
|
+
|
761
|
+
/**
|
762
|
+
* Return the correct AnimationEnd Prefix according to the current browser
|
763
|
+
* @method _animationEndPrefix
|
764
|
+
* @return
|
765
|
+
*/
|
766
|
+
selfish._animationEndPrefix = function() {
|
767
|
+
var endPrefixBrowserDetectionIndex = selfish._endPrefixBrowserDetectionIndex(),
|
768
|
+
animationEndBrowserPrefix = [ANIMATION_END, 'oAnimationEnd', ANIMATION_END, 'webkitAnimationEnd'];
|
769
|
+
|
770
|
+
return animationEndBrowserPrefix[endPrefixBrowserDetectionIndex];
|
771
|
+
};
|
772
|
+
|
773
|
+
/**
|
774
|
+
* Return the correct TransitionEnd Prefix according to the current browser
|
775
|
+
* @method _transitionEndPrefix
|
776
|
+
* @return
|
777
|
+
*/
|
778
|
+
selfish._transitionEndPrefix = function() {
|
779
|
+
var endPrefixBrowserDetectionIndex = selfish._endPrefixBrowserDetectionIndex(),
|
780
|
+
transitionEndBrowserPrefix = [TRANSITION_END, 'oTransitionEnd', TRANSITION_END, 'webkitTransitionEnd'];
|
781
|
+
|
782
|
+
return transitionEndBrowserPrefix[endPrefixBrowserDetectionIndex];
|
783
|
+
};
|
784
|
+
|
785
|
+
/**
|
786
|
+
* Return the correct Transition and Animation End Prefix helper according to the current browser
|
787
|
+
* @method _transitionEndPrefix
|
788
|
+
* @return index of the prefix acording to the browser
|
789
|
+
*/
|
790
|
+
selfish._endPrefixBrowserDetectionIndex = function() {
|
791
|
+
//TODO: Delete de element after create this
|
792
|
+
var el = document.createElement('fe'),
|
793
|
+
ANIM = 'Animation',
|
794
|
+
animationBrowserDetection = ['animation', 'O'+ANIM, 'Moz'+ANIM, 'webkit'+ANIM];
|
795
|
+
|
796
|
+
for (var i = 0; i < animationBrowserDetection.length; i++) {
|
797
|
+
if (el.style[animationBrowserDetection[i]] !== undefined) {
|
798
|
+
return i;
|
799
|
+
}
|
800
|
+
}
|
801
|
+
};
|
802
|
+
|
803
|
+
/////////////////////////////////////////////////////////
|
804
|
+
// Private SubModules
|
805
|
+
/////////////////////////////////////////////////////////
|
806
|
+
|
807
|
+
/**
|
808
|
+
* Encapsulate the animation Context
|
809
|
+
* @class animationContext
|
810
|
+
* @author @dariel_noel
|
811
|
+
*/
|
812
|
+
AniJS.AnimationContext = (function(config) {
|
813
|
+
|
814
|
+
//TODO: Module aproach here
|
815
|
+
var animationContextInstance = this;
|
816
|
+
|
817
|
+
/**
|
818
|
+
* Class constructor
|
819
|
+
* @method init
|
820
|
+
* @param {} config
|
821
|
+
* @return
|
822
|
+
*/
|
823
|
+
animationContextInstance.init = function(config) {
|
824
|
+
|
825
|
+
//TODO: Valorar la idea de usar prototype por performance reasons
|
826
|
+
//ATTRS
|
827
|
+
animationContextInstance.behaviorTargetList = config.behaviorTargetList || [];
|
828
|
+
|
829
|
+
animationContextInstance.nodeHelper = config.nodeHelper;
|
830
|
+
|
831
|
+
animationContextInstance.animationEndEvent = config.animationEndEvent;
|
832
|
+
|
833
|
+
animationContextInstance.behavior = config.behavior;
|
834
|
+
|
835
|
+
animationContextInstance.after = config.after;
|
836
|
+
|
837
|
+
animationContextInstance.eventSystem = config.eventSystem;
|
838
|
+
|
839
|
+
animationContextInstance.eventTarget = config.eventTarget;
|
840
|
+
|
841
|
+
animationContextInstance.afterFunctionName = config.afterFunctionName;
|
842
|
+
|
843
|
+
animationContextInstance.dataAniJSOwner = config.dataAniJSOwner;
|
844
|
+
|
845
|
+
animationContextInstance.listener = config.listener;
|
846
|
+
|
847
|
+
animationContextInstance.event = config.event;
|
848
|
+
animationContextInstance.before = config.before;
|
849
|
+
};
|
850
|
+
|
851
|
+
/**
|
852
|
+
* Custom AniJS animation behavior
|
853
|
+
* @author Dariel Noel <darielnoel@gmail.com>
|
854
|
+
* @since 2014-09-03
|
855
|
+
* @param {[type]} target [description]
|
856
|
+
* @param {[type]} behavior [description]
|
857
|
+
* @return {[type]} [description]
|
858
|
+
*/
|
859
|
+
animationContextInstance.doDefaultAction = function(target, behavior){
|
860
|
+
var instance = animationContextInstance,
|
861
|
+
nodeHelper = instance.nodeHelper,
|
862
|
+
animationEndEvent = instance.animationEndEvent,
|
863
|
+
after = instance.after,
|
864
|
+
afterFunctionName = instance.afterFunctionName,
|
865
|
+
lastBehavior;
|
866
|
+
|
867
|
+
//create event
|
868
|
+
instance.eventSystem.addEventListenerHelper(target, animationEndEvent, function(e) {
|
869
|
+
e.stopPropagation();
|
870
|
+
//remove event
|
871
|
+
instance.eventSystem.removeEventListenerHelper(e.target, e.type, arguments.callee);
|
872
|
+
if(after){
|
873
|
+
if(selfish.Util.isFunction(after)){
|
874
|
+
after(e, animationContextInstance);
|
875
|
+
} else if(selfish.Util.beArray(after)) {
|
876
|
+
after[0](e, animationContextInstance, selfish._paramsHelper(after));
|
877
|
+
}
|
878
|
+
}
|
879
|
+
});
|
880
|
+
// Backguard compatibility
|
881
|
+
if (afterFunctionName !== "holdAnimClass" && afterFunctionName !== "$holdAnimClass") {
|
882
|
+
lastBehavior = target._ajLastBehavior;
|
883
|
+
if(lastBehavior){
|
884
|
+
// removing the animation by default if there are not hold animClass
|
885
|
+
nodeHelper.removeClass(target, lastBehavior);
|
886
|
+
}
|
887
|
+
target._ajLastBehavior = behavior;
|
888
|
+
}
|
889
|
+
// Trigger a reflow in between removing and adding the class name.
|
890
|
+
// http://css-tricks.com/restart-css-animation/
|
891
|
+
target.offsetWidth = target.offsetWidth;
|
892
|
+
nodeHelper.addClass(target, behavior);
|
893
|
+
};
|
894
|
+
|
895
|
+
/**
|
896
|
+
* Allows to use a custom helpers function via do definitions
|
897
|
+
* @author Dariel Noel <darielnoel@gmail.com>
|
898
|
+
* @since 2014-09-03
|
899
|
+
* @param {[type]} target [description]
|
900
|
+
* @param {[type]} behavior [description]
|
901
|
+
* @return {[type]} [description]
|
902
|
+
*/
|
903
|
+
animationContextInstance.doFunctionAction = function(target, behavior){
|
904
|
+
var instance = animationContextInstance,
|
905
|
+
after = instance.after,
|
906
|
+
e = {target:target};
|
907
|
+
behavior[0](e, animationContextInstance, selfish._paramsHelper(behavior));
|
908
|
+
if(selfish.Util.isFunction(after)){
|
909
|
+
after(e, animationContextInstance);
|
910
|
+
} else {
|
911
|
+
if(selfish.Util.beArray(after)) {
|
912
|
+
after[0](e, animationContextInstance, selfish._paramsHelper(after));
|
913
|
+
}
|
914
|
+
}
|
915
|
+
};
|
916
|
+
|
917
|
+
/**
|
918
|
+
* Create an animation context instance for every behavior target list
|
919
|
+
* and run it
|
920
|
+
* @method run
|
921
|
+
* @return
|
922
|
+
*/
|
923
|
+
animationContextInstance.runAll = function() {
|
924
|
+
var instance = animationContextInstance,
|
925
|
+
behaviorTargetList = instance.behaviorTargetList,
|
926
|
+
behaviorTargetListSize = behaviorTargetList.length,
|
927
|
+
behavior = instance.behavior,
|
928
|
+
j = 0,
|
929
|
+
before = instance.before,
|
930
|
+
simpleAnimationContextInstance,
|
931
|
+
event = animationContextInstance.event,
|
932
|
+
animationContextConfig;
|
933
|
+
|
934
|
+
for (j; j < behaviorTargetListSize; j++) {
|
935
|
+
|
936
|
+
animationContextConfig = {
|
937
|
+
behaviorTargetList: [behaviorTargetList[j]],
|
938
|
+
nodeHelper: animationContextInstance.nodeHelper,
|
939
|
+
animationEndEvent: animationContextInstance.animationEndEvent,
|
940
|
+
behavior: animationContextInstance.behavior,
|
941
|
+
after: animationContextInstance.after,
|
942
|
+
eventSystem: animationContextInstance.eventSystem,
|
943
|
+
eventTarget: animationContextInstance.eventTarget,
|
944
|
+
afterFunctionName: animationContextInstance.afterFunctionName,
|
945
|
+
dataAniJSOwner: animationContextInstance.dataAniJSOwner,
|
946
|
+
listener: animationContextInstance.listener,
|
947
|
+
event: event
|
948
|
+
//TODO: eventSystem should be called directly
|
949
|
+
};
|
950
|
+
|
951
|
+
simpleAnimationContextInstance = new AniJS.AnimationContext(animationContextConfig);
|
952
|
+
if (before) {
|
953
|
+
if(selfish.Util.isFunction(before)) {
|
954
|
+
before(event, simpleAnimationContextInstance);
|
955
|
+
} else if(selfish.Util.beArray(before)) {
|
956
|
+
before[0](event, simpleAnimationContextInstance, selfish._paramsHelper(before));
|
957
|
+
}
|
958
|
+
} else {
|
959
|
+
simpleAnimationContextInstance.run();
|
960
|
+
}
|
961
|
+
}
|
962
|
+
};
|
963
|
+
/**
|
964
|
+
* Execute an animation context instance
|
965
|
+
* @method run
|
966
|
+
* @return
|
967
|
+
*/
|
968
|
+
animationContextInstance.run = function() {
|
969
|
+
var instance = animationContextInstance,
|
970
|
+
behavior = instance.behavior,
|
971
|
+
behaviorTargetListItem = instance.behaviorTargetList[0];
|
972
|
+
|
973
|
+
animationContextInstance.hasRunned = 1;
|
974
|
+
if(selfish.Util.beArray(behavior)){
|
975
|
+
instance
|
976
|
+
.doFunctionAction(behaviorTargetListItem, behavior);
|
977
|
+
} else{
|
978
|
+
instance
|
979
|
+
.doDefaultAction(behaviorTargetListItem, behavior);
|
980
|
+
}
|
981
|
+
};
|
982
|
+
|
983
|
+
animationContextInstance.init(config);
|
984
|
+
});
|
985
|
+
|
986
|
+
/**
|
987
|
+
* Encapsulate the AnimJS sintax parser
|
988
|
+
* @class Parser
|
989
|
+
* @author @dariel_noel
|
990
|
+
*/
|
991
|
+
selfish.Parser = {
|
992
|
+
|
993
|
+
/**
|
994
|
+
* Parse a aniJSDeclaration
|
995
|
+
* @method parse
|
996
|
+
* @param {} aniJSDeclaration
|
997
|
+
* @return CallExpression
|
998
|
+
*/
|
999
|
+
parse: function(aniJSDeclaration) {
|
1000
|
+
return this.parseDeclaration(aniJSDeclaration);
|
1001
|
+
},
|
1002
|
+
|
1003
|
+
/**
|
1004
|
+
* Declaration parse
|
1005
|
+
* Sintax: Declaration -> Sentence; | *
|
1006
|
+
* Example: SentenceA; SentenceB
|
1007
|
+
* @method _parseDeclaration
|
1008
|
+
* @param {} declaration
|
1009
|
+
* @return parsedDeclaration
|
1010
|
+
*/
|
1011
|
+
parseDeclaration: function(declaration) {
|
1012
|
+
var parsedDeclaration = [],
|
1013
|
+
sentenceCollection,
|
1014
|
+
parsedSentence;
|
1015
|
+
|
1016
|
+
sentenceCollection = declaration.split(';');
|
1017
|
+
|
1018
|
+
var size = sentenceCollection.length,
|
1019
|
+
i = 0;
|
1020
|
+
|
1021
|
+
for (i; i < size; i++) {
|
1022
|
+
parsedSentence = this.parseSentence(sentenceCollection[i]);
|
1023
|
+
parsedDeclaration.push(parsedSentence);
|
1024
|
+
}
|
1025
|
+
|
1026
|
+
return parsedDeclaration;
|
1027
|
+
},
|
1028
|
+
|
1029
|
+
/**
|
1030
|
+
* Sentence Parse
|
1031
|
+
* Sintax: Sentence -> if, on, do, to, after, helper
|
1032
|
+
* Example: "if: DOMContentLoaded, on: document, do:flip, to: .animatecss, after: testcallback"
|
1033
|
+
* note: The order it's not important
|
1034
|
+
* @method _parseSentence
|
1035
|
+
* @param {} sentence
|
1036
|
+
* @return parsedSentence
|
1037
|
+
*/
|
1038
|
+
parseSentence: function(sentence) {
|
1039
|
+
var parsedSentence = {},
|
1040
|
+
definitionCollection,
|
1041
|
+
parsedDefinition;
|
1042
|
+
|
1043
|
+
definitionCollection = sentence.split(',');
|
1044
|
+
|
1045
|
+
var size = definitionCollection.length,
|
1046
|
+
i = 0;
|
1047
|
+
|
1048
|
+
for (i; i < size; i++) {
|
1049
|
+
parsedDefinition = this.parseDefinition(definitionCollection[i]);
|
1050
|
+
parsedSentence[parsedDefinition.key] = parsedDefinition.value;
|
1051
|
+
}
|
1052
|
+
return parsedSentence;
|
1053
|
+
},
|
1054
|
+
|
1055
|
+
/**
|
1056
|
+
* Parse definition
|
1057
|
+
* Sintax: Definition -> if | on | do | to | after | helper
|
1058
|
+
* Example: "if: DOMContentLoaded, on: document, do:flip, to: .animatecss, after: testcallback"
|
1059
|
+
* @method _parseDefinition
|
1060
|
+
* @param {} definition
|
1061
|
+
* @return parsedDefinition
|
1062
|
+
*/
|
1063
|
+
parseDefinition: function(definition) {
|
1064
|
+
var parsedDefinition = {},
|
1065
|
+
definitionBody,
|
1066
|
+
definitionKey,
|
1067
|
+
definitionValue,
|
1068
|
+
EVENT_KEY = 'event',
|
1069
|
+
EVENT_TARGET_KEY = 'eventTarget',
|
1070
|
+
BEHAVIOR_KEY = ['behavior', 'after', 'before', 'behaviorTarget'];
|
1071
|
+
|
1072
|
+
//Performance reasons
|
1073
|
+
definitionBody = definition.split(':');
|
1074
|
+
if (definitionBody.length > 1) {
|
1075
|
+
definitionKey = definitionBody[0].trim();
|
1076
|
+
//CSS3 selectors support
|
1077
|
+
if(definitionBody.length > 2){
|
1078
|
+
definitionValue = definitionBody.slice(1);
|
1079
|
+
definitionValue = definitionValue.join(':');
|
1080
|
+
definitionValue = definitionValue.trim();
|
1081
|
+
} else {
|
1082
|
+
definitionValue = definitionBody[1].trim();
|
1083
|
+
}
|
1084
|
+
parsedDefinition.value = definitionValue;
|
1085
|
+
//Change by reserved words
|
1086
|
+
if (definitionKey === EVENT_RESERVED_WORD) {
|
1087
|
+
definitionKey = EVENT_KEY;
|
1088
|
+
} else if (definitionKey === EVENT_TARGET_RESERVED_WORD) {
|
1089
|
+
definitionKey = EVENT_TARGET_KEY;
|
1090
|
+
} else {
|
1091
|
+
for (var i = BEHAVIOR_RESERVED_WORD.length - 1; i >= 0; i--) {
|
1092
|
+
if(definitionKey === BEHAVIOR_RESERVED_WORD[i]) {
|
1093
|
+
definitionKey = BEHAVIOR_KEY[i];
|
1094
|
+
/**
|
1095
|
+
* TODO: This code is deprecated for next version
|
1096
|
+
*/
|
1097
|
+
if((definitionKey === 'after' || definitionKey === 'before') && definitionValue[0]!== '$') {
|
1098
|
+
definitionValue = '$' + definitionValue;
|
1099
|
+
}
|
1100
|
+
definitionValue = this.parseDoDefinition(definitionValue);
|
1101
|
+
}
|
1102
|
+
}
|
1103
|
+
}
|
1104
|
+
parsedDefinition.key = definitionKey;
|
1105
|
+
parsedDefinition.value = definitionValue;
|
1106
|
+
}
|
1107
|
+
|
1108
|
+
return parsedDefinition;
|
1109
|
+
},
|
1110
|
+
|
1111
|
+
/**
|
1112
|
+
* Allow to parse do definitions
|
1113
|
+
* @author Dariel Noel <darielnoel@gmail.com>
|
1114
|
+
* @since 2014-09-03
|
1115
|
+
* @param {[type]} doDefinition [description]
|
1116
|
+
*/
|
1117
|
+
parseDoDefinition: function(doDefinition) {
|
1118
|
+
var reg = /^\$(\w+)\s*/g,
|
1119
|
+
regMatch = reg.exec(doDefinition),
|
1120
|
+
functionName = "",
|
1121
|
+
parametersArray = [], it = 1;
|
1122
|
+
|
1123
|
+
if(regMatch !== null) {
|
1124
|
+
functionName = regMatch[1];
|
1125
|
+
doDefinitionArray = doDefinition.split(regMatch[0])[1];
|
1126
|
+
doDefinitionArray = doDefinitionArray !== null ? doDefinitionArray.split(PARAMS_SEPARATOR) : [];
|
1127
|
+
doDefinition = [];
|
1128
|
+
doDefinition[0] = functionName;
|
1129
|
+
for (var i = 0; i < doDefinitionArray.length; i++) {
|
1130
|
+
if(doDefinitionArray[i] !== "")
|
1131
|
+
doDefinition[it++] = doDefinitionArray[i].trim();
|
1132
|
+
}
|
1133
|
+
return doDefinition;
|
1134
|
+
}
|
1135
|
+
return doDefinition;
|
1136
|
+
}
|
1137
|
+
};
|
1138
|
+
|
1139
|
+
/**
|
1140
|
+
* Helper to DOM manipulation
|
1141
|
+
* @class Parser
|
1142
|
+
* @author @dariel_noel
|
1143
|
+
*/
|
1144
|
+
selfish.NodeHelper = {
|
1145
|
+
|
1146
|
+
/**
|
1147
|
+
* Add some classes to a node
|
1148
|
+
* @method addClass
|
1149
|
+
* @param {} elem
|
1150
|
+
* @param {} string
|
1151
|
+
* @return
|
1152
|
+
*/
|
1153
|
+
addClass: function(elem, string) {
|
1154
|
+
if (!(string instanceof Array)) {
|
1155
|
+
string = string.split(' ');
|
1156
|
+
}
|
1157
|
+
for (var i = 0, len = string.length; i < len; ++i) {
|
1158
|
+
if (string[i] && !new RegExp(REGEX_BEGIN + string[i] + REGEX_END).test(elem.className)) {
|
1159
|
+
elem.className = (elem.className === "") ? string[i] : elem.className.trim() + ' ' + string[i];
|
1160
|
+
}
|
1161
|
+
}
|
1162
|
+
},
|
1163
|
+
|
1164
|
+
/**
|
1165
|
+
* Remove class of some DOM element
|
1166
|
+
* @method removeClass
|
1167
|
+
* @param {} elem
|
1168
|
+
* @param {} string
|
1169
|
+
* @return
|
1170
|
+
*/
|
1171
|
+
removeClass: function(elem, string) {
|
1172
|
+
if (!(string instanceof Array)) {
|
1173
|
+
string = string.split(' ');
|
1174
|
+
}
|
1175
|
+
for (var i = 0, len = string.length; i < len; ++i) {
|
1176
|
+
elem.className = elem.className.replace(new RegExp(REGEX_BEGIN + string[i] + REGEX_END), ' ').trim();
|
1177
|
+
}
|
1178
|
+
},
|
1179
|
+
|
1180
|
+
/**
|
1181
|
+
* Test if the nested element has the supply class
|
1182
|
+
* @method hasClass
|
1183
|
+
* @param {} elem
|
1184
|
+
* @param {} string
|
1185
|
+
* @return LogicalExpression
|
1186
|
+
*/
|
1187
|
+
hasClass: function(elem, string) {
|
1188
|
+
return string && new RegExp(REGEX_BEGIN + string + REGEX_END).test(elem.className);
|
1189
|
+
}
|
1190
|
+
};
|
1191
|
+
|
1192
|
+
/**
|
1193
|
+
* A kind of util functions
|
1194
|
+
* @class Util
|
1195
|
+
* @author @dariel_noel
|
1196
|
+
*/
|
1197
|
+
selfish.Util = {
|
1198
|
+
|
1199
|
+
/**
|
1200
|
+
* Thanks a lot to underscore guys
|
1201
|
+
* @method isFunction
|
1202
|
+
* @param {} obj
|
1203
|
+
* @return UnaryExpression
|
1204
|
+
*/
|
1205
|
+
isFunction: function(obj) {
|
1206
|
+
return !!(obj && obj.constructor && obj.call && obj.apply);
|
1207
|
+
},
|
1208
|
+
/**
|
1209
|
+
* Test if some object is an array
|
1210
|
+
* @author Dariel Noel <darielnoel@gmail.com>
|
1211
|
+
* @since 2014-09-09
|
1212
|
+
* @return {Boolean} [description]
|
1213
|
+
*/
|
1214
|
+
beArray:function(object){
|
1215
|
+
return Array.isArray(object);
|
1216
|
+
}
|
1217
|
+
};
|
1218
|
+
|
1219
|
+
/////////////////////////////////////////////////////////
|
1220
|
+
// Public SubModules
|
1221
|
+
/////////////////////////////////////////////////////////
|
1222
|
+
|
1223
|
+
/**
|
1224
|
+
* Event System Interface (AniJS Current Implementation)
|
1225
|
+
* @class EventSystem
|
1226
|
+
* @author @dariel_noel
|
1227
|
+
*/
|
1228
|
+
AniJS.EventSystem = {
|
1229
|
+
|
1230
|
+
//ATTRS
|
1231
|
+
eventCollection: {},
|
1232
|
+
|
1233
|
+
eventIdCounter: 0,
|
1234
|
+
|
1235
|
+
/**
|
1236
|
+
* Return true if the element it's an event target object
|
1237
|
+
* @method isEventTarget
|
1238
|
+
* @param {} element
|
1239
|
+
* @return true or false
|
1240
|
+
*/
|
1241
|
+
isEventTarget: function(element) {
|
1242
|
+
return (element.addEventListener) ? 1 : 0;
|
1243
|
+
},
|
1244
|
+
|
1245
|
+
/**
|
1246
|
+
* Create new EventTarget element
|
1247
|
+
* @method createEventTarget
|
1248
|
+
* @return AniJS.EventTarget
|
1249
|
+
*/
|
1250
|
+
createEventTarget: function() {
|
1251
|
+
return new AniJS.EventTarget();
|
1252
|
+
},
|
1253
|
+
|
1254
|
+
/**
|
1255
|
+
* Put a listener in the object
|
1256
|
+
* @method addEventListenerHelper
|
1257
|
+
* @param {} eventTargetItem
|
1258
|
+
* @param {} event
|
1259
|
+
* @param {} listener
|
1260
|
+
* @param {} other
|
1261
|
+
* @return
|
1262
|
+
*/
|
1263
|
+
addEventListenerHelper: function(eventTargetItem, event, listener, other) {
|
1264
|
+
eventTargetItem.addEventListener(event, listener, false);
|
1265
|
+
},
|
1266
|
+
|
1267
|
+
/**
|
1268
|
+
* Put a listener of the object
|
1269
|
+
* @method removeEventListenerHelper
|
1270
|
+
* @param {} e
|
1271
|
+
* @param {} arguments
|
1272
|
+
* @return
|
1273
|
+
*/
|
1274
|
+
removeEventListenerHelper: function(element, type, listener) {
|
1275
|
+
if(element){
|
1276
|
+
element.removeEventListener(type, listener);
|
1277
|
+
}
|
1278
|
+
},
|
1279
|
+
|
1280
|
+
|
1281
|
+
/**
|
1282
|
+
* Purge all register elements handle
|
1283
|
+
* @method purgeAll
|
1284
|
+
* @return
|
1285
|
+
*/
|
1286
|
+
purgeAll: function() {
|
1287
|
+
var instance = this,
|
1288
|
+
eventCollection = instance.eventCollection,
|
1289
|
+
eventCollectionKeyList = Object.keys(eventCollection),
|
1290
|
+
size = eventCollectionKeyList.length,
|
1291
|
+
i = 0,
|
1292
|
+
key,
|
1293
|
+
eventObject;
|
1294
|
+
|
1295
|
+
for (i; i < size; i++) {
|
1296
|
+
key = eventCollectionKeyList[i];
|
1297
|
+
eventObject = eventCollection[key];
|
1298
|
+
|
1299
|
+
if (eventObject && eventObject.handleCollection && eventObject.handleCollection.length > 0) {
|
1300
|
+
instance.purgeEventTarget(eventObject.handleCollection[0].element);
|
1301
|
+
}
|
1302
|
+
|
1303
|
+
delete eventCollection[key];
|
1304
|
+
}
|
1305
|
+
},
|
1306
|
+
|
1307
|
+
/**
|
1308
|
+
* Detach all AniJS subscriptions to the all nodes bellow this
|
1309
|
+
* @method purgeAllNodes
|
1310
|
+
* @param {} element
|
1311
|
+
* @return
|
1312
|
+
*/
|
1313
|
+
purgeAllNodes: function(element){
|
1314
|
+
//Dame todos los que tengan data-anijs
|
1315
|
+
//a cada uno purgue
|
1316
|
+
var nodes = element.querySelectorAll("*");
|
1317
|
+
size = nodes.length;
|
1318
|
+
for (var i = size - 1; i >= 0; i--) {
|
1319
|
+
this.purgeEventTarget(nodes[i]);
|
1320
|
+
}
|
1321
|
+
},
|
1322
|
+
|
1323
|
+
/**
|
1324
|
+
* Detach all AniJS subscriptions to this element
|
1325
|
+
* @method purgeEventTarget
|
1326
|
+
* @param {} element
|
1327
|
+
* @return
|
1328
|
+
*/
|
1329
|
+
purgeEventTarget: function(element) {
|
1330
|
+
var instance = this,
|
1331
|
+
aniJSEventID = element._aniJSEventID,
|
1332
|
+
elementHandleCollection;
|
1333
|
+
if (aniJSEventID) {
|
1334
|
+
|
1335
|
+
//Se le quitan todos los eventos a los que este suscrito
|
1336
|
+
elementHandleCollection = instance.eventCollection[aniJSEventID].handleCollection;
|
1337
|
+
|
1338
|
+
var size = elementHandleCollection.length,
|
1339
|
+
i = 0,
|
1340
|
+
item;
|
1341
|
+
|
1342
|
+
for (i; i < size; i++) {
|
1343
|
+
item = elementHandleCollection[i];
|
1344
|
+
|
1345
|
+
//Para cada handle
|
1346
|
+
instance.removeEventListenerHelper(element, item.eventType, item.listener);
|
1347
|
+
|
1348
|
+
}
|
1349
|
+
instance.eventCollection[aniJSEventID] = element._aniJSEventID = null;
|
1350
|
+
delete instance.eventCollection[aniJSEventID];
|
1351
|
+
delete element._aniJSEventID;
|
1352
|
+
}
|
1353
|
+
},
|
1354
|
+
|
1355
|
+
/**
|
1356
|
+
* Create a handle to remove the listener when purge it
|
1357
|
+
* @method registerEventHandle
|
1358
|
+
* @param {} element
|
1359
|
+
* @param {} eventType
|
1360
|
+
* @param {} listener
|
1361
|
+
* @return
|
1362
|
+
*/
|
1363
|
+
registerEventHandle: function(element, eventType, listener) {
|
1364
|
+
var instance = this,
|
1365
|
+
aniJSEventID = element._aniJSEventID,
|
1366
|
+
eventCollection = instance.eventCollection,
|
1367
|
+
elementEventHandle = {
|
1368
|
+
eventType: eventType,
|
1369
|
+
listener: listener,
|
1370
|
+
element: element
|
1371
|
+
};
|
1372
|
+
|
1373
|
+
if (aniJSEventID) {
|
1374
|
+
eventCollection[aniJSEventID].handleCollection.push(elementEventHandle);
|
1375
|
+
} else {
|
1376
|
+
var tempEventHandle = {
|
1377
|
+
handleCollection: [elementEventHandle]
|
1378
|
+
};
|
1379
|
+
|
1380
|
+
eventCollection[++instance.eventIdCounter] = tempEventHandle;
|
1381
|
+
element._aniJSEventID = instance.eventIdCounter;
|
1382
|
+
}
|
1383
|
+
}
|
1384
|
+
|
1385
|
+
};
|
1386
|
+
|
1387
|
+
|
1388
|
+
/**
|
1389
|
+
* Helper the custom EventTarget
|
1390
|
+
* Copyright (c) 2010 Nicholas C. Zakas. All rights reserved.
|
1391
|
+
* MIT License
|
1392
|
+
* http://www.nczonline.net/blog/2010/03/09/custom-events-in-javascript/
|
1393
|
+
* @class EventTarget
|
1394
|
+
*/
|
1395
|
+
AniJS.EventTarget = function EventTarget() {
|
1396
|
+
this._listeners = {};
|
1397
|
+
};
|
1398
|
+
|
1399
|
+
AniJS.EventTarget.prototype = {
|
1400
|
+
|
1401
|
+
constructor: AniJS.EventTarget,
|
1402
|
+
|
1403
|
+
/**
|
1404
|
+
* Registers the specified listener on the EventTarget it's called on
|
1405
|
+
* Similar to the native implementation
|
1406
|
+
* @method addEventListener
|
1407
|
+
* @param {} type
|
1408
|
+
* @param {} listener
|
1409
|
+
* @param {} other
|
1410
|
+
* @return
|
1411
|
+
*/
|
1412
|
+
addEventListener: function(type, listener, other) {
|
1413
|
+
var instance = this;
|
1414
|
+
if (typeof instance._listeners[type] == "undefined") {
|
1415
|
+
instance._listeners[type] = [];
|
1416
|
+
}
|
1417
|
+
|
1418
|
+
instance._listeners[type].push(listener);
|
1419
|
+
},
|
1420
|
+
|
1421
|
+
/**
|
1422
|
+
* Dispatches an Event at the specified EventTarget
|
1423
|
+
* Similar to the native implementation
|
1424
|
+
* @method dispatchEvent
|
1425
|
+
* @param {} event
|
1426
|
+
* @return
|
1427
|
+
*/
|
1428
|
+
dispatchEvent: function(event) {
|
1429
|
+
var instance = this;
|
1430
|
+
if (typeof event == "string") {
|
1431
|
+
event = {
|
1432
|
+
type: event
|
1433
|
+
};
|
1434
|
+
}
|
1435
|
+
if (!event.target) {
|
1436
|
+
event.target = instance;
|
1437
|
+
}
|
1438
|
+
|
1439
|
+
if (!event.type) { //falsy
|
1440
|
+
throw new Error("Event object missing 'type' property.");
|
1441
|
+
}
|
1442
|
+
|
1443
|
+
if (this._listeners[event.type] instanceof Array) {
|
1444
|
+
var listeners = instance._listeners[event.type];
|
1445
|
+
|
1446
|
+
for (var i = 0, len = listeners.length; i < len; i++) {
|
1447
|
+
listeners[i].call(instance, event);
|
1448
|
+
}
|
1449
|
+
}
|
1450
|
+
},
|
1451
|
+
|
1452
|
+
/**
|
1453
|
+
* Removes the event listener previously registered with EventTarget.addEventListener.
|
1454
|
+
* Similar to the native implementation
|
1455
|
+
* @method removeEventListener
|
1456
|
+
* @param {} type
|
1457
|
+
* @param {} listener
|
1458
|
+
* @return
|
1459
|
+
*/
|
1460
|
+
removeEventListener: function(type, listener) {
|
1461
|
+
var instance = this;
|
1462
|
+
if (instance._listeners[type] instanceof Array) {
|
1463
|
+
var listeners = instance._listeners[type];
|
1464
|
+
for (var i = 0, len = listeners.length; i < len; i++) {
|
1465
|
+
if (listeners[i] === listener) {
|
1466
|
+
listeners.splice(i, 1);
|
1467
|
+
break;
|
1468
|
+
}
|
1469
|
+
}
|
1470
|
+
}
|
1471
|
+
}
|
1472
|
+
};
|
1473
|
+
|
1474
|
+
return AniJS;
|
1475
|
+
|
1476
|
+
}(AniJS || {}));
|
1477
|
+
|
1478
|
+
AniJS.init();
|
1479
|
+
AniJS.run();
|
1480
|
+
|
1481
|
+
// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
|
1482
|
+
// AMD Support
|
1483
|
+
if (typeof define === "function" && define.amd) {
|
1484
|
+
define("anijs", [], function() {
|
1485
|
+
return AniJS;
|
1486
|
+
});
|
1487
|
+
}
|
1488
|
+
if (typeof noGlobal == typeof undefined) {
|
1489
|
+
window.AniJS = AniJS;
|
1490
|
+
}
|
1491
|
+
|
1492
|
+
return AniJS;
|
1493
|
+
});
|