Skip to content

Instantly share code, notes, and snippets.

@Satyam
Created July 22, 2014 21:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Satyam/957d42729832c1a0816e to your computer and use it in GitHub Desktop.
Save Satyam/957d42729832c1a0816e to your computer and use it in GitHub Desktop.
YUI App todo demo on its way to Mithril with htmlparsing of HTML templates
<!doctype html>
<html>
<head>
<title>Virtual DOM with node references</title>
<script src="http://cdnjs.cloudflare.com/ajax/libs/mithril/0.1.18/mithril.min.js"></script>
<script src="../../node_modules/htmlparser-jresig/htmlparser-lib/htmlparser.js"></script>
<!-- This is the main container and "shell" for the todo app. -->
<script type="text/x-template" id="todo-app-template">
<div id="todo-app">
<label class="todo-label" for="new-todo">What do you want to do today?</label>
<input type="text" id="new-todo" class="todo-input"
placeholder="buy milk">
<ul id="todo-list"></ul>
<div id="todo-stats"></div>
</div>
</script>
<!-- This template HTML will be used to render each todo item. -->
<script type="text/x-template" id="todo-item-template">
<div class="todo-view">
<input type="checkbox" class="todo-checkbox" {checked}>
<span class="todo-content" tabindex="0">{text}</span>
</div>
<div class="todo-edit">
<input type="text" class="todo-input" value="{text}">
</div>
<a href="#" class="todo-remove" title="Remove this task">
<span class="todo-remove-icon"></span>
</a>
</script>
<!-- This template HTML will be used to render the statistics at the bottom
of the todo list. -->
<script type="text/x-template" id="todo-stats-template">
<span class="todo-count">
<span class="todo-remaining">{numRemaining}</span>
<span class="todo-remaining-label">{remainingLabel}</span> left.
</span>
<a href="#" class="todo-clear">
Clear <span class="todo-done">{numDone}</span>
completed <span class="todo-done-label">{doneLabel}</span>
</a>
</script>
<style>
#todo-app {
margin: 1em;
text-align: center;
}
#todo-list,
#todo-stats {
margin: 1em auto;
text-align: left;
width: 450px;
}
#todo-list {
list-style: none;
padding: 0;
}
#todo-stats,
.todo-clear { color: #777; }
.todo-clear { float: right; }
.todo-done .todo-content {
color: #666;
text-decoration: line-through;
}
.todo-edit,
.editing .todo-view { display: none; }
.editing .todo-edit { display: block; }
.todo-input {
display: block;
font-family: Helvetica, sans-serif;
font-size: 20px;
line-height: normal;
margin: 5px auto 0;
padding: 6px;
width: 420px;
}
.todo-item {
border-bottom: 1px dotted #cfcfcf;
font-size: 20px;
padding: 6px;
position: relative;
}
.todo-label {
color: #444;
font-size: 20px;
font-weight: bold;
text-align: center;
}
.todo-remaining {
color: #333;
font-weight: bold;
}
.todo-remove {
position: absolute;
right: 0;
top: 12px;
}
.todo-remove-icon {
/*
Delete icon courtesy of The Noun Project:
http://thenounproject.com/noun/delete/
*/
background: url(../assets/app/remove.png) no-repeat;
display: block;
height: 16px;
opacity: 0.6;
visibility: hidden;
width: 23px;
}
.todo-remove:hover .todo-remove-icon { opacity: 1.0; }
.todo-hover .todo-remove-icon,
.todo-remove:focus .todo-remove-icon { visibility: visible; }
.editing .todo-remove-icon { visibility: hidden; }
</style>
</head>
<body>
<script>
var SUBREGEX = /\{\s*([^|}]+?)\s*(?:\|([^}]*))?\s*\}/g,
sub = function(s, o) {
return s.replace ? s.replace(SUBREGEX, function (match, key) {
return (o[key] === undefined) ? match : o[key];
}) : s;
};
var HTMLparse = function (html) {
var virtualDom = [];
var nodeStack = [virtualDom];
var getAttrs = function (attrs) {
var a = {};
attrs.forEach(function (attr) {
a[attr.name] = attr.value;
});
return a;
};
HTMLParser(html, {
start: function(tag, attrs, unary) {
//console.log('start', tag, attrs, unary);
var vNode = {
tag: tag,
attrs: getAttrs(attrs)
};
nodeStack[0].push(vNode);
if (!unary) {
vNode.children = [];
nodeStack.unshift(vNode.children);
}
},
end: function(tag) {
//console.log('end', tag);
nodeStack.shift();
},
chars: function(text) {
text = text.trim();
if (text.length) {
//console.log('chars', '|' + text + '|');
nodeStack[0].push(text);
}
},
comment: function(text) {
//console.log('comment',text);
}
});
return virtualDom;
};
var TodoApp = {
controller: function () {
},
view: function (ctrl) {
return HTMLparse(document.getElementById('todo-app-template').innerHTML);
}
};
var TodoItem = {
controller: function () {
},
view: function (ctrl) {
}
};
m.route(document.body, '/', {
'/':TodoApp,
'/:item': TodoItem
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment