| author | Josh Kropf <josh@slashdev.ca> | 2010-06-06 22:36:10 (GMT) |
|---|---|---|
| committer | Josh Kropf <josh@slashdev.ca> | 2010-06-06 22:36:10 (GMT) |
| commit | 8ac0b2c778d836f4d9ae1a065a665bcac961921a (patch) (side-by-side diff) | |
| tree | 39c0890e9101252f001ebbc3f44ed185d54e8abb | |
| parent | 6c3bfbf5dc6b1fe4b9e31b427d0917af696feebd (diff) | |
| download | jqtemplate-master.zip jqtemplate-master.tar.gz jqtemplate-master.tar.bz2 | |
repeated evaluation of the last element in a loop
when several elements in the template contained the
same relative dom path.
| -rw-r--r-- | build.properties | 2 | ||||
| -rw-r--r-- | dist/jquery.jqtemplate-0.3.min.js | 1 | ||||
| -rw-r--r-- | dist/jquery.jqtemplate-0.4.min.js | 1 | ||||
| -rw-r--r-- | src/jquery.jqtemplate.js | 101 |
4 files changed, 48 insertions, 57 deletions
diff --git a/build.properties b/build.properties index 5971fc4..1646df2 100644 --- a/build.properties +++ b/build.properties @@ -1 +1 @@ -version=0.3 +version=0.4 diff --git a/dist/jquery.jqtemplate-0.3.min.js b/dist/jquery.jqtemplate-0.3.min.js deleted file mode 100644 index 02fd861..0000000 --- a/dist/jquery.jqtemplate-0.3.min.js +++ b/dev/null @@ -1 +0,0 @@ -(function(d){d.fn.jqtemplate=function(g,f){var i=d.extend({},d.fn.jqtemplate.defaults,f),h=this.selector+"/";if(this.data("compiled")!=true){c(this,this.selector);this.data("compiled",true)}if(i.inplace){return this.each(function(j,k){b(g,k,h+k.get(0).nodeName)})}else{var e=typeof(i.root)=="string"?d(i.root):i.root;return this.each(function(j,k){var l=d(k).clone();e.append(l);b(g,l,h+k.nodeName)})}};d.fn.jqtemplate.defaults={inplace:false,root:"body"};var a={};function c(g,k){k=k+"/"+g.get(0).nodeName;var j=["jqloop","jqbind","jqattr","jqtext"];for(var e in j){if(g.attr(j[e])){var h=new Function(["$this"],"return "+g.attr(j[e]));a[k+"/"+j[e]]=h}}g.children().each(function(f,l){c(d(l),k)})}function b(l,g,q){if(g.attr("jqloop")){var k=a[q+"/jqloop"](l),j=g,o=g;g.removeAttr("jqloop");for(var h in k.array){l[k.object]=k.array[h];var e=d(j.clone());o.after(e);o=e;b(l,e,q)}j.remove();return}if(g.attr("jqbind")){var f=d.makeArray(a[q+"/jqbind"](l));for(var h in f){g.bind(f[h].event,f[h],function(i){var r=i.data;r.fn.apply(this,d.makeArray(r.args))})}}if(g.attr("jqattr")){var n=a[q+"/jqattr"](l);for(var m in n){g.attr(m,n[m])}}if(g.attr("jqtext")){var p=a[q+"/jqtext"](l);g.text(p)}g.children().each(function(r,s){b(l,d(s),q+"/"+s.nodeName)})}})(jQuery);
\ No newline at end of file diff --git a/dist/jquery.jqtemplate-0.4.min.js b/dist/jquery.jqtemplate-0.4.min.js new file mode 100644 index 0000000..2ceccc1 --- a/dev/null +++ b/dist/jquery.jqtemplate-0.4.min.js @@ -0,0 +1 @@ +(function(c){c.fn.jqtemplate=function(f,e){var h=c.extend({},c.fn.jqtemplate.defaults,e),g=this.selector+"/";if(this.data("compiled")!=true){b(this);this.data("compiled",true)}if(h.inplace){return this.each(function(j,k){a(f,c(k),c(k))})}else{var d=typeof(h.root)=="string"?c(h.root):h.root;return this.each(function(j,k){var l=c(k).clone();d.append(l);a(f,l,c(k))})}};c.fn.jqtemplate.defaults={inplace:false,root:"body"};function b(f){var g=["jqloop","jqbind","jqattr","jqtext"];for(var e in g){var d=g[e];if(f.attr(d)){f.data(d,new Function(["$this"],"return "+f.attr(d)))}}f.children().each(function(h,j){b(c(j))})}function a(m,f,e){if(f.attr("jqloop")){var k=e.data("jqloop")(m),h=f,l=f;f.removeAttr("jqloop");for(var g in k.array){m[k.object]=k.array[g];var j=c(f.clone());l.after(j);l=j;a(m,j,e)}h.remove();return}if(f.attr("jqbind")){var d=e.data("jqbind")(m);for(var g in d){f.bind(d[g].event,d[g],function(i){var p=i.data;p.fn.apply(this,c.makeArray(p.args))})}}if(f.attr("jqattr")){var o=e.data("jqattr")(m);for(var n in o){f.attr(n,o[n])}}if(f.attr("jqtext")){f.text(e.data("jqtext")(m))}(function(p,i){if(p.length!=0){a(m,p,i);arguments.callee(p.next(),i.next())}})(f.children().first(),e.children().first())}})(jQuery);
\ No newline at end of file diff --git a/src/jquery.jqtemplate.js b/src/jquery.jqtemplate.js index 320101c..ae846ba 100644 --- a/src/jquery.jqtemplate.js +++ b/src/jquery.jqtemplate.js @@ -1,7 +1,7 @@ /* * jQtemplate jQuery plugin * - * Copyright (c) 2009 Josh Kropf + * Copyright (c) 2009-2010 Josh Kropf * * Licensed under the GPL license: * http://www.gnu.org/licenses/gpl.html @@ -61,100 +61,89 @@ $.fn.jqtemplate = function(model, options) { var opts = $.extend({}, $.fn.jqtemplate.defaults, options), templatePath = this.selector + "/"; - + if (this.data("compiled") != true) { - compileTemplate(this, this.selector); + compileTemplate(this); this.data("compiled", true); } - + if (opts.inplace) { return this.each(function(i, node) { - evalNode(model, node, templatePath + node.get(0).nodeName); + evalNode(model, $(node), $(node)); }); } else { // when root option is a string use it as a selector, otherwise // assume it is already a jquery object for the root node var root = typeof(opts.root) == "string"? $(opts.root) : opts.root; - + return this.each(function(i, node) { var copy = $(node).clone(); root.append(copy); - evalNode(model, copy, templatePath + node.nodeName); + evalNode(model, copy, $(node)); }); } }; - + $.fn.jqtemplate.defaults = { inplace: false, root: "body" }; - - /** - * Map of attribute functions. Keys of the map are path representations - * of the template node that contains jqtemplate attributes. The value for - * a given key is the compiled function. - */ - var attrCallback = {}; - + /** * Recursively create function objects for jqtemplate attributes. * @param node current template node - * @param path path representation of template node */ - function compileTemplate(node, path) { - path = path + "/" + node.get(0).nodeName; - + function compileTemplate(node) { var names = ["jqloop", "jqbind", "jqattr", "jqtext"]; for (var i in names) { - if (node.attr(names[i])) { - var f = new Function(["$this"], "return " + node.attr(names[i])); - attrCallback[path + "/" + names[i]] = f; + var attr = names[i]; + if (node.attr(attr)) { + node.data(attr, new Function(["$this"], "return " + node.attr(attr))); } } - + node.children().each(function(i, node) { - compileTemplate($(node), path); + compileTemplate($(node)); }); } - + /** * Recursively evaluate nodes of the template and their children. * @param $this object model/context of template evaluation - * @param node current template node - * @param path path representation of template node + * @param node current node to be manipulated in the dom + * @param templateNode current template node */ - function evalNode($this, node, path) { + function evalNode($this, node, templateNode) { if (node.attr("jqloop")) { - var op = attrCallback[path + "/jqloop"]($this), - first = node, - last = node; - + var op = templateNode.data("jqloop")($this), + first = node, current = node; + // remove jqloop attribute to avoid infinate recursion node.removeAttr("jqloop"); - + // iterate over objects in the loop array and create/add // new nodes in the dom for (var i in op.array) { // place the current array element in the template context $this[op.object] = op.array[i]; - - // clone the first node (the template node) and - // add it after the last node - var copy = $(first.clone()); - last.after(copy); - last = copy; - + + // clone the current node and add it after the current + var next = $(node.clone()); + current.after(next); + current = next; + // evaluate the cloned node - evalNode($this, copy, path); + evalNode($this, next, templateNode); } - + + // first node is used as a place holder and is not evaluated first.remove(); return; } - + if (node.attr("jqbind")) { - var bindings = $.makeArray(attrCallback[path + "/jqbind"]($this)); - + var bindings = templateNode.data("jqbind")($this); + for (var i in bindings) { node.bind(bindings[i].event, bindings[i], function(event) { // apply will call the function with a given 'this' object @@ -166,22 +155,24 @@ }); } } - + if (node.attr("jqattr")) { - var attrs = attrCallback[path + "/jqattr"]($this); + var attrs = templateNode.data("jqattr")($this); for (var key in attrs) { node.attr(key, attrs[key]); } } - + if (node.attr("jqtext")) { - var text = attrCallback[path + "/jqtext"]($this); - node.text(text); + node.text(templateNode.data("jqtext")($this)); } - - node.children().each(function(i, node) { - evalNode($this, $(node), path + "/" + node.nodeName); - }); + + (function(nodeChild, templateChild) { + if (nodeChild.length != 0) { + evalNode($this, nodeChild, templateChild); + arguments.callee(nodeChild.next(), templateChild.next()); + } + })(node.children().first(), templateNode.children().first()); } })(jQuery); |
