jQuery++ template

Includes the full version of jQuery++. Use it as a starting point when you want to demo something.

HTML

<script src="http://jquerypp.com/release/latest/jquerypp.js"></script>
<article>
    <h1 class="post-title">Weekly Widget 1 -&nbsp;TreeCombo</h1>
    <div class="author-time">18 January 2013 by justinbmeyer</div>
    <p>I, <a href="http://twitter.com/justinbmeyer">@justinbmeyer</a>, am 
        going to post a weekly widget made with CanJS. I hope to continue
        this for as long as I have widgets to write. If you 
        <strong>want to see something</strong>, please tweet it to 
        <a href="http://twitter.com/justinbmeyer">@canjs</a>. These posts
        are going to be quick and dirty. Eventually, I will put 
        these up on <a href="http://canjs.us/recipes.html">CanJS’s recipe page</a> with
        a full description.
    </p>
    <p>I’m starting with the <code>TreeCombo</code> below:</p>

    <iframe style="width: 100%; height: 300px" src="http://jsfiddle.net/sTLhX/35/embedded/result,html,js"         
           allowfullscreen="allowfullscreen" frameborder="0">JSFiddle</iframe>

    <h2 id="what-it-does">What it does</h2>

    <p>The tree combo allows you to select items within and
    navigate through a hierarchial collection
    of data. Click “→” to see child items. Click the
    breadcrumb navigation at the top to return to parent items.</p>

    <p>It also displays a list of the items the user has selected under

        “You’ve selected:”.</p>
</article>
<article>
    <h1 class="post-title">Weekly Widget 2 - 2-Way Mustache&nbsp;Helpers
	</h1>
	<div class="author-time">27 January 2013 by justinbmeyer</div>
	<p>This article shows how to make 2-way binding mustache helpers
        and use them in a basic form.</p>

    <p>By default, CanJS supports 1-way binding templates. 
        1-way binding means that if data changes,
        the template is automatically updated. For example,
        if <code>attendee.name</code> changes, the following input’s value is updated:
    </p>

    <pre><code class="xml"><span class="tag">&lt;<span...

CSS

* {
font: 13px/16px "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
    color: #333;
}
h1, h2, h3, b, strong { font-weight: bold; color: #000;}
h1 { font-size: 18px; margin-bottom:5px; }
p {margin: 5px 0; }
article {
    margin: 10px;
    padding-bottom: 10px;
    border-bottom: solid 1px #eee;
}
.author-time { color: #999; font-size: 11px; }
.more, .less {
    color: #fff;    
    text-decoration: none;
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    border-radius: 10px;
    text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
    background-color: #49afcd;
    border-color: #2f96b4 #2f96b4 #1f6377;
    padding: 0 3px 2px;
    height: 11px;
    line-height: 11px;
    display: inline-block;
}
.less {
    padding: 0 4px 2px;
    background-color: #206478;
}

JavaScript

(function(){

	
	/**
	 * $('.body').more({
	 *   moreHTML: "<a href='javascript://' class='more'>...</a>",
	 *   moreWidth: 50,
	 *   lessHTML: " <a href='javascript://' class='less'>less</a>",
     *   lines: 2
	 * })
	 */
	$.fn.more = function(options){
		// setup defaults
			options = $.extend({
				lessHTML: " <a href='javascript://' class='less'>-</a>",
				moreHTML: " <a href='javascript://' class='more'>+</a>",
				moreWidth: 50,
                lines: 2
			},options||{});
			
	    this.each(function(el){
			var $el = $(this);
			
			// save current HTML for later
			$el.data('originalHTML', $el.html())

			// the active range we will be moving around
			var range = $el.range(),
				// the end of the body's text for comparison
				end = range.clone().collapse(false).start("-1"),
				// the start of the body's text for comparison
				start = nextChar(range.collapse().end("+1"),end).clone(),
				// the current line's first character's coordinates
				prevRect = start.rect(),
				// how many lines we've come across
				lines = 0;
			
			// go until we reach the end of the body 
			while(range.compare("START_TO_START",end) != 0){
				range.end("+1").start("+1");
                
				var rect = range.rect();
				// if the charcter is on a new line
				if( rect && (rect.top -prevRect.top  > 4) ) {
					lines++;
					// quit on second line
					if(lines == options.lines){
						break;
					}
					prevStart = range.clone()
					prevRect = rect;
				}
			}
			
			if(lines === options.lines){
				// backup to previous line
				range.end('-1').start('-1');
			}
			
			// get the last visible text element
			prevChar(range, start)
			
			var movedLeft = false,
                offset = $el.offset(),
				width = $el.width();
            
			// keep moving back until there is room for more
			while(range.compare("START_TO_START",start) != -1 ){
				if( range.rect(true).left <= (offset.left+width-options.moreWidth) ) {
					break;
				}
				movedLeft =...