<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,3 +1,4 @@
 .DS_Store
 commit.sh
 js/*.html
+bugs/*</diff>
      <filename>.gitignore</filename>
    </modified>
    <modified>
      <diff>@@ -14,7 +14,8 @@ var $p = {};
 		//default to browser internal selector
 		find: function(n, sel){
 			return (n||document).querySelector( sel );
-		}
+		},
+		autoAtt:'class'
 	};
 	//if IE take the internal method otherwise build one
 	var outerHTML = function(node){
@@ -30,15 +31,22 @@ var $p = {};
 		};
 	};
 
-	var walk = function(n, f) {
+	var walk = function(n, bf, af) {
 		n = n.firstChild;
 		while (n) {
-			walk(n, f);
-			f(n);
+			if(bf(n)){ //if true, stop this branch
+				return;
+			};
+			walk(n, bf, af);
+			af(n);
 			n = n.nextSibling;
 		}
 	};
 
+	var getAtt =  config.autoAtt === 'class' ? 
+		function(node){return node.className;}:
+		function(node){return node.getAttribute(config.autoAtt);};
+
 	// create a function that concatenates constant string
 	// sections (given in parts) and the results of called
 	// functions to fill in the gaps between parts (fns).
@@ -203,7 +211,7 @@ var $p = {};
 		}
 	};
 
-	var render0, render1;				// for JSLint - defined later.
+	var render0;				// for JSLint - defined later.
 
 	var loopfn = function(name, dselect, inner){
 		return function(ctxt){
@@ -223,22 +231,27 @@ var $p = {};
 		};
 	};
 
-	var loopgen = function(dom, sel, loop, fns, node, data, attr){
+	var loopgen = function(dom, sel, loop, fns, currNode, data){
 		var already = false;
-		var p;
-		for(var i in loop){
-			if(loop.hasOwnProperty(i)){
-				if(already){
-					error('cannot have more than one loop on a target');
+		var p, dsel;
+		if(loop){
+			for(var i in loop){
+				if(loop.hasOwnProperty(i)){
+					if(already){
+						error('cannot have more than one loop on a target');
+					}
+					p = i;
+					already = true;
 				}
-				p = i;
-				already = true;
 			}
+			if(!p){
+				error('no loop spec');
+			}
+			dsel = loop[p];
+		}else{
+			dsel = {};
+			p = sel+'&lt;-'+sel;
 		}
-		if(!p){
-			error('no loop spec');
-		}
-		var dsel = loop[p];
 		// if it's a simple data selector then we default to contents, not replacement.
 		if(typeof(dsel) === 'string' || typeof(dsel) === 'function'){
 			loop = {};
@@ -247,13 +260,13 @@ var $p = {};
 		}
 		var spec = parseloopspec(p);
 		var itersel = dataselectfn(spec.sel);
-		var target = gettarget(dom, sel, true, node);
+		var target = gettarget(dom, sel, true, currNode);
 		var nodes = target.nodes;
 		for(i = 0; i &lt; nodes.length; i++){
 			var node = nodes[i];
 			// could check for overlapping loop targets here by checking that
 			// root is still ancestor of node.
-			var inner = render0(node, dsel, data, attr);
+			var inner = render0(node, dsel, data);
 			fns[fns.length] = wrapquote(target.quotefn, loopfn(spec.name, itersel, inner));
 			target.nodes = [node];		// N.B. side effect on target.
 			setsig(target, fns.length - 1);
@@ -263,48 +276,68 @@ var $p = {};
 	// render0 returns a function that, given a context argument,
 	// will render the template defined by dom and directive.
 	// NB. declared above.
-	render0 = function(dom, directive, data, attr){
-		var fns = [], target;
+	render0 = function(dom, directive, data){
+		var fns = [];
 		dom = clone(dom);
 
+		var buildLoops = function(sel, dsel, fns, node){
+			var val = dataselectfn(sel[2])({data:data});
+			if(typeof val === 'object'){ //array or object
+				loopgen(dom, sel[2], false, fns, node, data);
+				return true;
+			}else{
+				return false;
+			}
+		};
+		var buildParts = function(sel, dsel, fns, node){
+			var target;
+			if(typeof(dsel) === 'function' || typeof(dsel) === 'string'){
+				target = gettarget(dom, sel, false);
+				setsig(target, fns.length);
+				fns[fns.length] = wrapquote(target.quotefn, dataselectfn(dsel));
+			}else{
+				loopgen(dom, sel, dsel, fns, node, data);
+			}
+		};
+
 		for(var sel in directive){
 			if(directive.hasOwnProperty(sel)){
 				var dsel = directive[sel];
-				if(typeof(dsel) === 'function' || typeof(dsel) === 'string'){
-					target = gettarget(dom, sel, false);
-					setsig(target, fns.length);
-					fns[fns.length] = wrapquote(target.quotefn, dataselectfn(dsel));
-				}else{
-					loopgen(dom, sel, dsel, fns);
-				}
+				buildParts(sel, dsel, fns);
 			}
 		}
 		
 		if(data){
-			var getAtt = attr ? 
-				function(node){return node.getAttribute('attr');}:
-				function(node){return node.className;};
-			walk(dom, function(node){
-				if(node.nodeType !== 1) {return;}
-				var a, c, i = 0, l, sel;
+			var forEachClass = function(node, cb){
+				var a, c, i = 0, l, sel, val, stopWalk;
 				c = getAtt(node);
 				if(c){
 					a = c.split(' ');
 					l = a.length;
 					for(;i&lt;l;i++){
 						sel = a[i].match(/(\+)?([^\@\+]+)@?(\w+)?(\+)?/);
-						var dirSel = (sel[1]||'')+sel[2]+(sel[3] ? '['+sel[3]+']':'')+(sel[4]||'');
-						var val = dataselectfn(sel[2])({data:data});
-						if(typeof val === 'function' || typeof val === 'string'){
-							target = gettarget(dom, dirSel, false, node);
-							setsig(target, fns.length);
-							fns[fns.length] = wrapquote(target.quotefn, dataselectfn(sel[2]));
-						}else{
-							loopgen(dom, sel[0], val, fns, node, data, attr);
+//						if(typeof val.length === 'number' &amp;&amp; !(val.propertyIsEnumerable('length')) &amp;&amp; typeof val.splice === 'function'){
+//							(sel[1]||'')+sel[2]+(sel[3] ? '['+sel[3]+']':'')+(sel[4]||''),
+						isLoop = cb(sel, {}, fns, node);
+						if(isLoop){
+							stopWalk = true;
 						}
 					}
+					return stopWalk;
+				}
+			};
+			walk(dom, 
+				//before walk
+				function(node){
+					if(node.nodeType === 1) {
+						return forEachClass(node, buildLoops);}
+				},
+				//after walk
+				function(node){
+					if(node.nodeType === 1) {
+						return forEachClass(node, buildParts);}
 				}
-			});
+			);
 		}
 
 		var h = outerHTML(dom);
@@ -320,8 +353,9 @@ var $p = {};
 	};
 	
 	pure.compile = function(template, directive, ctxt){
+		var rfn = render0(template, directive, ctxt);
 		return function(data){
-			return render0(template, directive, ctxt)({data: data});
+			return rfn({data: data});
 		};
 	};
 	pure.config = function(cfg){</diff>
      <filename>js/pure2.js</filename>
    </modified>
    <modified>
      <diff>@@ -38,7 +38,9 @@
     &lt;/ul&gt;
 &lt;/div&gt;
 &lt;div class=&quot;helloWho&quot;&gt;
-	Hello &lt;span class=&quot;who+ +who@dataatt&quot; dataatt=&quot;_hey&quot;&gt;who&lt;/span&gt;
+	&lt;ul class=&quot;helloWho&quot;&gt;
+		&lt;li class=&quot;who who.name&quot;&gt;who&lt;/li&gt;
+	&lt;/ul&gt;
 &lt;/div&gt;
 
 	&lt;script src=&quot;../js/jquery.js&quot;&gt;&lt;/script&gt;
@@ -134,10 +136,23 @@
 			var h = rfn(countries);
 			$('ul.treeItem').get(0).innerHTML = h;
 	
-			var hello = {who:'Mary'};
-			var template = $('div.helloWho').get(0);
+			var hello = {
+				who:[
+					{name:'Mary'},
+					{name:'Harry'}
+				]
+			};
+			var dir = {
+				'.who':{
+					'person&lt;-who':{
+						'root':'person.name'
+					}
+				}
+			};
+
+			var template = $('ul.helloWho').get(0);
 			var rfn = jQuery.pureCompile(template, false, hello);
-			template.innerHTML = rfn(hello);
+			$('div.helloWho').get(0).innerHTML = rfn(hello);
 			
 		})();
 	&lt;/script&gt;</diff>
      <filename>test/testPage_jquery.html</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>fe47770e28fb018195c0921448a1a7842d91fad4</id>
    </parent>
  </parents>
  <author>
    <name>mic</name>
    <email>mic@micpro.local</email>
  </author>
  <url>http://github.com/pure/pure/commit/70f7b472040710c3c7326641a8564e0e0a954512</url>
  <id>70f7b472040710c3c7326641a8564e0e0a954512</id>
  <committed-date>2009-04-29T05:57:39-07:00</committed-date>
  <authored-date>2009-04-29T05:57:39-07:00</authored-date>
  <message>autorender not working for loops</message>
  <tree>c37cfe6065805f0b9daac4c67542d76f27dd846a</tree>
  <committer>
    <name>mic</name>
    <email>mic@micpro.local</email>
  </committer>
</commit>
