Commit 910cf9ad authored by Addy Osmani's avatar Addy Osmani

Removing o_O implementation. Has not been updated in forever

parent 6d5c1f0f
...@@ -125,9 +125,6 @@ ...@@ -125,9 +125,6 @@
<li class="routing labs"> <li class="routing labs">
<a href="labs/architecture-examples/rappidjs/" data-source="http://www.rappidjs.com" data-content="rAppid.js is a declarative JavaScript framework for rapid web application development. It supports dependency loading, Model-View binding, View-Model binding, dependency injection and i18n.">rAppid.js</a> <a href="labs/architecture-examples/rappidjs/" data-source="http://www.rappidjs.com" data-content="rAppid.js is a declarative JavaScript framework for rapid web application development. It supports dependency loading, Model-View binding, View-Model binding, dependency injection and i18n.">rAppid.js</a>
</li> </li>
<li class="routing labs">
<a href="labs/architecture-examples/o_O/" data-source="http://weepy.github.com/o_O/" data-content="o_O: HTML binding &lt;br> - Elegantly binds objects to HTML&lt;br>- Proxies through jQuery, Ender, etc&lt;br>- Automatic dependency resolution&lt;br>- Plays well with others">Funnyface.js</a>
</li>
<li class="routing labs"> <li class="routing labs">
<a href="labs/architecture-examples/knockoutjs_classBindingProvider/" data-source="https://github.com/rniemeyer/knockout-classBindingProvider" data-content="This project is an adaptation of /architecture-examples/knockoutjs with Ryan Niemeyer's Class Binding Provider.">Knockout +<br> ClassBinding</a> <a href="labs/architecture-examples/knockoutjs_classBindingProvider/" data-source="https://github.com/rniemeyer/knockout-classBindingProvider" data-content="This project is an adaptation of /architecture-examples/knockoutjs with Ryan Niemeyer's Class Binding Provider.">Knockout +<br> ClassBinding</a>
</li> </li>
......
{
"name": "todomvc-o_O",
"version": "0.0.0",
"dependencies": {
"todomvc-common": "~0.1.6",
"jquery": "~1.8.0"
}
}
(function () {
'use strict';
// Underscore's Template Module
// Courtesy of underscorejs.org
var _ = (function (_) {
_.defaults = function (object) {
if (!object) {
return object;
}
for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
var iterable = arguments[argsIndex];
if (iterable) {
for (var key in iterable) {
if (object[key] == null) {
object[key] = iterable[key];
}
}
}
}
return object;
}
// By default, Underscore uses ERB-style template delimiters, change the
// following template settings to use alternative delimiters.
_.templateSettings = {
evaluate : /<%([\s\S]+?)%>/g,
interpolate : /<%=([\s\S]+?)%>/g,
escape : /<%-([\s\S]+?)%>/g
};
// When customizing `templateSettings`, if you don't want to define an
// interpolation, evaluation or escaping regex, we need one that is
// guaranteed not to match.
var noMatch = /(.)^/;
// Certain characters need to be escaped so that they can be put into a
// string literal.
var escapes = {
"'": "'",
'\\': '\\',
'\r': 'r',
'\n': 'n',
'\t': 't',
'\u2028': 'u2028',
'\u2029': 'u2029'
};
var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
// JavaScript micro-templating, similar to John Resig's implementation.
// Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code.
_.template = function(text, data, settings) {
var render;
settings = _.defaults({}, settings, _.templateSettings);
// Combine delimiters into one regular expression via alternation.
var matcher = new RegExp([
(settings.escape || noMatch).source,
(settings.interpolate || noMatch).source,
(settings.evaluate || noMatch).source
].join('|') + '|$', 'g');
// Compile the template source, escaping string literals appropriately.
var index = 0;
var source = "__p+='";
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
source += text.slice(index, offset)
.replace(escaper, function(match) { return '\\' + escapes[match]; });
if (escape) {
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
}
if (interpolate) {
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
}
if (evaluate) {
source += "';\n" + evaluate + "\n__p+='";
}
index = offset + match.length;
return match;
});
source += "';\n";
// If a variable is not specified, place data values in local scope.
if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
source = "var __t,__p='',__j=Array.prototype.join," +
"print=function(){__p+=__j.call(arguments,'');};\n" +
source + "return __p;\n";
try {
render = new Function(settings.variable || 'obj', '_', source);
} catch (e) {
e.source = source;
throw e;
}
if (data) return render(data, _);
var template = function(data) {
return render.call(this, data, _);
};
// Provide the compiled function source as a convenience for precompilation.
template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
return template;
};
return _;
})({});
if (location.hostname === 'todomvc.com') {
window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
}
function redirect() {
if (location.hostname === 'tastejs.github.io') {
location.href = location.href.replace('tastejs.github.io/todomvc', 'todomvc.com');
}
}
function findRoot() {
var base;
[/labs/, /\w*-examples/].forEach(function (href) {
var match = location.href.match(href);
if (!base && match) {
base = location.href.indexOf(match);
}
});
return location.href.substr(0, base);
}
function getFile(file, callback) {
if (!location.host) {
return console.info('Miss the info bar? Run TodoMVC from a server to avoid a cross-origin error.');
}
var xhr = new XMLHttpRequest();
xhr.open('GET', findRoot() + file, true);
xhr.send();
xhr.onload = function () {
if (xhr.status === 200 && callback) {
callback(xhr.responseText);
}
};
}
function Learn(learnJSON, config) {
if (!(this instanceof Learn)) {
return new Learn(learnJSON, config);
}
var template, framework;
if (typeof learnJSON !== 'object') {
try {
learnJSON = JSON.parse(learnJSON);
} catch (e) {
return;
}
}
if (config) {
template = config.template;
framework = config.framework;
}
if (!template && learnJSON.templates) {
template = learnJSON.templates.todomvc;
}
if (!framework && document.querySelector('[data-framework]')) {
framework = document.querySelector('[data-framework]').getAttribute('data-framework');
}
if (template && learnJSON[framework]) {
this.frameworkJSON = learnJSON[framework];
this.template = template;
this.append();
}
}
Learn.prototype.append = function () {
var aside = document.createElement('aside');
aside.innerHTML = _.template(this.template, this.frameworkJSON);
aside.className = 'learn';
// Localize demo links
var demoLinks = aside.querySelectorAll('.demo-link');
Array.prototype.forEach.call(demoLinks, function (demoLink) {
demoLink.setAttribute('href', findRoot() + demoLink.getAttribute('href'));
});
document.body.className = (document.body.className + ' learn-bar').trim();
document.body.insertAdjacentHTML('afterBegin', aside.outerHTML);
};
redirect();
getFile('learn.json', Learn);
})();
<!doctype html>
<html lang="en" data-framework="funnyfacejs">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>o_O • TodoMVC</title>
<link rel="stylesheet" href="bower_components/todomvc-common/base.css">
</head>
<body>
<section id="todoapp">
<header id="header">
<h1>todos</h1>
<input id="new-todo" data-bind="value: current; enterKey: add" placeholder="What needs to be done?" autofocus>
</header>
<section id="main" data-bind="visible: todos.count">
<div>
<input id="toggle-all" type="checkbox" data-bind="value: allCompleted;">
<label for="toggle-all">Mark all as complete</label>
</div>
<ul id="todo-list" data-bind="foreach: todos">
<li data-bind="class: klass; visible">
<div class="view">
<input class="toggle" type="checkbox" data-bind="value: completed">
<label data-bind="text: title; dblclick: startEditing"></label>
<button class="destroy" data-bind="click: remove"></button>
</div>
<input class="edit" data-bind="value: title; enterKey: stopEditing; blur: stopEditing">
</li>
</ul>
</section>
<footer id="footer" data-bind="visible: todos.count">
<span id="todo-count">
<strong data-bind="text: remainingCount"></strong>
<span class="word" data-bind="text: pluralize('item', remainingCount())"></span> left
</span>
<ul id="filters" >
<li><a href="#/">All</a></li>
<li><a href="#/active">Active</a></li>
<li><a href="#/completed">Completed</a></li>
</ul>
<button id="clear-completed" data-bind="click: removeCompleted; visible: completedCount">
Clear completed (<span data-bind='text: completedCount'></span>)
</button>
</footer>
</section>
<footer id="info">
<p>Double-click to edit a todo</p>
<p>Created by <a href="http://weepy.github.com">weepy (Jonah Fox)</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>
<script src="bower_components/todomvc-common/base.js"></script>
<script src="bower_components/jquery/jquery.js"></script>
<script src="js/lib/o_O.js" ></script>
<script src="js/lib/o_O.router.js"></script>
<script src="js/app.js"></script>
</body>
</html>
/*jshint camelcase:false newcap:false*/
/*global $ o_O todoapp */
(function (window) {
'use strict';
// represents a single todo item
var Todo = o_O.model.extend({
title: '',
completed: false
}, {
initialize: function () {
this.editing = o_O(false);
},
startEditing: function () {
this.editing(true);
var self = this;
setTimeout(function () {
$(self.el).parent().find('input.edit').focus();
}, 0);
},
stopEditing: function () {
var text = $.trim(this.title());
if (text) {
this.title(text);
} else {
this.remove();
}
this.editing(false);
},
remove: function () {
todoapp.todos.remove(this);
},
visible: function () {
var filter = todoapp.filter(),
completed = this.completed();
return filter === '' ||
(filter === 'completed' && completed) ||
(filter === 'active' && !completed);
},
klass: function () {
if (this.editing()) {
return 'editing';
}
if (this.completed()) {
return 'completed';
} else {
return '';
}
}
}
);
// main application
var TodoApp = o_O.model.extend({
current: '',
completedCount: 0,
filter: ''
}, {
initialize: function () {
var self = this;
self.todos = o_O.array(this.todos());
this.todos.on('set:completed set:title add remove', function () {
var completed = self.todos.filter(function (todo) {
return todo.completed();
});
self.completedCount(completed.length);
self.persist();
});
this.remainingCount = o_O(function () {
return self.todos.count() - self.completedCount();
});
// writeable computed observable
// handles marking all complete/incomplete
// or retrieving if this is true
this.allCompleted = o_O(function (v) {
if (!arguments.length) {
return !self.remainingCount();
}
self.todos.each(function (todo) {
todo.completed(v);
});
return v;
});
},
add: function () {
var text = $.trim(this.current());
if (text) {
this.todos.unshift(Todo({
title: text
}));
this.current('');
}
},
removeCompleted: function () {
this.todos.remove(function (todo) {
return todo.completed();
});
return false;
},
persist: function () {
localStorage['todos-o_O'] = JSON.stringify(this.todos.toJSON());
},
pluralize: function (word, count) {
return word + (count === 1 ? '' : 's');
}
});
function main() {
// load todos
var i, l,
todos = [];
try {
todos = JSON.parse(localStorage['todos-o_O']);
} catch (e) {}
// create models
for (i = 0, l = todos.length; i < l; i++) {
todos[i] = Todo.create(todos[i]);
}
// create app
window.todoapp = TodoApp({
todos: todos
});
// bind to DOM element
todoapp.bind('#todoapp');
// setup Routing
o_O.router()
.add('*filter', function (filter) {
todoapp.filter(filter);
$('#filters a')
.removeClass('selected')
.filter('[href="#/' + filter + '"]')
.addClass('selected');
})
.start();
}
// a custom binding to handle the enter key
o_O.bindings.enterKey = function (func, $el) {
var ENTER_KEY = 13;
var context = this;
$el.keyup(function (e) {
if (e.which === ENTER_KEY) {
func.call(context);
}
});
};
o_O.bindingTypes.enterKey = 'outbound';
// kick it off
main();
})(window);
!function(){function e(a,b){function c(b){arguments.length?(c.old_value=c.value,c.value=d?b:a(b),c.emitset()):(j.checking&&j.emit("get",c),d||(c.value=a()));return c.value}var d="function"!=typeof a;d?c.value=a:(c.dependencies=[],s(j(c),function(a){c.dependencies.push(a);a.change(function(){c.emitset()})}));h(c,n,v);b&&(c.type=b);return c}function j(a){function b(b){var f;a:if(f=c,f.indexOf)f=f.indexOf(b,void 0);else{for(var i=0,e=f.length;i<e;i++)if(f[i]===b){f=i;break a}f=-1}0>f&&b!=a&&c.push(b)}
var c=[];j.checking=!0;j.on("get",b);j.lastResult=a();j.off("get",b);j.checking=!1;return c}function w(a){if(!a)return[];var a=o(a).split(";"),b=[],c,d,f;for(c=0;c<a.length;c++)if(f=o(a[c])){f=o(f).split(":");d=o;for(var e=[],k=0;k<f.length;k++)e[k]=d(f[k],k);d=e;f=o(d.shift());d=o(d.join(":"))||f;b.push([f,d])}return b}function p(a){var b=a.data("o_O:template");null==b&&(b=a.html(),a.html(""),a.data("o_O:template",b));return b}function x(a,b){return function(){return a.apply(b,arguments)}}function g(a,
b){if(!(this instanceof g))return new g(a,b);a=a||{};this.properties=[];for(var c in a)g.addProperty(this,c,a[c]),g.observeProperty(this,c);var d=this.constructor.defaults;for(c in d)c in a||(g.addProperty(this,c,d[c]),g.observeProperty(this,c));b&&h(this,b);this.initialize.apply(this,arguments)}function l(a){if(!(this instanceof l))return new l(a);var b=this;this.items=[];this.count=e(0);this.length=0;this.count.change(function(a){b.length=a});if(a)for(var c=0;c<a.length;c++)this.push(a[c]);this.initialize()}
function h(a){for(var b=t.call(arguments,1),c=0;c<b.length;c++){var d=b[c],f;for(f in d)a[f]=d[f]}return a}function s(a,b){if(a.forEach)return a.forEach(b);for(var c=0,d=a.length;c<d;c++)c in a&&b.call(null,a[c],c,a)}function o(a){return a.replace(/^\s+|\s+$/g,"")}function u(){}function r(a,b,c){var d=function(b,c){if(this instanceof d)a.apply(this,arguments);else return new d(b,c)};b&&b.hasOwnProperty("constructor")&&(d=b.constructor);h(d,a);u.prototype=a.prototype;d.prototype=new u;b&&h(d.prototype,
b);c&&h(d,c);d.prototype.constructor=d;d.__super__=a.prototype;return d}var t=Array.prototype.slice,n={on:function(a,b,c){for(var d,a=a.split(/\s+/),f=this._callbacks||(this._callbacks={});d=a.shift();){d=f[d]||(f[d]={});var e=d.tail||(d.tail=d.next={});e.callback=b;e.context=c;d.tail=e.next={}}return this},off:function(a,b,c){var d,f,e;if(a){if(f=this._callbacks)for(a=a.split(/\s+/);d=a.shift();)if(e=f[d],delete f[d],b&&e)for(;(e=e.next)&&e.next;)if(!(e.callback===b&&(!c||e.context===c)))this.on(d,
e.callback,e.context)}else delete this._callbacks;return this},emit:function(a){var b,c,d,e;if(!(d=this._callbacks))return this;e=d.all;for((a=a.split(/\s+/)).push(null);b=a.shift();)e&&a.push({next:e.next,tail:e.tail,event:b}),(c=d[b])&&a.push({next:c.next,tail:c.tail});for(e=t.call(arguments,1);c=a.pop();){b=c.tail;for(d=c.event?[c.event].concat(e):e;(c=c.next)!==b;)c.callback.apply(c.context||this,d)}return this}},v={incr:function(a){return this(this.value+(a||1))},scale:function(a){return this(this.value*
(a||1))},toggle:function(){return this(!this.value)},change:function(a){a?this.on("set",a):this.emit("set",this(),this.old_val);return this},mirror:function(a,b){a.change(function(a){a!=this.value&&this(a)});a.change();b&&a.mirror(this);return this},toString:function(){return"<"+(this.type?this.type+":":"")+this.value+">"},bind:function(a){e.bind(this,a);return this},emitset:function(){this._emitting||(this._emitting=!0,this.emit("set",this(),this.old_value),delete this._emitting)},constructor:e};
h(j,n);e.dependencies=j;e.expression=function(a){e.expression.last=a;return new Function("o_O","with(this) { return ("+a+"); } ")};e.nextFrame=function(){function a(){for(;b.length;)b.shift()();c=null}var b=[],c,d=this,e=d.requestAnimationFrame||d.webkitRequestAnimationFrame||d.mozRequestAnimationFrame||d.oRequestAnimationFrame||d.msRequestAnimationFrame||function(a){d.setTimeout(a,1E3/60)};return function(d){b.push(d);c=c||e(a)}}();e.bindRuleToElement=function(a,b,c,d){function f(){m=i.call(c,e.helpers);
m instanceof String&&(m=m.toString())}var i=e.expression(b),k=e.createBinding(a),g=$(d),m;if("outbound"==k.type)f(),k.call(c,m,g);else{a=j(f);"function"==typeof m&&"twoway"!=k.type&&(i=e.expression("("+b+")()"),a=j(f));k.call(c,m,g);var h;s(a,function(a){a.change(function(){f();if(!h){h=true;e.nextFrame(function(){k.call(c,m,g);h=false})}})})}};e.bind=function(a,b,c){b=$(b);c||(a.el=b[0]);for(var c=!0,d=w(b.attr(e.bindingAttribute)),f=0;f<d.length;f++){var i=d[f][0],g=d[f][1];if("with"==i||"foreach"==
i)c=!1;'"class"'==i&&(i="class");e.bindRuleToElement(i,g,a,b)}e.removeBindingAttribute&&b.attr(e.bindingAttribute,null);c&&b.children().each(function(b,c){e.bind(a,c,true)})};e.helpers={value:function(a){return function(b){return a.call(this,$(b.currentTarget).val(),b)}},position:function(a){return function(b){var c=$(b.currentTarget).offset();a.call(this,b.pageX-c.left,b.pageY-c.top,b)}}};e.bindings={visible:function(a,b){a?b.show():b.hide()},"if":function(a,b){var c=p(b);b.html(a?c:"")},unless:function(a,
b){return e.bindings["if"](!a,b)},"with":function(a,b){var c=p(b);b.html(a?c:"");a&&e.bind(a,b)},options:function(a,b){var c=a instanceof Array;$.each(a,function(a,e){var i=c?e:a;b.append($("<option>").attr("value",e).html(i))})},foreach:function(a,b){function c(a){$(d).each(function(c,d){var f=$(d);f.appendTo(b);e.bind(a,f)})}var d=p(b),f=a.renderItem||c;b.html("");a.forEach(function(c,d){f.call(a,c,b,d)});a.onbind&&a.onbind(b)},log:function(a,b){console.log("o_O",a,b,this)}};e.bindings.call=function(a,
b){a.call(this,b)};e.bindings.call.type="outbound";e.bindings.value=function(a,b){b.change(function(b){var d="checkbox"==$(this).attr("type")?!!$(this).attr("checked"):$(this).val();a(d,b)});a.constructor==e&&(a.on("set",function(a){"checkbox"==b.attr("type")?b.attr("checked",a?"checked":null):b.val(a)}),a.change())};e.bindings.value.type="twoway";e.bindingTypes={focus:"outbound",blur:"outbound",change:"outbound",submit:"outbound",keypress:"outbound",keydown:"outbound",keyup:"outbound",click:"outbound",
mouseover:"outbound",mouseout:"outbound",mousedown:"outbound",mousemove:"outbound",mouseup:"outbound",dblclick:"outbound",load:"outbound"};e.createBinding=function(a){var b;b=e.bindings[a]?e.bindings[a]:a in $.prototype?function(b,d){"function"==typeof b&&(b=x(b,this));return d[a](b)}:function(b,d){return d.attr(a,b)};b.type=b.type||e.bindingTypes[a]||"inbound";return b};h(g,n,{observeProperty:function(a,b){a[b].on("set",function(c,d){a.emit("set:"+b,a,c,d);if(c!==d){var e={},g={};e[b]=c;g[b]=d;a.emit("update",
a,e,g)}})},addProperty:function(a,b,c){a[b]=e(c);a.properties.push(b)},defaults:{},types:{},extend:function(a,b,c){a=a||{};b=r(this,b,c);b.defaults=a;b.extend=this.extend;a.type&&(g.types[a.type]=b);return b},create:function(a){var a=a||{},b=this==g?g.types[a.type]:this;if(!b)throw Error("no such Model with type: "+a.type);return new b(a)}});h(g.prototype,n,{toString:function(){return"#<"+(this.type?this.type():"model")+">"},bind:function(a){e.bind(this,a);return this},initialize:function(){},valid:function(){return!0},
update:function(a){var b={},c=this.constructor.defaults,d;for(d in a)d in c&&(b[d]=this[d].value,this[d].value=a[d]);if(this.valid()){for(d in b)this[d].value=b[d],this[d](a[d]);this.emit("update",this,a,b);return b}for(d in b)this[d](b[d]);return!1},destroy:function(){this.emit("destroy",this)},toJSON:function(){for(var a={},b=0;b<this.properties.length;b++){var c=this.properties[b];a[c]=this[c]()}return a},clone:function(){return g.create(this.toJSON())}});e.model=g;h(l,{add:function(a,b,c){a.count.incr();
b.on&&b.emit?(b.on("all",a._onevent,a),b.emit("add",b,a,c)):a.emit("add",b,a,c);return a.items.length},remove:function(a,b,c){a.count.incr(-1);b.off&&b.emit?(b.emit("remove",b,a,c),b.off("all",a._onevent,a)):a.emit("remove",b,c);return b},extend:function(a,b){var c=r(this,a,b);c.extend=this.extend;return c}});h(l.prototype,n,{type:"o_O.array",initialize:function(){},_onevent:function(a,b,c){("add"==a||"remove"==a)&&c!=this||("destroy"==a&&this.remove(b),this.emit.apply(this,arguments))},bind:function(a){e.bind(this,
a);return this},indexOf:function(a){return this.items.indexOf(a)},filter:function(a){return this.items.filter(a)},find:function(a){for(var b=0;b<this.items.length;b++){var c=this.items[b];if(a(c,b))return c}},map:function(a){this.count();for(var b=[],c=0;c<this.length;c++){var d=a.call(this,this.items[c],c);b.push(d)}return b},push:function(a){return this.insert(a,this.length)},unshift:function(a){return this.insert(a,0)},pop:function(){return this.removeAt(this.length-1)},shift:function(){return this.removeAt(0)},
at:function(a){return this.items[a]},insert:function(a,b){if(0>b||b>this.count())return!1;this.items.splice(b,0,a);l.add(this,a,b);return a},removeAt:function(a){if(0>a||a>this.count())return!1;var b=this.items[a];this.items.splice(a,1);l.remove(this,b,a);return b},remove:function(a){for(var b="function"===typeof a,a=b?this.items.filter(a):[a],c,d=a.length,e=0;e<d;e++)c=this.indexOf(a[e]),-1!==c&&this.removeAt(c);return b?a:a[0]},renderItem:function(a,b,c){var d=$(p(b));(c=this.at(c).el||b.children()[c])?
d.insertBefore(c):b.append(d);e.bind(a,d)},onbind:function(a){var b=this;this.on("add",function(c,d,e){b.renderItem(c,a,e)});this.on("remove",this.removeElement,this);this.el=a[0]},removeElement:function(a,b){$(a.el||$(this.el).children()[b]).remove()},toString:function(){return"#<"+this.type+":"+this.length+">"},toJSON:function(){return this.map(function(a){return a.toJSON?a.toJSON():a})}});l.prototype.each=l.prototype.forEach=l.prototype.map;e.array=l;e.uuid=function(){return Math.random().toString(36).slice(2)};
h(e,{bindingAttribute:"data-bind",removeBindingAttribute:!0,inherits:r,extend:h,Events:n,VERSION:"0.2.6"});if("undefined"==typeof module){var q=document.getElementsByTagName("script"),q=q[q.length-1].src.split("?")[1];window[q||"o_O"]=e}else module.exports=e}();
(function(){function d(a){a=a.replace(f,"\\$&").replace(g,"([^/]+)").replace(h,"(.*?)");return RegExp("^"+a+"$")}var g=/:\w+/g,h=/\*\w+/g,f=/[-[\]{}()+?.,\\^$|#\s]/g,i=/^[#\/]/;o_O.router=o_O.model.extend({},{initialize:function(){this.routes=[]},add:function(a,b){404===a?this.routing_404={handler:b}:this.routes.push({regex:d(a),handler:b});return this},runRouting:function(a){for(var b=[],c=0;c<this.routes.length;c++){var e=this.routes[c];e.regex.test(a)&&b.push(e)}for(c=0;c<b.length;c++){var d=e.regex.exec(a).slice(1);
this.runRoute(b[c],d)}0==b.length&&this.routing_404&&this.runRoute(this.routing_404,[])},runRoute:function(a,b){"string"==typeof a.handler?(b.unshift(a.handler),this.emit.apply(this,b)):a.handler.apply(null,b)},getHash:function(){var a=window.location.href.match(/#(.*)$/);return a?a[1]:""},go:function(){this.location=this.getHash().replace(i,"");this.runRouting(this.location)},start:function(){var a=this;this.go();$(window).bind("hashchange",function(){a.go()})},redirect:function(a,b){if(!1===b)this.runRouting(a);
else{var c="#!"+a;document.location.hash==c?this.go():document.location.hash=c}}});o_O.extend(o_O.router.prototype,o_O.Events)}).call(this);
# Funnyface.js TodoMVC Example
> O_o: HTML binding for teh lulz.
> _[Funnyface.js - weepy.github.io/o_O](http://weepy.github.io/o_O)_
## Learning Funnyface.js
The [Funnyface.js website](http://weepy.github.io/o_O) is a great resource for getting started.
Here are some links you may find helpful:
* [Examples](http://weepy.github.io/o_O/examples/guide/index.html)
* [Funnyface.js on GitHub](https://github.com/weepy/o_O)
_If you have other helpful links to share, or find any of the links above no longer work, please [let us know](https://github.com/tastejs/todomvc/issues)._
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment