<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <my-object></my-object>

    <script type="text/javascript" src="https://cdn.rawgit.com/riot/riot/master/riot+compiler.min.js"></script>
    <script type="text/javascript" src="interact.js"></script>
    <script type="riot/tag" src="./my-object.html"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.4.0/animate.min.css">

    <script type="text/javascript">
      riot.mount('*')
    </script>
    
    <style>
        h3 {
            display: inline-block;
            text-align: center;
            background: #3872FA;
            margin: 1em;
            color: white;
            padding: 4em 0;
            width: 7em;
            box-sizing: border-box;
            cursor: pointer;
        }
        body
        {
            font-family: Verdana;
        }
        h3 span {display: block;}
        h3:hover span
        {
            color: #FE8A8A;
        }
        .button {
          cursor: pointer;
          box-shadow: inset 0 -0.3em 0 rgba(0, 0, 0, 0.5);
          background: #f2f2f2;
          color: #1f1f1f;
          width: 100%;
          display: block;
          border: 1px solid #1f1f1f;
          line-height: 2;
          padding: 0 1em;
          margin-bottom: 1em;
          transition-duration: 0.5s;
          transition-delay: 0s;
          transition-timing-function: ease;
          transition-property: all;
          background: #247ca8;
          color: #f2f2f2;
          border: 0;
          border-radius: .2em;
          padding: .2em 1em .5em;
          position: relative;
          top: 0;
          display: inline-block;
          width: auto;
        }
        .button:hover {
          background: #288cbd;
          color: #ffffff;
        }
        .button:focus {
          box-shadow: none;
          top: 0.3em;
          background: #1f6d93;
          color: #e5e5e5;
        }
        
    </style>

  </body>
</html>
<my-object>
    <div onclick={add} class="button">Add</div>
    <div name="example">
        <h3 class="animated fadeInUp" if={message.exist} each={message in messages} onclick={remove}>{ message.name } <span>&times;</span></h3>
    </div>
    
  

  <script>
        this.mixin(interact)
        this.messages = [
            
            {
                name: 'hello there', 
                exist: true
            },
            {
                name: 'cookie', 
                exist: true
            },
        ]
        
        this.on(
            'mount', function()
            {
                var x = new this.interaction(this.example)
                console.log(x)
            }
        )
        
        remove(e) {
            e.item.message.exist = false
        }
        
        add(e) {
            this.messages.push({name:Math.random()*30 | 0, exist: true})
        }
    
  </script>
</my-object>
var interact = {
	interaction : function(element, classes)
	{
		classes = classes || ['animated','fadeOut']
		this.element = element
		this.classes = ' ' + classes.join(' ')
		this.observer = {}

		this.setup = function()
		{
			if (JSON.stringify(this.observer) != '{}')
			{
				this.observe()
				return this
			}

			this.observer = new MutationObserver(
				function (mutations)
				{
					this._doAnimate(mutations, this)
				}.bind(this)
			)

			this.observe()
			return this.observer
		}

		this.observe = function()
		{
			this.observer.observe(			
				this.element, 
				{
					childList: true,
					attributes: false,
					characterData: false,
	
				}
			) 
		}

		this.disconnect = function()
		{
			this.observer.disconnect()
		}

		this._doAnimate = function(mutations, observer)
		{
			for (var mutation in mutations)
			{
				mutation = mutations[mutation]
				if (mutation.removedNodes.length)
				{
					var nodes = Array.prototype.slice.call(mutation.removedNodes)
					
					for (var node in nodes)
					{
						node = nodes[node]
						node.className += observer.classes
						if (node.className.length > 120)
						{
							window.document.body.innerHTML = 'STOP!!'
							// This is just added for security, in case the observer 
							// does not fire the disconnect and is trapped in the loop
						}
						var next = mutation.nextSibling
						var prev = mutation.previousSibling
						
						if (!next)
						{
						   mutation.target.appendChild(node)
						}
						else if (next)
						{
							mutation.target.insertBefore(node, mutation.nextSibling)
						}
						
						node.addEventListener(
							"animationend",
							function(e)
							{
								observer.disconnect()
								e.target.remove()
								observer.observe()
							}.bind(this)
						)
						//node.target.appendChild()
					}
				}
			}
		}

		this.setup()
	}

	
}