less.js templating

by paulftw

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/1.4.1/less.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.5/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-strap/0.7.4/angular-strap.min.js"></script>
<div class=pickerctrl>
    <h1>Background</h1>
    <div class=picker></div>
    <h1>Text</h1>
    <div class=picker></div>
    
    <button class=targetbutton>choose target</button>
</div>

<div class=document data-theme=b>
    <div class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">PName</a>
        </div>
        <div class="navbar-collapse collapse">
          <ul class="nav navbar-nav">
            <li class="active"><a href="#">Home</a></li>
            <li><a href="#about">About</a></li>
            <li><a href="#contact">Contact</a></li>
            <li class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
              <ul class="dropdown-menu">
                <li><a href="#">Action</a></li>
                <li><a href="#">Another action</a></li>
                <li><a href="#">Something else here</a></li>
                <li class="divider"></li>
                <li class="dropdown-header">Nav header</li>
                <li><a href="#">Separated link</a></li>
                <li><a href="#">One more separated link</a></li>
              </ul>
            </li>
          </ul>
      ...

CSS

.pickerctrl {
    position: fixed;
    right: 10px;
    top: 20%;
    
    background-color: rgba(0,0,0,0.4);
    border: 1px dashed #fff;
    border-radius: 4px;
    //height: 40px;
    //width: 40px;
    z-index: 1000;
}

.pickerctrl h1 {
    color: #fff;
    font-size: 12px;
}

#hoverframe {
    position: absolute;
    border: 3px dashed #3c3;
    
    height: 10px;
    width: 10px;
    pointer-events: none;
    pointer-events: none;
}

@jumbothron_bg: #ddd;
@jumbothron_color: #000;

@button_bg: #ccc;
@p_bg: #efe;

.jumbotron {
    background-color: @jumbothron_bg;
    color: @jumbothron_color;
}

a.btn {
    background-color: @button_bg;
}

p {
    background-color: @p_bg;
}

JavaScript

$(function() {
    var theme = {
        button_bg: '#ccc',
        p_bg: '#fff',
        jumbotron_bg: '#666'
    };
    window.setTimeout(function() {
        less.modifyVars(theme);
    }, 3000);
    
    $('.jumbotron a.btn').click(function() {
        console.log('jquery click - you want to learn more?');
    });
    
    var cw = Raphael.colorwheel(
            $('.pickerctrl .picker')[0],
            70);
    cw.onchange(function(color) {
        console.log('change color', color.hex);
    });
    cw.color('#ffffff');
    
    function get_frame() {
        if ($('#hoverframe').length) {
            return $('#hoverframe');
        }
        return $('<div id=hoverframe></div>')
                .appendTo($('body'));
    };
    
    var pick_element = function($el) {
        var swatch = $el.closest('[data-theme]').data('theme');
        console.log('found swatch', swatch);
    };

    var hover_stack = [];
    hover_in_element = function(el) {
        hover_stack.push(el);
        
        el._styler_old_onclick = this.onclick;
        el.onclick = null;
        active_el = el;
        console.log('events on el:', $(el).data('events'));
        
        show_frame(active_el);
    };
    
    var show_frame = function(el) {
        var f = get_frame().show();
        var tg = $(el);
        var pos = tg.offset();
        f.css('left', '' + pos.left + 'px')
            .css('top', '' + pos.top + 'px');
        f.width(tg.outerWidth())
            .height(tg.outerHeight());
    };
    
    var hide_frame = function() {
        get_frame().hide();
    };
    
    hover_out_element = function(el) {
        hover_stack.pop();
        el.onclick = el._styler_old_onclick;
        hide_frame();
        if (hover_stack.length) {
            hover_in_element(hover_stack[hover_stack.length - 1]);
        }
    };
    
    var select_active = false;
    $('button.targetbutton').click(function() {
        var select_active = true;
        var active_el = null;
        
...