backbonejs-rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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);