Bootstrap "compiler"

by path411

HTML

<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
<script type="bootshine">
    <dropdown>
        <button id="dropdownMenu1" caret>Dropdown</button>
        <menu>
            <item link="#">Action</item>
            <item link="#">Another action</item>
            <item link="#">Something else here</item>
            <menudivider/>
            <item link="#">Separeted link</item>
        </menu>
    </dropdown>
</script>

JavaScript

function isDefined(val) {
	return typeof val != 'undefined';
}

$(function() {
	Main();
});

function Main() {
	$('script[type="bootshine"]').each(BuildSection);
}

function BuildSection(i, src) {
	var $xml = $($(src).html());
	var $section = $([]);
	$xml.each(function() {
		var $this = $(this);
		var $component = BuildComponent($this);
		$section = $section.add($component);
	});

	$(src).replaceWith($section);
}

function BuildComponent($component) {
	var $built = null;;
	switch($component.prop('tagName').toLowerCase()) {
		case "dropdown":
			$built = BuildDropdown($component);
		break;	
	}
	return $built;
}

function BuildDropdown($xml) {
	var $dropdown = $('<div/>', {'class': 'dropdown'});
	$xml.children().each(function BuildChildren () {
		var $this = $(this);
		var $child = null;
		var buttonid = null;
		switch($this.prop('tagName').toLowerCase()) {
			case 'button':
				$child = BuildButton($this, ['data-toggle', 'dropdown']);
				buttonid = isDefined($child.attr('id')) ? $child.attr('id') : null;
			break;
			case 'menu':
				$child = BuildDropdownMenu($this, (buttonid == null ? undefined : ['aria-labelledby', buttonid]));
			break;
		}

		if($child != null) {
			$dropdown.append($child);
		}
	});

	return $dropdown;
}
	function BuildDropdownMenu($xml, attrs) {
		var $menu = $('<ul/>', 	{
									'class': 'dropdown-menu' + (isDefined($xml.attr('class')) ? ' ' + $xml.attr('class') : ''),
									'role': 'menu'
								});
		$xml.children().each(function() {
			var $this = $(this);
			var $menuitem = $('<li/>');
			if( isDefined($this.attr('class')) ) {
				$menuitem.attr('class', $this.attr('class'));
			}
			switch($this.prop('tagName').toLowerCase()) {
				case 'item':
					if( isDefined($this.attr('link')) ) {
						$menuitem.attr('role', 'presentation');
						var $link = $('<a/>', { 'role':'menuitem', 'tabindex':'-1', 'href': $this.attr('link'), 'text': $this.text() });
						$menuitem.append($link);
					}
					else {
						$menuitem.attr('role',...