CanJS {{switch}} case helper

by prometh

HTML

<script src="http://canjs.us/release/latest/can.jquery.js"></script>
<script src="http://canjs.us/release/latest/can.construct.proxy.js"></script>
<script src="http://canjs.us/release/latest/can.control.plugin.js"></script>
<script src="http://canjs.us/release/latest/can.view.modifiers.js"></script>
<script src="http://canjs.us/release/latest/can.construct.super.js"></script>
<script src="http://canjs.us/release/latest/can.object.js"></script>
<script src="http://canjs.us/release/latest/can.ejs.js"></script>
<script src="http://canjs.us/release/latest/can.map.attributes.js"></script>
<script src="http://canjs.us/release/latest/can.map.backup.js"></script>
<script src="http://canjs.us/release/latest/can.map.delegate.js"></script>
<script src="http://canjs.us/release/latest/can.map.setter.js"></script>
<script src="http://canjs.us/release/latest/can.map.validations.js"></script>
<script src="http://canjs.com/release/latest/can.fixture.js"></script>
<script src="http://canjs.com/release/latest/can.stache.js"></script>
<script id="main" type="text/handlebars">
    {{#switch state}}
        {{#case "page1"}}page 1{{/case}}
        {{#case "page2"}}page 2{{/case}}
    {{/switch}}
</script>

JavaScript

can.Component.extend({
    tag: "app-main",
    template: can.view("main"),
    scope: { state:"page1" }
});


/*
{{#switch attr}}
    {{#case "value1"}}...{{/case}}
    {{#case "value2" "value3" ... "valueN"}}...{{/case}}
{{/switch}}

Note: nested switches probably won't work.
*/


can.stache.registerHelper("switch", function(param, options) {
	options.scope._switch = { is:true, done:false, param:param() };
	
	var fragment = options.fn(options.scope, options.options);
	
	delete options.scope._switch;
	return fragment;
});



can.stache.registerHelper("case", function() {
    var containsParam = false;
	var options = Array.prototype.pop.apply(arguments);
	
	if (options.scope._switch) {
		for (var i=0, numArgs=arguments.length; i<numArgs; i++) {
			if (arguments[i] == options.scope._switch.param) {
				containsParam = true;
				break;
			}
		}
		
		if (containsParam) {
			return options.fn(options.scope, options.options);
		}
	}
});


can.append( can.$(document.body), can.stache("<app-main/>")() );