<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="tabs.css">
</head>
<body>
<p>Custom Tag</p>
<alerts></alerts>
<code id="target"></code>
<script src="alert.html" type="riot/tag"></script>
<script src="alerts.html" type="riot/tag"></script>
<script src="riotcompiler.js"></script>
<script>
riot.mount('alerts', {
items: [{
player: 'Player 1',
category: 'info'
},{
player: 'Player 2',
category: 'warning'
}]
});
setTimeout(function() {
var el = document.getElementById('alerts')
var pre = document.getElementById('target')
console.log(el, pre)
var sample_html = el.outerHTML;
sample_html = sample_html.replace(/</g,"<").replace(/>/g,">");
pre.innerHTML = sample_html;
}, 4000)
</script>
</body>
</html>
Riot JS Tabs Example
====================
Tutorial from http://www.robertwpearce.com/blog/riotjs-example/ updated for in browser compile
Also updated to pass tabs from script ex.
````javascript
var tabs = [{ title: 'Tab 1', ref: 'tab1', content: "...},...]
riot.mount('tabs', {"tabs": tabs})
````
routing added, not sure if this is the proper way
*, *:before, *:after {
box-sizing: border-box; }
body {
font-size: 16px;
font-family: Helvetica;
line-height: 1.5;
font-weight: 300;
margin: 0;
padding: 0;
color: #55AFA8; }
a {
color: #B4EAE6;
cursor: pointer;
text-decoration: none;
border-bottom: 1px dotted; }
iframe {
border: none;
width: 100%; }
iframe.iframe--tabs {
height: 550px; }
iframe.iframe--posts {
height: 400px; }
.list--bare, .post__locations, .listing__comments {
list-style: none;
margin: 0;
padding: 0; }
.section, .section--main {
padding: 75px 0;
background-color: #FFF;
border-bottom: 1px solid #B4EAE6; }
.section--main {
background-color: #55AFA8;
color: #FFF;
border-bottom: none; }
.section--main h1 {
font-size: 3em; }
.layout--constrained {
width: 400px;
margin: 0 auto; }
tabs {
display: block; }
.tab {
display: inline-block;
vertical-align: middle;
width: 75px;
height: 45px;
line-height: 45px;
text-align: center;
cursor: pointer;
border: 1px solid;
background-color: #FFF;
margin-bottom: -1px;
margin-right: 5px; }
.tab.is-active {
border-bottom: none; }
.tabContent {
border: 1px solid;
padding: 20px; }
.tabContent__item {
display: none; }
.tabContent__item.is-active {
display: block; }
posts {
display: block; }
.listing {
margin-bottom: 50px;
width: 280px;
padding: 15px 0;
border: 1px solid #55AFA8;
margin-bottom: 25px;
font-size: 0; }
.listing__item {
display: inline-block;
vertical-align: middle;
font-size: 1.25rem;
width: 33.333333%;
text-align: center;
cursor: pointer;
border-right: 1px solid #55AFA8; }
.listing__item.is-inactive {
opacity: 0.4; }
.listing__item:last-of-type {
border-right: none; }
.listing__author {
display: inline-block;
vertical-align: middle;
cursor: pointer; }
.listing__author img {
display: inline-block;
vertical-align: middle;
width: 60px;
height: 60px;
border-radius: 50%; }
.listing__info {
padding-top: 20px;
height: 0;
visibility: hidden;
position: absolute;
transition: all 0.3s ease-in-out; }
.is-active .listing__info {
height: auto;
visibility: visible;
position: relative; }
.post__location--start,
.post__location--via,
.post__location--stop {
position: relative;
padding-left: 32px;
line-height: 1; }
.post__location--start:before,
.post__location--via:before,
.post__location--stop:before {
content: "";
position: absolute;
left: 12px;
border-left: 1px solid #55AFA8;
height: 100%;
width: 1px; }
.post__location--start:after,
.post__location--via:after,
.post__location--stop:after {
position: absolute;
left: 5px; }
.post__location--start,
.post__location--via {
padding-bottom: 15px; }
.post__location--via {
font-size: 0.813rem; }
.post__location--via:after {
content: "";
position: absolute;
top: 6px;
left: 12px;
border-bottom: 1px solid #55AFA8;
width: 6px;
height: 1px; }
.post__location--start:after,
.post__location--stop:after {
content: "";
width: 15px;
height: 15px;
border-radius: 50%;
border-width: 2px;
border-style: solid;
background-color: #82d0c9; }
.post__location--start:after {
border-color: #55AFA8;
top: 0; }
.post__location--stop:after {
border-color: #55AFA8;
bottom: 0; }
.listing__comments {
border-top: 1px solid #55AFA8;
margin-top: 20px; }
.listing__comments > li {
margin-top: 15px; }
.listing__comments img, .listing__comments span {
display: inline-block;
vertical-align: top; }
.listing__comments img {
width: 30px;
height: 30px;
border-radius: 50%; }
.listing__comments span {
padding-top: 3px;
padding-left: 5px;
width: 200px; }
.listing__infoContact {
margin-top: 10px;
border: 1px solid #55AFA8;
display: inline-block;
padding: 5px 10px; }
/*# sourceMappingURL=app.css.map */
/* Custom versione related to: https://github.com/muut/riotjs/issues/295
* Modification 1 lines: 523
* Modification 2 lines: 542 - 547
/* Riot 2.0.7, @license MIT, (c) 2015 Muut Inc. + contributors */
/* Riot 2.0.7, @license MIT, (c) 2015 Muut Inc. + contributors */
;(function() {
var riot = { version: 'v2.0.7' }
'use strict'
riot.observable = function(el) {
el = el || {}
var callbacks = {}
el.on = function(events, fn) {
if (typeof fn == 'function') {
events.replace(/\S+/g, function(name, pos) {
(callbacks[name] = callbacks[name] || []).push(fn)
fn.typed = pos > 0
})
}
return el
}
el.off = function(events, fn) {
if (events == '*') callbacks = {}
else if (fn) {
var arr = callbacks[events]
for (var i = 0, cb; (cb = arr && arr[i]); ++i) {
if (cb == fn) { arr.splice(i, 1); i-- }
}
} else {
events.replace(/\S+/g, function(name) {
callbacks[name] = []
})
}
return el
}
// only single event supported
el.one = function(name, fn) {
if (fn) fn.one = 1
return el.on(name, fn)
}
el.trigger = function(name) {
var args = [].slice.call(arguments, 1),
fns = callbacks[name] || []
for (var i = 0, fn; (fn = fns[i]); ++i) {
if (!fn.busy) {
fn.busy = 1
fn.apply(el, fn.typed ? [name].concat(args) : args)
if (fn.one) { fns.splice(i, 1); i-- }
else if (fns[i] !== fn) { i-- } // Makes self-removal possible during iteration
fn.busy = 0
}
}
return el
}
return el
}
;(function(riot, evt) {
// browsers only
if (!this.top) return
var loc = location,
fns = riot.observable(),
current = hash(),
win = window
function hash() {
return loc.hash.slice(1)
}
function parser(path) {
return path.split('/')
}
function emit(path) {
if (path.type) path = hash()
if (path != current) {
fns.trigger.apply(null, ['H'].concat(parser(path)))
current = path
}
}
var r = riot.route = function(arg) {
// string
if (arg[0]) {
loc.hash = arg
emit(arg)
// function
} else {
fns.on('H', arg)
}
}
r.exec = function(fn) {
fn.apply(null, parser(hash()))
}
r.parser = function(fn) {
parser = fn
}
win.addEventListener ? win.addEventListener(evt, emit, false) : win.attachEvent('on' + evt, emit)
})(riot, 'hashchange')
/*
//// How it works?
Three ways:
1. Expressions: tmpl('{ value }', data).
Returns the result of evaluated expression as a raw object.
2. Templates: tmpl('Hi { name } { surname }', data).
Returns a string with evaluated expressions.
3. Filters: tmpl('{ show: !done, highlight: active }', data).
Returns a space separated list of trueish keys (mainly
used for setting html classes), e.g. "show highlight".
// Template examples
tmpl('{ title || "Untitled" }', data)
tmpl('Results are { results ? "ready" : "loading" }', data)
tmpl('Today is { new Date() }', data)
tmpl('{ message.length > 140 && "Message is too long" }', data)
tmpl('This item got { Math.round(rating) } stars', data)
tmpl('<h1>{ title }</h1>{ body }', data)
// Falsy expressions in templates
In templates (as opposed to single expressions) all falsy values
except zero (undefined/null/false) will default to empty string:
tmpl('{ undefined } - { false } - { null } - { 0 }', {})
// will return: " - - - 0"
*/
riot._tmpl = (function() {
var cache = {},
// find variable names
re_vars = /("|').+?[^\\]\1|\.\w*|\w*:|\b(?:this|true|false|null|undefined|new|typeof|Number|String|Object|Array|Math|Date|JSON)\b|([a-z_]\w*)/gi
// [ 1 ][ 2 ][ 3 ][ 4 ][ 5 ]
// 1. skip quoted strings: "a b", 'a b', 'a \'b\''
// 2. skip object properties: .name
// 3. skip object literals: name:
// 4. skip reserved words
// 5. match var name
// build a template (or get it from cache), render with data
return function(str, data) {
return str && (cache[str] = cache[str] || tmpl(str))(data)
}
// create a template instance
function tmpl(s, p) {
p = (s || '{}')
// temporarily convert \{ and \} to a non-character
.replace(/\\{/g, '\uFFF0')
.replace(/\\}/g, '\uFFF1')
// split string to expression and non-expresion parts
.split(/({[\s\S]*?})/)
return new Function('d', 'return ' + (
// is it a single expression or a template? i.e. {x} or <b>{x}</b>
!p[0] && !p[2]
// if expression, evaluate it
? expr(p[1])
// if template, evaluate all expressions in it
: '[' + p.map(function(s, i) {
// is it an expression or a string (every second part is an expression)
return i % 2
// evaluate the expressions
? expr(s, 1)
// process string parts of the template:
: '"' + s
// preserve new lines
.replace(/\n/g, '\\n')
// escape quotes
.replace(/"/g, '\\"')
+ '"'
}).join(',') + '].join("")'
)
// bring escaped { and } back
.replace(/\uFFF0/g, '{')
.replace(/\uFFF1/g, '}')
)
}
// parse { ... } expression
function expr(s, n) {
s = s
// convert new lines to spaces
.replace(/\n/g, ' ')
// trim whitespace, curly brackets, strip comments
.replace(/^[{ ]+|[ }]+$|\/\*.+?\*\//g, '')
// is it an object literal? i.e. { key : value }
return /^\s*[\w-"']+ *:/.test(s)
// if object literal, return trueish keys
// e.g.: { show: isOpen(), done: item.done } -> "show done"
? '[' + s.replace(/\W*([\w-]+)\W*:([^,]+)/g, function(_, k, v) {
// safely execute vars to prevent undefined value errors
return v.replace(/\w[^,|& ]*/g, function(v) { return wrap(v, n) }) + '?"' + k + '":"",'
}) + '].join(" ")'
// if js expression, evaluate as javascript
: wrap(s, n)
}
// execute js w/o breaking on errors or undefined vars
function wrap(s, nonull) {
return '(function(v){try{v='
// prefix vars (name => data.name)
+ (s.replace(re_vars, function(s, _, v) { return v ? 'd.' + v : s })
// break the expression if its empty (resulting in undefined value)
|| 'x')
+ '}finally{return '
// default to empty string for falsy values except zero
+ (nonull ? '!v&&v!==0?"":v' : 'v')
+ '}}).call(d)'
}
})()
;(function(riot, is_browser) {
if (!is_browser) return
var tmpl = riot._tmpl,
all_tags = [],
tag_impl = {},
doc = document
function each(nodes, fn) {
for (var i = 0; i < (nodes || []).length; i++) {
if (fn(nodes[i], i) === false) i--
}
}
function extend(obj, from) {
from && Object.keys(from).map(function(key) {
obj[key] = from[key]
})
return obj
}
function diff(arr1, arr2) {
return arr1.filter(function(el) {
return arr2.indexOf(el) < 0
})
}
function walk(dom, fn) {
dom = fn(dom) === false ? dom.nextSibling : dom.firstChild
while (dom) {
walk(dom, fn)
dom = dom.nextSibling
}
}
function mkdom(tmpl) {
var tag_name = tmpl.trim().slice(1, 3).toLowerCase(),
root_tag = /td|th/.test(tag_name) ? 'tr' : tag_name == 'tr' ? 'tbody' : 'div'
el = doc.createElement(root_tag)
el.innerHTML = tmpl
return el
}
function setEventHandler(name, handler, dom, instance) {
dom[name] = function(e) {
// cross browser event fix
e = e || window.event
e.which = e.which || e.charCode || e.keyCode
e.target = e.target || e.srcElement
e.currentTarget = dom
// currently looped item
e.item = instance.__item || instance
// prevent default behaviour (by default)
if (handler.call(instance, e) !== true) {
e.preventDefault && e.preventDefault()
e.returnValue = false
}
instance.update()
}
}
function update(expressions, instance) {
// allow recalculation of context data
instance.trigger('update')
each(expressions, function(expr) {
var tag = expr.tag,
dom = expr.dom
function remAttr(name) {
dom.removeAttribute(name)
}
// loops first: TODO remove from expressions arr
if (expr.loop) {
remAttr('each')
return loop(expr, instance)
}
// custom tag
if (tag) return tag.update ? tag.update() :
expr.tag = createTag({ tmpl: tag[0], fn: tag[1], root: dom, parent: instance })
var attr_name = expr.attr,
value = tmpl(expr.expr, instance)
if (value == null) value = ''
// no change
if (expr.value === value) return
expr.value = value
// text node
if (!attr_name) return dom.nodeValue = value
// attribute
if (!value && expr.bool || /obj|func/.test(typeof value)) remAttr(attr_name)
// event handler
if (typeof value == 'function') {
setEventHandler(attr_name, value, dom, instance)
// show / hide / if
} else if (/^(show|hide|if)$/.test(attr_name)) {
remAttr(attr_name)
if (attr_name == 'hide') value = !value
dom.style.display = value ? '' : 'none'
// normal attribute
} else {
if (expr.bool) {
dom[attr_name] = value
if (!value) return
value = attr_name
}
dom.setAttribute(attr_name, value)
}
})
instance.trigger('updated')
}
function parse(root) {
var named_elements = {},
expressions = []
function addExpr(dom, value, data) {
if (value ? value.indexOf('{') >= 0 : data) {
var expr = { dom: dom, expr: value }
expressions.push(extend(expr, data || {}))
}
}
walk(root, function(dom) {
var type = dom.nodeType,
value = dom.nodeValue
// text node
if (type == 3 && dom.parentNode.tagName != 'STYLE') {
addExpr(dom, value)
// element
} else if (type == 1) {
// loop?
value = dom.getAttribute('each')
if (value) {
addExpr(dom, value, { loop: 1 })
return false
}
// custom tag?
var tag = tag_impl[dom.tagName.toLowerCase()]
// attributes
each(dom.attributes, function(attr) {
var name = attr.name,
value = attr.value
// named elements
if (/^(name|id)$/.test(name)) named_elements[value] = dom
// expressions
if (!tag) {
var bool = name.split('__')[1]
addExpr(dom, value, { attr: bool || name, bool: bool })
if (bool) {
dom.removeAttribute(name)
return false
}
}
})
if (tag) addExpr(dom, 0, { tag: tag })
}
})
return { expr: expressions, elem: named_elements }
}
function moveChildren(src, dst) {
while (src.firstChild) {
dst.appendChild(src.removeChild(src.firstChild))
}
return dst
}
// create new custom tag (component)
function createTag(conf) {
var opts = conf.opts || {},
dom = mkdom(conf.tmpl),
mountNode = conf.root,
parent = conf.parent,
ast = parse(dom),
tag = { root: mountNode, opts: opts, parent: parent, __item: conf.item },
attributes = {}
// named elements
extend(tag, ast.elem)
// attributes
each(mountNode.attributes, function(attr) {
attributes[attr.name] = attr.value
})
function updateOpts() {
Object.keys(attributes).map(function(name) {
var val = opts[name] = tmpl(attributes[name], parent || tag)
if (typeof val == 'object') mountNode.removeAttribute(name)
})
}
updateOpts()
if (!tag.on) {
riot.observable(tag)
delete tag.off // off method not needed
}
if (conf.fn) conf.fn.call(tag, opts)
tag.update = function(data, _system) {
/*
If loop is defined on the root of the HTML template
the original parent is a temporary <div/> by mkdom()
*/
if (parent && dom && !dom.firstChild) {
mountNode = parent.root
dom = null
}
if (_system || doc.body.contains(mountNode) || doc.querySelectorAll("[data-riot-tag='" + mountNode.nodeName + "']").length > 0) {
extend(tag, data)
extend(tag, tag.__item)
if (opts.transclude) {
// If transclude is enabled collect all the child elements of root node on a temporary node and save for later use
opts.include = moveChildren(mountNode, doc.createElement('div'))
}
updateOpts()
update(ast.expr, tag)
// update parent
!_system && tag.__item && parent.update()
return true
} else {
tag.trigger('unmount')
}
}
tag.update(0, true)
if (opts.replacetag) {
dom.firstChild.setAttribute("data-riot-tag", mountNode.nodeName);
if ((mountNode.nodeName == 'INCLUDE') && (parent.opts.include)) {
//if the parent has a stored include el and the current root node is INCLUDE
moveChildren(parent.opts.include, dom.firstChild)
mountNode = mountNode.parentNode.replaceChild(dom.firstChild, mountNode)
} else {
mountNode = mountNode.parentNode.replaceChild(dom.firstChild, mountNode)
}
}
else {
// append to root
while (dom.firstChild) {
if (conf.before) mountNode.insertBefore(dom.firstChild, conf.before)
else mountNode.appendChild(dom.firstChild)
}
}
tag.trigger('mount')
all_tags.push(tag)
return tag
}
function loop(expr, instance) {
// initialize once
if (expr.done) return
expr.done = true
var dom = expr.dom,
prev = dom.previousSibling,
root = dom.parentNode,
template = dom.outerHTML,
val = expr.expr,
els = val.split(/\s+in\s+/),
rendered = [],
checksum,
keys
if (els[1]) {
val = '{ ' + els[1]
keys = els[0].slice(1).trim().split(/,\s*/)
}
// clean template code
instance.one('mount', function() {
var p = dom.parentNode
if (p) {
root = p
root.removeChild(dom)
}
})
function startPos() {
return Array.prototype.indexOf.call(root.childNodes, prev) + 1
}
instance.on('updated', function() {
var items = tmpl(val, instance),
is_array = Array.isArray(items)
if (is_array) items = items.slice(0)
else {
if (!items) return // some IE8 issue
// detect Object changes
var testsum = JSON.stringify(items)
if (testsum == checksum) return
checksum = testsum
items = Object.keys(items).map(function(key, i) {
var item = {}
item[keys[0]] = key
item[keys[1]] = items[key]
return item
})
}
// remove redundant
diff(rendered, items).map(function(item) {
var pos = rendered.indexOf(item)
root.removeChild(root.childNodes[startPos() + pos])
rendered.splice(pos, 1)
})
// add new
diff(items, rendered).map(function(item, i) {
var pos = items.indexOf(item)
// string array
if (keys && !checksum) {
var obj = {}
obj[keys[0]] = item
obj[keys[1]] = pos
item = obj
}
var tag = createTag({
before: root.childNodes[startPos() + pos],
parent: instance,
tmpl: template,
item: item,
root: root
})
instance.on('update', function() {
tag.update(0, true)
})
})
// assign rendered
rendered = items
})
}
riot.tag = function(name, tmpl, fn) {
fn = fn || noop,
tag_impl[name] = [tmpl, fn]
}
riot.mountTo = function(node, tagName, opts) {
var tag = tag_impl[tagName]
return tag && createTag({ tmpl: tag[0], fn: tag[1], root: node, opts: opts })
}
riot.mount = function(selector, opts) {
if (selector == '*') selector = Object.keys(tag_impl).join(', ')
var instances = []
each(doc.querySelectorAll(selector), function(node) {
if (node.riot) return
var tagName = node.tagName.toLowerCase(),
instance = riot.mountTo(node, tagName, opts)
if (instance) {
instances.push(instance)
node.riot = 1
}
})
return instances
}
// update everything
riot.update = function() {
return all_tags = all_tags.filter(function(tag) {
return !!tag.update()
})
}
riot.tag('include', '<span></span>', function(opts) {
opts.replacetag = true
});
})(riot, this.top)
// support CommonJS
if (typeof exports === 'object')
module.exports = riot
// support AMD
else if (typeof define === 'function' && define.amd)
define(function() { return riot })
// support browser
else
this.riot = riot
})();
(function(e){var t=("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,"+"defaultchecked,defaultmuted,defaultselected,defer,disabled,draggable,enabled,formnovalidate,hidden,"+"indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,"+"pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,spellcheck,translate,truespeed,"+"typemustmatch,visible").split(",");var r="area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr".split(",");var n={jade:v};var i={coffeescript:p,none:g,cs:p,es6:d,typescript:m};var o=/^<([\w\-]+)>([^\x00]*[\w\/]>$)?([^\x00]*?)^<\/\1>/gim,a=/<script(\s+type=['"]?([^>'"]+)['"]?)?>([^\x00]*?)<\/script>/gm,c=/<!--.*?-->/g,u=/<([\w\-]+)([^\/]*)\/\s*>/g,f=/^\s*\/\/.*$/gm,s=/\/\*[^\x00]*?\*\//gm;function l(e,n,i){e=e.replace(/\s+/g," ");e=e.trim().replace(c,"");e=e.replace(/=(\{[^\}]+\})([\s\>])/g,'="$1"$2');e=e.replace(/([\w\-]+)=["'](\{[^\}]+\})["']/g,function(e,r,n){if(t.indexOf(r.toLowerCase())>=0)r="__"+r;return r+'="'+n+'"'});if(n.expr){e=e.replace(/\{\s*([^\}]+)\s*\}/g,function(e,t){return"{"+w(t,n,i).trim()+"}"})}e=e.replace(u,function(e,t,n){var i="<"+t+(n?" "+n.trim():"")+">";if(r.indexOf(t.toLowerCase())==-1)i+="</"+t+">";return i});e=e.replace(/'/g,"\\'");e=e.replace(/\\[{}]/g,"\\$&");if(n.compact)e=e.replace(/> </g,"><");return e}function p(e){return require("coffee-script").compile(e,{bare:true})}function d(e){return require("6to5").transform(e).code}function m(e){return require("typescript-simple")(e)}function g(e){return e}function v(e){return require("jade").render(e,{pretty:true})}function h(e){e=e.replace(f,"").replace(s,"");var t=e.split("\n"),r="";t.forEach(function(e,n){var i=e.trim();if(i[0]!="}"&&i.indexOf("(")>0&&i.slice(-1)=="{"&&i.indexOf("function")==-1){var o=/(\s+)([\w]+)\s*\(([\w,\s]*)\)\s*\{/.exec(e);if(o&&!/^(if|while|switch|for)$/.test(o[2])){t[n]=o[1]+"this."+o[2]+" = function("+o[3]+") {";r=o[1]}}if(e.slice(0,r.length+1)==r+"}"){t[n]+=".bind(this);";r=""}});return t.join("\n")}function w(e,t,r){var n=t.parser||(r?i[r]:h);if(!n)throw new Error('Parser not found "'+r+'"');return n(e,t)}function y(e,t){var r=n[e];if(!r)throw new Error('Template parser not found "'+e+'"');return r(t)}function x(e,t){t=t||{};if(t.template)e=y(t.template,e);return e.replace(o,function(e,r,n,i){n=n||"";var o=t.type;if(!i.trim()){n=n.replace(a,function(e,t,r,n){if(r)o=r.replace("text/","");i=n;return""})}return"riot.tag('"+r+"', '"+l(n,t,o)+"', function(opts) {"+w(i,t,o)+"\n});"})}if(e){return module.exports={html:l,compile:x}}var b=document,q,E;function k(e,t){var r=new XMLHttpRequest;r.onreadystatechange=function(){if(r.readyState==4&&r.status==200)t(r.responseText)};r.open("GET",e,true);r.send("")}function T(e){var t=/[ \t]+/.exec(e);if(t)e=e.replace(new RegExp("^"+t[0],"gm"),"");return e}function $(e){var t=b.createElement("script"),r=b.documentElement;t.text=x(e);r.appendChild(t);r.removeChild(t)}function C(e){var t=b.querySelectorAll('script[type="riot/tag"]');[].map.call(t,function(r,n){var i=r.getAttribute("src");function o(i){r.parentNode.removeChild(r);$(i);if(n+1==t.length){q.trigger("ready");E=true;e&&e()}}return i?k(i,o):o(T(r.innerHTML))})}function L(e,t){if(typeof e=="string"){var r=T(x(e));if(!t)$(r);return r}if(typeof e!="function")e=undefined;if(E)return e&&e();if(q){e&&q.on("ready",e)}else{q=riot.observable();C(e)}}var O=riot.mount,j=riot.mountTo;riot.mount=function(e,t){L(function(){O(e,t)})};riot.mountTo=function(e,t,r){L(function(){j(e,t,r)})};riot._compile=function(e){return L(e,true)}})(!this.top);
<alert>
<div class="alert alert-{category}" role="alert">...<include></div>
opts.replacetag = true
opts.transclude = true
this.category = opts.category || "info"
</alert>
<alerts>
<ul><li each={ items }><alert category={ category }> { player } </alert></li></ul>
this.items = opts.items
</alerts>