diff --git a/animate.coffee b/animate.coffee
deleted file mode 100644
index a08a29b..0000000
--- a/animate.coffee
+++ /dev/null
@@ -1,13 +0,0 @@
-Template.animate.onRendered ->
- self = @
- $node = @$('>').first()
- animation = self.data?.type || 'bounce'
- delay = self.data?.delay && parseInt(self.data.delay) || 200
-
- animate = ->
- $node.addClass("animated #{animation}")
-
- if delay
- Meteor.setTimeout animate, delay
- else
- animate()
diff --git a/animate.js b/animate.js
new file mode 100644
index 0000000..d1b58e6
--- /dev/null
+++ b/animate.js
@@ -0,0 +1,14 @@
+Template.animate.onRendered(function() {
+ const self = this;
+ const $node = this.$('>').first();
+ const animation = (self.data != null ? self.data.type : undefined) || 'bounce';
+ const delay = ((self.data != null ? self.data.delay : undefined) && parseInt(self.data.delay)) || 200;
+
+ const animate = () => $node.addClass(`animated ${animation}`);
+
+ if (delay) {
+ return Meteor.setTimeout(animate, delay);
+ } else {
+ return animate();
+ }
+});
diff --git a/package.js b/package.js
index 45411d0..e1fe826 100644
--- a/package.js
+++ b/package.js
@@ -1,6 +1,6 @@
Package.describe({
name: 'webtempest:animate',
- version: '0.1.9',
+ version: '0.2.0',
summary: 'Easily perform CSS animations and transitions in Meteor',
git: 'https://github.com/webtempest/meteor-animate.git',
documentation: 'README.md'
@@ -8,13 +8,12 @@ Package.describe({
Package.onUse(function(api) {
api.versionsFrom('1.1.0.3');
- api.use('coffeescript');
api.use('templating');
api.addFiles([
'transition.html',
- 'transitions.coffee',
+ 'transitions.js',
'animate.html',
- 'animate.coffee',
+ 'animate.js',
'animate.css'
], 'client');
});
diff --git a/transitions.coffee b/transitions.coffee
deleted file mode 100644
index 209e853..0000000
--- a/transitions.coffee
+++ /dev/null
@@ -1,129 +0,0 @@
-ENDTRANSITION = 'transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd transitionEnd msTransitionEnd animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd animationEnd msAnimationEnd'
-
-class Transitions
- constructor: (options) ->
- defaults =
- onScreenClass: ''
- offScreenClass: ''
- hiddenClass: 'out'
- animateClass: "animated"
-
- @opt = _.defaults options, defaults
- @opt.insertTimeout = @getInsertTimeout()
- @opt.removeTimeout = @getRemoveTimeout()
- @opt.parentNode._uihooks = @createHooks()
-
- self = @
- @setupStyles()
-
- # This for when the page first loads
- _.each $(@opt.parentNode).find('.animated.out'), (item) ->
- self.insertElement(item, null)
-
- setupStyles: ->
- if @opt.inDuration or @opt.outDuration
-
- # For durations to be changed we need to inject CSS
- randName = @opt.onScreenClass + _.random(0, 1000)
-
- styleInjection = $("")
- $(@opt.parentNode).addClass(randName)
-
- if @opt.inDuration
- styleInjection.append(".#{randName} .animated.#{@opt.onScreenClass} {-webkit-animation-duration: #{@opt.inDuration}ms;animation-duration: #{@opt.inDuration}ms;}")
-
- if @opt.outDuration
- styleInjection.append(".#{randName} .animated.#{@opt.offScreenClass} {-webkit-animation-duration: #{@opt.outDuration}ms;animation-duration: #{@opt.outDuration}ms;}")
-
- $(@opt.parentNode).append(styleInjection)
-
- getInsertTimeout: ->
- return parseInt(@opt.inDuration) if @opt.inDuration
- switch @opt.onScreenClass
- when 'hinge' then 2000
- when 'bounceIn' then 750
- else 1000
-
- getRemoveTimeout: ->
- return parseInt(@opt.outDuration) if @opt.outDuration
- switch @opt.offScreenClass
- when 'hinge' then 2000
- when 'bounceOut' then 750
- when 'flipOutX' then 750
- when 'flipOutY' then 750
- else 1000
-
- insertElement: (node, next) ->
- self = @
- $node = $(node)
- $parent = $(self.opt.parentNode)
- $node.addClass("#{self.opt.animateClass} #{self.opt.hiddenClass}")
- $node.attr('hidden', true)
- $(next).before($node)
-
- finish = (e) ->
- $node.removeClass(self.opt.onScreenClass)
- node.setAttribute('inserting', false)
-
- insert = ->
- $node.width()
- $node.attr('hidden', false)
- $node.removeClass(self.opt.hiddenClass)
- $node.addClass(self.opt.onScreenClass)
- $node.one ENDTRANSITION, finish
-
- if self.removing
- Meteor.setTimeout insert, self.opt.removeTimeout
- else
- insert()
-
- removeElement: (node) ->
- $node = $(node)
-
- self = @
- $node.addClass(self.opt.animateClass)
- remove = (e) ->
- self.removing = false
- $node.remove()
-
- if self.opt.offScreenClass
- $node.addClass(self.opt.offScreenClass)
- self.removing = true
- $node.one ENDTRANSITION, remove
- else
- remove()
-
- createHooks: ->
- opt: @opt
- insertElement: @insertElement
- removeElement: @removeElement
-
-
-Template.transition.onRendered ->
- transitionIn = @data?.in?.match(/^(.*)\:/)?[1] || @data?.in
- transitionOut = @data?.out?.match(/^(.*)\:/)?[1] || @data?.out
-
- # Duration can be passed in like this:
- # in="bounceIn:500"
- # 500 means 500 milliseconds
- inDuration = @data?.in?.match(/\:(\d*)/)?[1]
- outDuration = @data?.out?.match(/\:(\d*)/)?[1]
-
- # If "wrap=true" is provided, then div.transition-wrapper will
- # be the parent. Else just whatever is the parent above this template.
- if @$('>').first().hasClass('transition-wrapper')
- parentNode = @$('>').first()[0]
- else
- parentNode = @firstNode?.parentNode
-
- params =
- onScreenClass: transitionIn
- offScreenClass: transitionOut
- inDuration: inDuration
- outDuration: outDuration
- parentNode: parentNode
-
- transitions = new Transitions(params)
-
-Template.transition.onDestroyed ->
- @firstNode?.parentNode?._uihooks = null
diff --git a/transitions.js b/transitions.js
new file mode 100644
index 0000000..abe1385
--- /dev/null
+++ b/transitions.js
@@ -0,0 +1,168 @@
+/**
+ * Created by matt_000 on 24/09/2018.
+ */
+/*
+ * decaffeinate suggestions:
+ * DS102: Remove unnecessary code created because of implicit returns
+ * DS103: Rewrite code to no longer use __guard__
+ * DS207: Consider shorter variations of null checks
+ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
+ */
+const ENDTRANSITION = 'transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd transitionEnd msTransitionEnd animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd animationEnd msAnimationEnd';
+
+class Transitions {
+ constructor(options) {
+ const defaults = {
+ onScreenClass: '',
+ offScreenClass: '',
+ hiddenClass: 'out',
+ animateClass: "animated"
+ };
+
+ this.opt = _.defaults(options, defaults);
+ this.opt.insertTimeout = this.getInsertTimeout();
+ this.opt.removeTimeout = this.getRemoveTimeout();
+ this.opt.parentNode._uihooks = this.createHooks();
+
+ const self = this;
+ this.setupStyles();
+
+ // This for when the page first loads
+ _.each($(this.opt.parentNode).find('.animated.out'), item => self.insertElement(item, null));
+ }
+
+ setupStyles() {
+ if (this.opt.inDuration || this.opt.outDuration) {
+
+ // For durations to be changed we need to inject CSS
+ const randName = this.opt.onScreenClass + _.random(0, 1000);
+
+ const styleInjection = $("");
+ $(this.opt.parentNode).addClass(randName);
+
+ if (this.opt.inDuration) {
+ styleInjection.append(`.${randName} .animated.${this.opt.onScreenClass} {-webkit-animation-duration: ${this.opt.inDuration}ms;animation-duration: ${this.opt.inDuration}ms;}`);
+ }
+
+ if (this.opt.outDuration) {
+ styleInjection.append(`.${randName} .animated.${this.opt.offScreenClass} {-webkit-animation-duration: ${this.opt.outDuration}ms;animation-duration: ${this.opt.outDuration}ms;}`);
+ }
+
+ return $(this.opt.parentNode).append(styleInjection);
+ }
+ }
+
+ getInsertTimeout() {
+ if (this.opt.inDuration) { return parseInt(this.opt.inDuration); }
+ switch (this.opt.onScreenClass) {
+ case 'hinge': return 2000;
+ case 'bounceIn': return 750;
+ default: return 1000;
+ }
+ }
+
+ getRemoveTimeout() {
+ if (this.opt.outDuration) { return parseInt(this.opt.outDuration); }
+ switch (this.opt.offScreenClass) {
+ case 'hinge': return 2000;
+ case 'bounceOut': return 750;
+ case 'flipOutX': return 750;
+ case 'flipOutY': return 750;
+ default: return 1000;
+ }
+ }
+
+ insertElement(node, next) {
+ const self = this;
+ const $node = $(node);
+ const $parent = $(self.opt.parentNode);
+ $node.addClass(`${self.opt.animateClass} ${self.opt.hiddenClass}`);
+ $node.attr('hidden', true);
+ $(next).before($node);
+
+ const finish = function(e) {
+ $node.removeClass(self.opt.onScreenClass);
+ return node.setAttribute('inserting', false);
+ };
+
+ const insert = function() {
+ $node.width();
+ $node.attr('hidden', false);
+ $node.removeClass(self.opt.hiddenClass);
+ $node.addClass(self.opt.onScreenClass);
+ return $node.one(ENDTRANSITION, finish);
+ };
+
+ if (self.removing) {
+ return Meteor.setTimeout(insert, self.opt.removeTimeout);
+ } else {
+ return insert();
+ }
+ }
+
+ removeElement(node) {
+ const $node = $(node);
+
+ const self = this;
+ $node.addClass(self.opt.animateClass);
+ const remove = function(e) {
+ self.removing = false;
+ return $node.remove();
+ };
+
+ if (self.opt.offScreenClass) {
+ $node.addClass(self.opt.offScreenClass);
+ self.removing = true;
+ return $node.one(ENDTRANSITION, remove);
+ } else {
+ return remove();
+ }
+ }
+
+ createHooks() {
+ return {
+ opt: this.opt,
+ insertElement: this.insertElement,
+ removeElement: this.removeElement
+ };
+ }
+}
+
+
+Template.transition.onRendered(function() {
+ let parentNode, transitions;
+ const transitionIn = __guard__(__guard__(this.data != null ? this.data.in : undefined, x1 => x1.match(/^(.*)\:/)), x => x[1]) || (this.data != null ? this.data.in : undefined);
+ const transitionOut = __guard__(__guard__(this.data != null ? this.data.out : undefined, x3 => x3.match(/^(.*)\:/)), x2 => x2[1]) || (this.data != null ? this.data.out : undefined);
+
+ // Duration can be passed in like this:
+ // in="bounceIn:500"
+ // 500 means 500 milliseconds
+ const inDuration = __guard__(__guard__(this.data != null ? this.data.in : undefined, x5 => x5.match(/\:(\d*)/)), x4 => x4[1]);
+ const outDuration = __guard__(__guard__(this.data != null ? this.data.out : undefined, x7 => x7.match(/\:(\d*)/)), x6 => x6[1]);
+
+ // If "wrap=true" is provided, then div.transition-wrapper will
+ // be the parent. Else just whatever is the parent above this template.
+ if (this.$('>').first().hasClass('transition-wrapper')) {
+ parentNode = this.$('>').first()[0];
+ } else {
+ parentNode = this.firstNode != null ? this.firstNode.parentNode : undefined;
+ }
+
+ const params = {
+ onScreenClass: transitionIn,
+ offScreenClass: transitionOut,
+ inDuration,
+ outDuration,
+ parentNode
+ };
+
+ return transitions = new Transitions(params);
+});
+
+Template.transition.onDestroyed(function() {
+ return __guard__(this.firstNode != null ? this.firstNode.parentNode : undefined, x => x._uihooks = null);
+});
+
+function __guard__(value, transform) {
+ return (typeof value !== 'undefined' && value !== null) ? transform(value) : undefined;
+}