anijs-rails 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ });