backbonejs-rails 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,27 @@
1
+ // Backbone.js 0.3.3
2
+ // (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
3
+ // Backbone may be freely distributed under the MIT license.
4
+ // For all details and documentation:
5
+ // http://documentcloud.github.com/backbone
6
+ (function(){var e;e=typeof exports!=="undefined"?exports:this.Backbone={};e.VERSION="0.3.3";var f=this._;if(!f&&typeof require!=="undefined")f=require("underscore")._;var h=this.jQuery||this.Zepto;e.emulateHTTP=false;e.emulateJSON=false;e.Events={bind:function(a,b){this._callbacks||(this._callbacks={});(this._callbacks[a]||(this._callbacks[a]=[])).push(b);return this},unbind:function(a,b){var c;if(a){if(c=this._callbacks)if(b){c=c[a];if(!c)return this;for(var d=0,g=c.length;d<g;d++)if(b===c[d]){c.splice(d,
7
+ 1);break}}else c[a]=[]}else this._callbacks={};return this},trigger:function(a){var b,c,d,g;if(!(c=this._callbacks))return this;if(b=c[a]){d=0;for(g=b.length;d<g;d++)b[d].apply(this,Array.prototype.slice.call(arguments,1))}if(b=c.all){d=0;for(g=b.length;d<g;d++)b[d].apply(this,arguments)}return this}};e.Model=function(a,b){a||(a={});if(this.defaults)a=f.extend({},this.defaults,a);this.attributes={};this._escapedAttributes={};this.cid=f.uniqueId("c");this.set(a,{silent:true});this._previousAttributes=
8
+ f.clone(this.attributes);if(b&&b.collection)this.collection=b.collection;this.initialize(a,b)};f.extend(e.Model.prototype,e.Events,{_previousAttributes:null,_changed:false,initialize:function(){},toJSON:function(){return f.clone(this.attributes)},get:function(a){return this.attributes[a]},escape:function(a){var b;if(b=this._escapedAttributes[a])return b;b=this.attributes[a];return this._escapedAttributes[a]=(b==null?"":b).replace(/&(?!\w+;)/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,
9
+ "&quot;")},set:function(a,b){b||(b={});if(!a)return this;if(a.attributes)a=a.attributes;var c=this.attributes,d=this._escapedAttributes;if(!b.silent&&this.validate&&!this._performValidation(a,b))return false;if("id"in a)this.id=a.id;for(var g in a){var i=a[g];if(!f.isEqual(c[g],i)){c[g]=i;delete d[g];if(!b.silent){this._changed=true;this.trigger("change:"+g,this,i,b)}}}!b.silent&&this._changed&&this.change(b);return this},unset:function(a,b){b||(b={});var c={};c[a]=void 0;if(!b.silent&&this.validate&&
10
+ !this._performValidation(c,b))return false;delete this.attributes[a];delete this._escapedAttributes[a];if(!b.silent){this._changed=true;this.trigger("change:"+a,this,void 0,b);this.change(b)}return this},clear:function(a){a||(a={});var b=this.attributes,c={};for(attr in b)c[attr]=void 0;if(!a.silent&&this.validate&&!this._performValidation(c,a))return false;this.attributes={};this._escapedAttributes={};if(!a.silent){this._changed=true;for(attr in b)this.trigger("change:"+attr,this,void 0,a);this.change(a)}return this},
11
+ fetch:function(a){a||(a={});var b=this,c=j(a.error,b,a);(this.sync||e.sync)("read",this,function(d){if(!b.set(b.parse(d),a))return false;a.success&&a.success(b,d)},c);return this},save:function(a,b){b||(b={});if(a&&!this.set(a,b))return false;var c=this,d=j(b.error,c,b),g=this.isNew()?"create":"update";(this.sync||e.sync)(g,this,function(i){if(!c.set(c.parse(i),b))return false;b.success&&b.success(c,i)},d);return this},destroy:function(a){a||(a={});var b=this,c=j(a.error,b,a);(this.sync||e.sync)("delete",
12
+ this,function(d){b.collection&&b.collection.remove(b);a.success&&a.success(b,d)},c);return this},url:function(){var a=k(this.collection);if(this.isNew())return a;return a+(a.charAt(a.length-1)=="/"?"":"/")+this.id},parse:function(a){return a},clone:function(){return new this.constructor(this)},isNew:function(){return!this.id},change:function(a){this.trigger("change",this,a);this._previousAttributes=f.clone(this.attributes);this._changed=false},hasChanged:function(a){if(a)return this._previousAttributes[a]!=
13
+ this.attributes[a];return this._changed},changedAttributes:function(a){a||(a=this.attributes);var b=this._previousAttributes,c=false,d;for(d in a)if(!f.isEqual(b[d],a[d])){c=c||{};c[d]=a[d]}return c},previous:function(a){if(!a||!this._previousAttributes)return null;return this._previousAttributes[a]},previousAttributes:function(){return f.clone(this._previousAttributes)},_performValidation:function(a,b){var c=this.validate(a);if(c){b.error?b.error(this,c):this.trigger("error",this,c,b);return false}return true}});
14
+ e.Collection=function(a,b){b||(b={});if(b.comparator){this.comparator=b.comparator;delete b.comparator}this._boundOnModelEvent=f.bind(this._onModelEvent,this);this._reset();a&&this.refresh(a,{silent:true});this.initialize(a,b)};f.extend(e.Collection.prototype,e.Events,{model:e.Model,initialize:function(){},toJSON:function(){return this.map(function(a){return a.toJSON()})},add:function(a,b){if(f.isArray(a))for(var c=0,d=a.length;c<d;c++)this._add(a[c],b);else this._add(a,b);return this},remove:function(a,
15
+ b){if(f.isArray(a))for(var c=0,d=a.length;c<d;c++)this._remove(a[c],b);else this._remove(a,b);return this},get:function(a){if(a==null)return null;return this._byId[a.id!=null?a.id:a]},getByCid:function(a){return a&&this._byCid[a.cid||a]},at:function(a){return this.models[a]},sort:function(a){a||(a={});if(!this.comparator)throw Error("Cannot sort a set without a comparator");this.models=this.sortBy(this.comparator);a.silent||this.trigger("refresh",this,a);return this},pluck:function(a){return f.map(this.models,
16
+ function(b){return b.get(a)})},refresh:function(a,b){a||(a=[]);b||(b={});this._reset();this.add(a,{silent:true});b.silent||this.trigger("refresh",this,b);return this},fetch:function(a){a||(a={});var b=this,c=j(a.error,b,a);(this.sync||e.sync)("read",this,function(d){b.refresh(b.parse(d));a.success&&a.success(b,d)},c);return this},create:function(a,b){var c=this;b||(b={});if(a instanceof e.Model)a.collection=c;else a=new this.model(a,{collection:c});return a.save(null,{success:function(d,g){c.add(d);
17
+ b.success&&b.success(d,g)},error:b.error})},parse:function(a){return a},chain:function(){return f(this.models).chain()},_reset:function(){this.length=0;this.models=[];this._byId={};this._byCid={}},_add:function(a,b){b||(b={});a instanceof e.Model||(a=new this.model(a,{collection:this}));var c=this.getByCid(a);if(c)throw Error(["Can't add the same model to a set twice",c.id]);this._byId[a.id]=a;this._byCid[a.cid]=a;a.collection=this;this.models.splice(this.comparator?this.sortedIndex(a,this.comparator):
18
+ this.length,0,a);a.bind("all",this._boundOnModelEvent);this.length++;b.silent||a.trigger("add",a,this,b);return a},_remove:function(a,b){b||(b={});a=this.getByCid(a)||this.get(a);if(!a)return null;delete this._byId[a.id];delete this._byCid[a.cid];delete a.collection;this.models.splice(this.indexOf(a),1);this.length--;b.silent||a.trigger("remove",a,this,b);a.unbind("all",this._boundOnModelEvent);return a},_onModelEvent:function(a,b){if(a==="change:id"){delete this._byId[b.previous("id")];this._byId[b.id]=
19
+ b}this.trigger.apply(this,arguments)}});f.each(["forEach","each","map","reduce","reduceRight","find","detect","filter","select","reject","every","all","some","any","include","invoke","max","min","sortBy","sortedIndex","toArray","size","first","rest","last","without","indexOf","lastIndexOf","isEmpty"],function(a){e.Collection.prototype[a]=function(){return f[a].apply(f,[this.models].concat(f.toArray(arguments)))}});e.Controller=function(a){a||(a={});if(a.routes)this.routes=a.routes;this._bindRoutes();
20
+ this.initialize(a)};var o=/:([\w\d]+)/g,p=/\*([\w\d]+)/g;f.extend(e.Controller.prototype,e.Events,{initialize:function(){},route:function(a,b,c){e.history||(e.history=new e.History);f.isRegExp(a)||(a=this._routeToRegExp(a));e.history.route(a,f.bind(function(d){d=this._extractParameters(a,d);c.apply(this,d);this.trigger.apply(this,["route:"+b].concat(d))},this))},saveLocation:function(a){e.history.saveLocation(a)},_bindRoutes:function(){if(this.routes)for(var a in this.routes){var b=this.routes[a];
21
+ this.route(a,b,this[b])}},_routeToRegExp:function(a){a=a.replace(o,"([^/]*)").replace(p,"(.*?)");return RegExp("^"+a+"$")},_extractParameters:function(a,b){return a.exec(b).slice(1)}});e.History=function(){this.handlers=[];this.fragment=this.getFragment();f.bindAll(this,"checkUrl")};var l=/^#*/;f.extend(e.History.prototype,{interval:50,getFragment:function(a){return(a||window.location).hash.replace(l,"")},start:function(){var a=document.documentMode;if(a=h.browser.msie&&(!a||a<=7))this.iframe=h('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo("body")[0].contentWindow;
22
+ "onhashchange"in window&&!a?h(window).bind("hashchange",this.checkUrl):setInterval(this.checkUrl,this.interval);return this.loadUrl()},route:function(a,b){this.handlers.push({route:a,callback:b})},checkUrl:function(){var a=this.getFragment();if(a==this.fragment&&this.iframe)a=this.getFragment(this.iframe.location);if(a==this.fragment||a==decodeURIComponent(this.fragment))return false;if(this.iframe)window.location.hash=this.iframe.location.hash=a;this.loadUrl()},loadUrl:function(){var a=this.fragment=
23
+ this.getFragment();return f.any(this.handlers,function(b){if(b.route.test(a)){b.callback(a);return true}})},saveLocation:function(a){a=(a||"").replace(l,"");if(this.fragment!=a){window.location.hash=this.fragment=a;if(this.iframe&&a!=this.getFragment(this.iframe.location)){this.iframe.document.open().close();this.iframe.location.hash=a}}}});e.View=function(a){this._configure(a||{});this._ensureElement();this.delegateEvents();this.initialize(a)};var q=/^(\w+)\s*(.*)$/;f.extend(e.View.prototype,e.Events,
24
+ {tagName:"div",$:function(a){return h(a,this.el)},initialize:function(){},render:function(){return this},remove:function(){h(this.el).remove();return this},make:function(a,b,c){a=document.createElement(a);b&&h(a).attr(b);c&&h(a).html(c);return a},delegateEvents:function(a){if(a||(a=this.events)){h(this.el).unbind();for(var b in a){var c=a[b],d=b.match(q),g=d[1];d=d[2];c=f.bind(this[c],this);d===""?h(this.el).bind(g,c):h(this.el).delegate(d,g,c)}}},_configure:function(a){if(this.options)a=f.extend({},
25
+ this.options,a);if(a.model)this.model=a.model;if(a.collection)this.collection=a.collection;if(a.el)this.el=a.el;if(a.id)this.id=a.id;if(a.className)this.className=a.className;if(a.tagName)this.tagName=a.tagName;this.options=a},_ensureElement:function(){if(!this.el){var a={};if(this.id)a.id=this.id;if(this.className)a["class"]=this.className;this.el=this.make(this.tagName,a)}}});var m=function(a,b){var c=r(this,a,b);c.extend=m;return c};e.Model.extend=e.Collection.extend=e.Controller.extend=e.View.extend=
26
+ m;var s={create:"POST",update:"PUT","delete":"DELETE",read:"GET"};e.sync=function(a,b,c,d){var g=s[a];a=a==="create"||a==="update"?JSON.stringify(b.toJSON()):null;b={url:k(b),type:g,contentType:"application/json",data:a,dataType:"json",processData:false,success:c,error:d};if(e.emulateJSON){b.contentType="application/x-www-form-urlencoded";b.processData=true;b.data=a?{model:a}:{}}if(e.emulateHTTP)if(g==="PUT"||g==="DELETE"){if(e.emulateJSON)b.data._method=g;b.type="POST";b.beforeSend=function(i){i.setRequestHeader("X-HTTP-Method-Override",
27
+ g)}}h.ajax(b)};var n=function(){},r=function(a,b,c){var d;d=b&&b.hasOwnProperty("constructor")?b.constructor:function(){return a.apply(this,arguments)};n.prototype=a.prototype;d.prototype=new n;b&&f.extend(d.prototype,b);c&&f.extend(d,c);d.prototype.constructor=d;d.__super__=a.prototype;return d},k=function(a){if(!(a&&a.url))throw Error("A 'url' property or function must be specified");return f.isFunction(a.url)?a.url():a.url},j=function(a,b,c){return function(d){a?a(b,d):b.trigger("error",b,d,c)}}})();
@@ -0,0 +1,401 @@
1
+ /*!
2
+ ICanHaz.js version 0.9 -- by @HenrikJoreteg
3
+ More info at: http://icanhazjs.com
4
+ */
5
+ (function ($) {
6
+ /*!
7
+ mustache.js -- Logic-less templates in JavaScript
8
+
9
+ by @janl (MIT Licensed, https://github.com/janl/mustache.js/blob/master/LICENSE).
10
+
11
+ See http://mustache.github.com/ for more info.
12
+ */
13
+
14
+ var Mustache = function() {
15
+ var Renderer = function() {};
16
+
17
+ Renderer.prototype = {
18
+ otag: "{{",
19
+ ctag: "}}",
20
+ pragmas: {},
21
+ buffer: [],
22
+ pragmas_implemented: {
23
+ "IMPLICIT-ITERATOR": true
24
+ },
25
+ context: {},
26
+
27
+ render: function(template, context, partials, in_recursion) {
28
+ // reset buffer & set context
29
+ if(!in_recursion) {
30
+ this.context = context;
31
+ this.buffer = []; // TODO: make this non-lazy
32
+ }
33
+
34
+ // fail fast
35
+ if(!this.includes("", template)) {
36
+ if(in_recursion) {
37
+ return template;
38
+ } else {
39
+ this.send(template);
40
+ return;
41
+ }
42
+ }
43
+
44
+ template = this.render_pragmas(template);
45
+ var html = this.render_section(template, context, partials);
46
+ if(in_recursion) {
47
+ return this.render_tags(html, context, partials, in_recursion);
48
+ }
49
+
50
+ this.render_tags(html, context, partials, in_recursion);
51
+ },
52
+
53
+ /*
54
+ Sends parsed lines
55
+ */
56
+ send: function(line) {
57
+ if(line != "") {
58
+ this.buffer.push(line);
59
+ }
60
+ },
61
+
62
+ /*
63
+ Looks for %PRAGMAS
64
+ */
65
+ render_pragmas: function(template) {
66
+ // no pragmas
67
+ if(!this.includes("%", template)) {
68
+ return template;
69
+ }
70
+
71
+ var that = this;
72
+ var regex = new RegExp(this.otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" +
73
+ this.ctag);
74
+ return template.replace(regex, function(match, pragma, options) {
75
+ if(!that.pragmas_implemented[pragma]) {
76
+ throw({message:
77
+ "This implementation of mustache doesn't understand the '" +
78
+ pragma + "' pragma"});
79
+ }
80
+ that.pragmas[pragma] = {};
81
+ if(options) {
82
+ var opts = options.split("=");
83
+ that.pragmas[pragma][opts[0]] = opts[1];
84
+ }
85
+ return "";
86
+ // ignore unknown pragmas silently
87
+ });
88
+ },
89
+
90
+ /*
91
+ Tries to find a partial in the curent scope and render it
92
+ */
93
+ render_partial: function(name, context, partials) {
94
+ name = this.trim(name);
95
+ if(!partials || partials[name] === undefined) {
96
+ throw({message: "unknown_partial '" + name + "'"});
97
+ }
98
+ if(typeof(context[name]) != "object") {
99
+ return this.render(partials[name], context, partials, true);
100
+ }
101
+ return this.render(partials[name], context[name], partials, true);
102
+ },
103
+
104
+ /*
105
+ Renders inverted (^) and normal (#) sections
106
+ */
107
+ render_section: function(template, context, partials) {
108
+ if(!this.includes("#", template) && !this.includes("^", template)) {
109
+ return template;
110
+ }
111
+
112
+ var that = this;
113
+ // CSW - Added "+?" so it finds the tighest bound, not the widest
114
+ var regex = new RegExp(this.otag + "(\\^|\\#)\\s*(.+)\\s*" + this.ctag +
115
+ "\n*([\\s\\S]+?)" + this.otag + "\\/\\s*\\2\\s*" + this.ctag +
116
+ "\\s*", "mg");
117
+
118
+ // for each {{#foo}}{{/foo}} section do...
119
+ return template.replace(regex, function(match, type, name, content) {
120
+ var value = that.find(name, context);
121
+ if(type == "^") { // inverted section
122
+ if(!value || that.is_array(value) && value.length === 0) {
123
+ // false or empty list, render it
124
+ return that.render(content, context, partials, true);
125
+ } else {
126
+ return "";
127
+ }
128
+ } else if(type == "#") { // normal section
129
+ if(that.is_array(value)) { // Enumerable, Let's loop!
130
+ return that.map(value, function(row) {
131
+ return that.render(content, that.create_context(row),
132
+ partials, true);
133
+ }).join("");
134
+ } else if(that.is_object(value)) { // Object, Use it as subcontext!
135
+ return that.render(content, that.create_context(value),
136
+ partials, true);
137
+ } else if(typeof value === "function") {
138
+ // higher order section
139
+ return value.call(context, content, function(text) {
140
+ return that.render(text, context, partials, true);
141
+ });
142
+ } else if(value) { // boolean section
143
+ return that.render(content, context, partials, true);
144
+ } else {
145
+ return "";
146
+ }
147
+ }
148
+ });
149
+ },
150
+
151
+ /*
152
+ Replace {{foo}} and friends with values from our view
153
+ */
154
+ render_tags: function(template, context, partials, in_recursion) {
155
+ // tit for tat
156
+ var that = this;
157
+
158
+ var new_regex = function() {
159
+ return new RegExp(that.otag + "(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?" +
160
+ that.ctag + "+", "g");
161
+ };
162
+
163
+ var regex = new_regex();
164
+ var tag_replace_callback = function(match, operator, name) {
165
+ switch(operator) {
166
+ case "!": // ignore comments
167
+ return "";
168
+ case "=": // set new delimiters, rebuild the replace regexp
169
+ that.set_delimiters(name);
170
+ regex = new_regex();
171
+ return "";
172
+ case ">": // render partial
173
+ return that.render_partial(name, context, partials);
174
+ case "{": // the triple mustache is unescaped
175
+ return that.find(name, context);
176
+ default: // escape the value
177
+ return that.escape(that.find(name, context));
178
+ }
179
+ };
180
+ var lines = template.split("\n");
181
+ for(var i = 0; i < lines.length; i++) {
182
+ lines[i] = lines[i].replace(regex, tag_replace_callback, this);
183
+ if(!in_recursion) {
184
+ this.send(lines[i]);
185
+ }
186
+ }
187
+
188
+ if(in_recursion) {
189
+ return lines.join("\n");
190
+ }
191
+ },
192
+
193
+ set_delimiters: function(delimiters) {
194
+ var dels = delimiters.split(" ");
195
+ this.otag = this.escape_regex(dels[0]);
196
+ this.ctag = this.escape_regex(dels[1]);
197
+ },
198
+
199
+ escape_regex: function(text) {
200
+ // thank you Simon Willison
201
+ if(!arguments.callee.sRE) {
202
+ var specials = [
203
+ '/', '.', '*', '+', '?', '|',
204
+ '(', ')', '[', ']', '{', '}', '\\'
205
+ ];
206
+ arguments.callee.sRE = new RegExp(
207
+ '(\\' + specials.join('|\\') + ')', 'g'
208
+ );
209
+ }
210
+ return text.replace(arguments.callee.sRE, '\\$1');
211
+ },
212
+
213
+ /*
214
+ find `name` in current `context`. That is find me a value
215
+ from the view object
216
+ */
217
+ find: function(name, context) {
218
+ name = this.trim(name);
219
+
220
+ // Checks whether a value is thruthy or false or 0
221
+ function is_kinda_truthy(bool) {
222
+ return bool === false || bool === 0 || bool;
223
+ }
224
+
225
+ var value;
226
+ if(is_kinda_truthy(context[name])) {
227
+ value = context[name];
228
+ } else if(is_kinda_truthy(this.context[name])) {
229
+ value = this.context[name];
230
+ }
231
+
232
+ if(typeof value === "function") {
233
+ return value.apply(context);
234
+ }
235
+ if(value !== undefined) {
236
+ return value;
237
+ }
238
+ // silently ignore unkown variables
239
+ return "";
240
+ },
241
+
242
+ // Utility methods
243
+
244
+ /* includes tag */
245
+ includes: function(needle, haystack) {
246
+ return haystack.indexOf(this.otag + needle) != -1;
247
+ },
248
+
249
+ /*
250
+ Does away with nasty characters
251
+ */
252
+ escape: function(s) {
253
+ s = String(s === null ? "" : s);
254
+ return s.replace(/&(?!\w+;)|["<>\\]/g, function(s) {
255
+ switch(s) {
256
+ case "&": return "&amp;";
257
+ case "\\": return "\\\\";
258
+ case '"': return '\"';
259
+ case "<": return "&lt;";
260
+ case ">": return "&gt;";
261
+ default: return s;
262
+ }
263
+ });
264
+ },
265
+
266
+ // by @langalex, support for arrays of strings
267
+ create_context: function(_context) {
268
+ if(this.is_object(_context)) {
269
+ return _context;
270
+ } else {
271
+ var iterator = ".";
272
+ if(this.pragmas["IMPLICIT-ITERATOR"]) {
273
+ iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator;
274
+ }
275
+ var ctx = {};
276
+ ctx[iterator] = _context;
277
+ return ctx;
278
+ }
279
+ },
280
+
281
+ is_object: function(a) {
282
+ return a && typeof a == "object";
283
+ },
284
+
285
+ is_array: function(a) {
286
+ return Object.prototype.toString.call(a) === '[object Array]';
287
+ },
288
+
289
+ /*
290
+ Gets rid of leading and trailing whitespace
291
+ */
292
+ trim: function(s) {
293
+ return s.replace(/^\s*|\s*$/g, "");
294
+ },
295
+
296
+ /*
297
+ Why, why, why? Because IE. Cry, cry cry.
298
+ */
299
+ map: function(array, fn) {
300
+ if (typeof array.map == "function") {
301
+ return array.map(fn);
302
+ } else {
303
+ var r = [];
304
+ var l = array.length;
305
+ for(var i = 0; i < l; i++) {
306
+ r.push(fn(array[i]));
307
+ }
308
+ return r;
309
+ }
310
+ }
311
+ };
312
+
313
+ return({
314
+ name: "mustache.js",
315
+ version: "0.3.0",
316
+
317
+ /*
318
+ Turns a template and view into HTML
319
+ */
320
+ to_html: function(template, view, partials, send_fun) {
321
+ var renderer = new Renderer();
322
+ if(send_fun) {
323
+ renderer.send = send_fun;
324
+ }
325
+ renderer.render(template, view, partials);
326
+ if(!send_fun) {
327
+ return renderer.buffer.join("\n");
328
+ }
329
+ }
330
+ });
331
+ }();/*!
332
+ ICanHaz.js -- by @HenrikJoreteg
333
+ */
334
+ /*global jQuery */
335
+ function ICanHaz() {
336
+ var self = this;
337
+ self.VERSION = "0.9";
338
+ self.templates = {};
339
+ self.partials = {};
340
+
341
+ // public function for adding templates
342
+ // We're enforcing uniqueness to avoid accidental template overwrites.
343
+ // If you want a different template, it should have a different name.
344
+ self.addTemplate = function (name, templateString) {
345
+ if (self[name]) throw "Invalid name: " + name + ".";
346
+ if (self.templates[name]) throw "Template \" + name + \" exists";
347
+
348
+ self.templates[name] = templateString;
349
+ self[name] = function (data, raw) {
350
+ data = data || {};
351
+ var result = Mustache.to_html(self.templates[name], data, self.partials);
352
+ return raw ? result : $(result);
353
+ };
354
+ };
355
+
356
+ // public function for adding partials
357
+ self.addPartial = function (name, templateString) {
358
+ if (self.partials[name]) {
359
+ throw "Partial \" + name + \" exists";
360
+ } else {
361
+ self.partials[name] = templateString;
362
+ }
363
+ };
364
+
365
+ // grabs templates from the DOM and caches them.
366
+ // Loop through and add templates.
367
+ // Whitespace at beginning and end of all templates inside <script> tags will
368
+ // be trimmed. If you want whitespace around a partial, add it in the parent,
369
+ // not the partial. Or do it explicitly using <br/> or &nbsp;
370
+ self.grabTemplates = function () {
371
+ $('script[type="text/html"]').each(function (a, b) {
372
+ var script = $((typeof a === 'number') ? b : a), // Zepto doesn't bind this
373
+ text = (''.trim) ? script.html().trim() : $.trim(script.html());
374
+
375
+ self[script.hasClass('partial') ? 'addPartial' : 'addTemplate'](script.attr('id'), text);
376
+ script.remove();
377
+ });
378
+ };
379
+
380
+ // clears all retrieval functions and empties caches
381
+ self.clearAll = function () {
382
+ for (var key in self.templates) {
383
+ delete self[key];
384
+ }
385
+ self.templates = {};
386
+ self.partials = {};
387
+ };
388
+
389
+ self.refresh = function () {
390
+ self.clearAll();
391
+ self.grabTemplates();
392
+ };
393
+ }
394
+
395
+ window.ich = new ICanHaz();
396
+
397
+ // init itself on document ready
398
+ $(function () {
399
+ ich.grabTemplates();
400
+ });
401
+ })(window.jQuery || window.Zepto);
@@ -0,0 +1,9 @@
1
+ (function(i){var n=function(){var f=function(){};f.prototype={otag:"{{",ctag:"}}",pragmas:{},buffer:[],pragmas_implemented:{"IMPLICIT-ITERATOR":true},context:{},render:function(a,b,c,d){if(!d){this.context=b;this.buffer=[]}if(!this.includes("",a))if(d)return a;else{this.send(a);return}a=this.render_pragmas(a);a=this.render_section(a,b,c);if(d)return this.render_tags(a,b,c,d);this.render_tags(a,b,c,d)},send:function(a){a!=""&&this.buffer.push(a)},render_pragmas:function(a){if(!this.includes("%",a))return a;
2
+ var b=this;return a.replace(RegExp(this.otag+"%([\\w-]+) ?([\\w]+=[\\w]+)?"+this.ctag),function(c,d,e){if(!b.pragmas_implemented[d])throw{message:"This implementation of mustache doesn't understand the '"+d+"' pragma"};b.pragmas[d]={};if(e){c=e.split("=");b.pragmas[d][c[0]]=c[1]}return""})},render_partial:function(a,b,c){a=this.trim(a);if(!c||c[a]===undefined)throw{message:"unknown_partial '"+a+"'"};if(typeof b[a]!="object")return this.render(c[a],b,c,true);return this.render(c[a],b[a],c,true)},render_section:function(a,
3
+ b,c){if(!this.includes("#",a)&&!this.includes("^",a))return a;var d=this;return a.replace(RegExp(this.otag+"(\\^|\\#)\\s*(.+)\\s*"+this.ctag+"\n*([\\s\\S]+?)"+this.otag+"\\/\\s*\\2\\s*"+this.ctag+"\\s*","mg"),function(e,j,k,h){e=d.find(k,b);if(j=="^")return!e||d.is_array(e)&&e.length===0?d.render(h,b,c,true):"";else if(j=="#")return d.is_array(e)?d.map(e,function(g){return d.render(h,d.create_context(g),c,true)}).join(""):d.is_object(e)?d.render(h,d.create_context(e),c,true):typeof e==="function"?
4
+ e.call(b,h,function(g){return d.render(g,b,c,true)}):e?d.render(h,b,c,true):""})},render_tags:function(a,b,c,d){var e=this,j=function(){return RegExp(e.otag+"(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?"+e.ctag+"+","g")},k=j(),h=function(o,m,l){switch(m){case "!":return"";case "=":e.set_delimiters(l);k=j();return"";case ">":return e.render_partial(l,b,c);case "{":return e.find(l,b);default:return e.escape(e.find(l,b))}};a=a.split("\n");for(var g=0;g<a.length;g++){a[g]=a[g].replace(k,h,this);d||this.send(a[g])}if(d)return a.join("\n")},
5
+ set_delimiters:function(a){a=a.split(" ");this.otag=this.escape_regex(a[0]);this.ctag=this.escape_regex(a[1])},escape_regex:function(a){if(!arguments.callee.sRE)arguments.callee.sRE=RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\)","g");return a.replace(arguments.callee.sRE,"\\$1")},find:function(a,b){a=this.trim(a);var c;if(b[a]===false||b[a]===0||b[a])c=b[a];else if(this.context[a]===false||this.context[a]===0||this.context[a])c=this.context[a];if(typeof c==="function")return c.apply(b);
6
+ if(c!==undefined)return c;return""},includes:function(a,b){return b.indexOf(this.otag+a)!=-1},escape:function(a){a=String(a===null?"":a);return a.replace(/&(?!\w+;)|["<>\\]/g,function(b){switch(b){case "&":return"&amp;";case "\\":return"\\\\";case '"':return'"';case "<":return"&lt;";case ">":return"&gt;";default:return b}})},create_context:function(a){if(this.is_object(a))return a;else{var b=".";if(this.pragmas["IMPLICIT-ITERATOR"])b=this.pragmas["IMPLICIT-ITERATOR"].iterator;var c={};c[b]=a;return c}},
7
+ is_object:function(a){return a&&typeof a=="object"},is_array:function(a){return Object.prototype.toString.call(a)==="[object Array]"},trim:function(a){return a.replace(/^\s*|\s*$/g,"")},map:function(a,b){if(typeof a.map=="function")return a.map(b);else{for(var c=[],d=a.length,e=0;e<d;e++)c.push(b(a[e]));return c}}};return{name:"mustache.js",version:"0.3.0",to_html:function(a,b,c,d){var e=new f;if(d)e.send=d;e.render(a,b,c);if(!d)return e.buffer.join("\n")}}}();window.ich=new function(){var f=this;
8
+ f.VERSION="0.9";f.templates={};f.partials={};f.addTemplate=function(a,b){if(f[a])throw"Invalid name: "+a+".";if(f.templates[a])throw'Template " + name + " exists';f.templates[a]=b;f[a]=function(c,d){c=c||{};var e=n.to_html(f.templates[a],c,f.partials);return d?e:i(e)}};f.addPartial=function(a,b){if(f.partials[a])throw'Partial " + name + " exists';else f.partials[a]=b};f.grabTemplates=function(){i('script[type="text/html"]').each(function(a,b){var c=i(typeof a==="number"?b:a),d="".trim?c.html().trim():
9
+ i.trim(c.html());f[c.hasClass("partial")?"addPartial":"addTemplate"](c.attr("id"),d);c.remove()})};f.clearAll=function(){for(var a in f.templates)delete f[a];f.templates={};f.partials={}};f.refresh=function(){f.clearAll();f.grabTemplates()}};i(function(){ich.grabTemplates()})})(window.jQuery||window.Zepto);