jim 0.1.2 → 0.2.0

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.
Files changed (72) hide show
  1. data/HISTORY +28 -0
  2. data/README.rdoc +1 -1
  3. data/Rakefile +2 -1
  4. data/jim.gemspec +67 -9
  5. data/lib/jim/bundler.rb +14 -11
  6. data/lib/jim/cli.rb +51 -9
  7. data/lib/jim/index.rb +3 -7
  8. data/lib/jim/installer.rb +140 -22
  9. data/lib/jim/templates/commands +21 -6
  10. data/lib/jim/version_parser.rb +2 -3
  11. data/lib/jim.rb +19 -2
  12. data/test/fixtures/jimfile +3 -3
  13. data/test/fixtures/sammy-0.5.0/HISTORY.md +135 -0
  14. data/test/fixtures/sammy-0.5.0/LICENSE +22 -0
  15. data/test/fixtures/sammy-0.5.0/README.md +81 -0
  16. data/test/fixtures/sammy-0.5.0/Rakefile +174 -0
  17. data/test/fixtures/sammy-0.5.0/examples/backend/README.md +23 -0
  18. data/test/fixtures/sammy-0.5.0/examples/backend/Rakefile +15 -0
  19. data/test/fixtures/sammy-0.5.0/examples/backend/app.rb +17 -0
  20. data/test/fixtures/sammy-0.5.0/examples/backend/app.ru +3 -0
  21. data/test/fixtures/sammy-0.5.0/examples/backend/public/javascripts/app.js +106 -0
  22. data/test/fixtures/sammy-0.5.0/examples/backend/public/javascripts/jquery.cloudkit.js +840 -0
  23. data/test/fixtures/sammy-0.5.0/examples/backend/public/javascripts/jquery.js +19 -0
  24. data/test/fixtures/sammy-0.5.0/examples/backend/public/javascripts/sammy.js +1013 -0
  25. data/test/fixtures/sammy-0.5.0/examples/backend/public/templates/index.html.erb +11 -0
  26. data/test/fixtures/sammy-0.5.0/examples/backend/public/templates/task.html.erb +4 -0
  27. data/test/fixtures/sammy-0.5.0/examples/backend/public/templates/task_details.html.erb +4 -0
  28. data/test/fixtures/sammy-0.5.0/examples/backend/views/app.sass +63 -0
  29. data/test/fixtures/sammy-0.5.0/examples/backend/views/index.haml +18 -0
  30. data/test/fixtures/sammy-0.5.0/examples/form_handling/files/form.html +12 -0
  31. data/test/fixtures/sammy-0.5.0/examples/form_handling/index.html +65 -0
  32. data/test/fixtures/sammy-0.5.0/examples/hello_world/index.html +50 -0
  33. data/test/fixtures/sammy-0.5.0/examples/location_override/README.md +15 -0
  34. data/test/fixtures/sammy-0.5.0/examples/location_override/data.html +110 -0
  35. data/test/fixtures/sammy-0.5.0/examples/location_override/index.html +79 -0
  36. data/test/fixtures/sammy-0.5.0/examples/location_override/test.html +121 -0
  37. data/test/fixtures/sammy-0.5.0/lib/min/sammy-0.5.0.min.js +5 -0
  38. data/test/fixtures/sammy-0.5.0/lib/min/sammy-lastest.min.js +5 -0
  39. data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.cache.js +117 -0
  40. data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.haml.js +539 -0
  41. data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.json.js +362 -0
  42. data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.mustache.js +415 -0
  43. data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.nested_params.js +118 -0
  44. data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.storage.js +515 -0
  45. data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.template.js +117 -0
  46. data/test/fixtures/sammy-0.5.0/lib/sammy.js +1367 -0
  47. data/test/fixtures/sammy-0.5.0/test/fixtures/partial +1 -0
  48. data/test/fixtures/sammy-0.5.0/test/fixtures/partial.html +1 -0
  49. data/test/fixtures/sammy-0.5.0/test/fixtures/partial.noengine +1 -0
  50. data/test/fixtures/sammy-0.5.0/test/fixtures/partial.template +1 -0
  51. data/test/fixtures/sammy-0.5.0/test/index.html +84 -0
  52. data/test/fixtures/sammy-0.5.0/test/test_sammy_application.js +953 -0
  53. data/test/fixtures/sammy-0.5.0/test/test_sammy_event_context.js +252 -0
  54. data/test/fixtures/sammy-0.5.0/test/test_sammy_location_proxy.js +91 -0
  55. data/test/fixtures/sammy-0.5.0/test/test_sammy_plugins.js +296 -0
  56. data/test/fixtures/sammy-0.5.0/test/test_sammy_storage.js +175 -0
  57. data/test/fixtures/sammy-0.5.0/test/test_server +27 -0
  58. data/test/fixtures/sammy-0.5.0/vendor/jquery-1.4.1.js +6078 -0
  59. data/test/fixtures/sammy-0.5.0/vendor/jquery-1.4.1.min.js +152 -0
  60. data/test/fixtures/sammy-0.5.0/vendor/jsdoc/doc.haml +58 -0
  61. data/test/fixtures/sammy-0.5.0/vendor/jsdoc/jsdoc.rb +143 -0
  62. data/test/fixtures/sammy-0.5.0/vendor/jslitmus.js +670 -0
  63. data/test/fixtures/sammy-0.5.0/vendor/qunit/qunit.css +119 -0
  64. data/test/fixtures/sammy-0.5.0/vendor/qunit/qunit.js +1043 -0
  65. data/test/fixtures/sammy-0.5.0/vendor/qunit-spec.js +127 -0
  66. data/test/helper.rb +23 -3
  67. data/test/test_jim_bundler.rb +9 -8
  68. data/test/test_jim_cli.rb +21 -12
  69. data/test/test_jim_installer.rb +152 -35
  70. data/test/test_jim_version_parser.rb +4 -0
  71. metadata +117 -27
  72. data/.document +0 -5
@@ -0,0 +1,515 @@
1
+ (function($) {
2
+
3
+ Sammy = Sammy || {};
4
+
5
+ // Sammy.Store is an abstract adapter class that wraps the multitude of in
6
+ // browser data storage into a single common set of methods for storing and
7
+ // retreiving data. The JSON library is used (through the inclusion of the
8
+ // Sammy.JSON) plugin, to automatically convert objects back and forth from
9
+ // stored strings.
10
+ //
11
+ // Sammy.Store can be used directly, but within a Sammy.Application it is much
12
+ // easier to use the <tt>Sammy.Storage</tt> plugin and its helper methods.
13
+ //
14
+ // Sammy.Store also supports the KVO pattern, by firing DOM/jQuery Events when
15
+ // a key is set.
16
+ //
17
+ // === Example
18
+ //
19
+ // // create a new store named 'mystore', tied to the #main element, using HTML5 localStorage
20
+ // // Note: localStorage only works on browsers that support it
21
+ // var store = new Sammy.Store({name: 'mystore', element: '#element', type: 'local'});
22
+ // store.set('foo', 'bar');
23
+ // store.get('foo'); //=> 'bar'
24
+ // store.set('json', {obj: 'this is an obj'});
25
+ // store.get('json'); //=> {obj: 'this is an obj'}
26
+ // store.keys(); //=> ['foo','json']
27
+ // store.clear('foo');
28
+ // store.keys(); //=> ['json']
29
+ // store.clearAll();
30
+ // store.keys(); //=> []
31
+ //
32
+ // === Arguments
33
+ //
34
+ // The constructor takes a single argument which is a Object containing these possible options.
35
+ //
36
+ // +name+:: The name/namespace of this store. Stores are unique by name/type. (default 'store')
37
+ // +element+:: A selector for the element that the store is bound to. (default 'body')
38
+ // +type+:: The type of storage/proxy to use (default 'memory')
39
+ //
40
+ // Extra options are passed to the storage constructor.
41
+ // Sammy.Store supports the following methods of storage:
42
+ //
43
+ // +memory+:: Basic object storage
44
+ // +data+:: jQuery.data DOM Storage
45
+ // +cookie+:: Access to document.cookie. Limited to 2K
46
+ // +local+:: HTML5 DOM localStorage, browswer support is currently limited.
47
+ // +session+:: HTML5 DOM sessionStorage, browswer support is currently limited.
48
+ //
49
+ Sammy.Store = function(options) {
50
+ this.options = options || {};
51
+ this.name = this.options.name || 'store';
52
+ this.element = this.options.element || 'body';
53
+ this.$element = $(this.element);
54
+ this.type = this.options.type || 'memory';
55
+ this.meta_key = this.options.meta_key || '__keys__';
56
+ this.storage = new Sammy.Store[Sammy.Store.stores[this.type]](this.name, this.element, this.options);
57
+ };
58
+
59
+ Sammy.Store.stores = {
60
+ 'memory': 'Memory',
61
+ 'data': 'Data',
62
+ 'local': 'LocalStorage',
63
+ 'session': 'SessionStorage',
64
+ 'cookie': 'Cookie'
65
+ };
66
+
67
+ $.extend(Sammy.Store.prototype, {
68
+ // Checks for the availability of the current storage type in the current browser/config.
69
+ isAvailable: function() {
70
+ if ($.isFunction(this.storage.isAvailable)) {
71
+ return this.storage.isAvailable();
72
+ } else {
73
+ true;
74
+ }
75
+ },
76
+ // Checks for the existance of <tt>key</tt> in the current store. Returns a boolean.
77
+ exists: function(key) {
78
+ return this.storage.exists(key);
79
+ },
80
+ // Sets the value of <tt>key<tt> with <tt>value</tt>. If <tt>value<tt> is an
81
+ // object, it is turned to and stored as a string with <tt>JSON.stringify</tt>.
82
+ // It also tries to conform to the KVO pattern triggering jQuery events on the
83
+ // element that the store is bound to.
84
+ //
85
+ // === Example
86
+ //
87
+ // var store = new Sammy.Store({name: 'kvo'});
88
+ // $('body').bind('set-kvo.foo', function() {
89
+ // alert('foo changed!')
90
+ // });
91
+ // store.set('foo', 'bar'); // alerted: foo changed!
92
+ //
93
+ set: function(key, value) {
94
+ var string_value = (typeof value == 'string') ? value : JSON.stringify(value);
95
+ key = key.toString();
96
+ this.storage.set(key, string_value);
97
+ if (key != this.meta_key) {
98
+ this._addKey(key);
99
+ this.$element.trigger('set-' + this.name + '.' + key, [key, value]);
100
+ };
101
+ return string_value;
102
+ },
103
+ // Returns the set value at <tt>key</tt>, parsing with <tt>JSON.parse</tt> and
104
+ // turning into an object if possible
105
+ get: function(key) {
106
+ var value = this.storage.get(key);
107
+ if (typeof value == 'undefined' || value == null || value == '') {
108
+ return value;
109
+ }
110
+ try {
111
+ return JSON.parse(value);
112
+ } catch(e) {
113
+ return value;
114
+ }
115
+ },
116
+ // Removes the value at <tt>key</tt> from the current store
117
+ clear: function(key) {
118
+ this._removeKey(key);
119
+ return this.storage.clear(key);
120
+ },
121
+ // Clears all the values for the current store.
122
+ clearAll: function() {
123
+ var self = this;
124
+ $.each(this.keys(), function(i, key) {
125
+ self.clear(key);
126
+ });
127
+ },
128
+ // Returns the all the keys set for the current store as an array.
129
+ // Internally Sammy.Store keeps this array in a 'meta_key' for easy access.
130
+ keys: function() {
131
+ return this.get(this.meta_key) || [];
132
+ },
133
+ // Returns the value at <tt>key</tt> if set, otherwise, runs the callback
134
+ // and sets the value to the value returned in the callback.
135
+ //
136
+ // === Example
137
+ //
138
+ // var store = new Sammy.Store;
139
+ // store.exists('foo'); //=> false
140
+ // store.fetch('foo', function() {
141
+ // return 'bar!';
142
+ // }); //=> 'bar!'
143
+ // store.get('foo') //=> 'bar!'
144
+ // store.fetch('foo', function() {
145
+ // return 'baz!';
146
+ // }); //=> 'bar!
147
+ //
148
+ fetch: function(key, callback) {
149
+ if (!this.exists(key)) {
150
+ return this.set(key, callback.apply(this));
151
+ } else {
152
+ return this.get(key);
153
+ }
154
+ },
155
+ // loads the response of a request to <tt>path</tt> into <tt>key</tt>.
156
+ //
157
+ // === Example
158
+ //
159
+ // In /mytemplate.tpl:
160
+ //
161
+ // My Template
162
+ //
163
+ // In app.js:
164
+ //
165
+ // var store = new Sammy.Store;
166
+ // store.load('mytemplate', '/mytemplate.tpl', function() {
167
+ // s.get('mytemplate') //=> My Template
168
+ // });
169
+ //
170
+ load: function(key, path, callback) {
171
+ var s = this;
172
+ $.get(path, function(response) {
173
+ s.set(key, response);
174
+ if (callback) { callback.apply(this, [response]); }
175
+ });
176
+ },
177
+ _addKey: function(key) {
178
+ var keys = this.keys();
179
+ if ($.inArray(key, keys) == -1) { keys.push(key); }
180
+ this.set(this.meta_key, keys);
181
+ },
182
+ _removeKey: function(key) {
183
+ var keys = this.keys();
184
+ var index = $.inArray(key, keys);
185
+ if (index != -1) { keys.splice(index, 1); }
186
+ this.set(this.meta_key, keys);
187
+ }
188
+ });
189
+
190
+ // Tests if the type of storage is available/works in the current browser/config.
191
+ // Especially useful for testing the availability of the awesome, but not widely
192
+ // supported HTML5 DOM storage
193
+ Sammy.Store.isAvailable = function(type) {
194
+ try {
195
+ return Sammy.Store[Sammy.Store.stores[type]].prototype.isAvailable();
196
+ } catch(e) {
197
+ return false;
198
+ }
199
+ };
200
+
201
+ // Memory ('memory') is the basic/default store. It stores data in a global
202
+ // JS object. Data is lost on refresh.
203
+ Sammy.Store.Memory = function(name, element) {
204
+ this.name = name;
205
+ this.element = element;
206
+ this.namespace = [this.element, this.name].join('.');
207
+ Sammy.Store.Memory.store = Sammy.Store.Memory.store || {};
208
+ Sammy.Store.Memory.store[this.namespace] = Sammy.Store.Memory.store[this.namespace] || {};
209
+ this.store = Sammy.Store.Memory.store[this.namespace];
210
+ };
211
+ $.extend(Sammy.Store.Memory.prototype, {
212
+ isAvailable: function() { return true; },
213
+ exists: function(key) {
214
+ return (typeof this.store[key] != "undefined");
215
+ },
216
+ set: function(key, value) {
217
+ return this.store[key] = value;
218
+ },
219
+ get: function(key) {
220
+ return this.store[key];
221
+ },
222
+ clear: function(key) {
223
+ delete this.store[key];
224
+ }
225
+ });
226
+
227
+ // Data ('data') stores objects using the jQuery.data() methods. This has the advantadge
228
+ // of scoping the data to the specific element. Like the 'memory' store its data
229
+ // will only last for the length of the current request (data is lost on refresh/etc).
230
+ Sammy.Store.Data = function(name, element) {
231
+ this.name = name;
232
+ this.element = element;
233
+ this.$element = $(element);
234
+ };
235
+ $.extend(Sammy.Store.Data.prototype, {
236
+ isAvailable: function() { return true; },
237
+ exists: function(key) {
238
+ return (typeof this.$element.data(this._key(key)) != "undefined");
239
+ },
240
+ set: function(key, value) {
241
+ return this.$element.data(this._key(key), value);
242
+ },
243
+ get: function(key) {
244
+ return this.$element.data(this._key(key));
245
+ },
246
+ clear: function(key) {
247
+ this.$element.removeData(this._key(key));
248
+ },
249
+ _key: function(key) {
250
+ return ['store', this.name, key].join('.');
251
+ }
252
+ });
253
+
254
+ // LocalStorage ('local') makes use of HTML5 DOM Storage, and the window.localStorage
255
+ // object. The great advantage of this method is that data will persist beyond
256
+ // the current request. It can be considered a pretty awesome replacement for
257
+ // cookies accessed via JS. The great disadvantage, though, is its only available
258
+ // on the latest and greatest browsers.
259
+ //
260
+ // For more info on DOM Storage:
261
+ // [https://developer.mozilla.org/en/DOM/Storage]
262
+ // [http://www.w3.org/TR/2009/WD-webstorage-20091222/]
263
+ //
264
+ Sammy.Store.LocalStorage = function(name, element) {
265
+ this.name = name;
266
+ this.element = element;
267
+ };
268
+ $.extend(Sammy.Store.LocalStorage.prototype, {
269
+ isAvailable: function() {
270
+ return ('localStorage' in window) && (window.location.protocol != 'file:');
271
+ },
272
+ exists: function(key) {
273
+ return (this.get(key) != null);
274
+ },
275
+ set: function(key, value) {
276
+ return window.localStorage.setItem(this._key(key), value);
277
+ },
278
+ get: function(key) {
279
+ return window.localStorage.getItem(this._key(key));
280
+ },
281
+ clear: function(key) {
282
+ window.localStorage.removeItem(this._key(key));;
283
+ },
284
+ _key: function(key) {
285
+ return ['store', this.element, this.name, key].join('.');
286
+ }
287
+ });
288
+
289
+ // .SessionStorage ('session') is similar to LocalStorage (part of the same API)
290
+ // and shares similar browser support/availability. The difference is that
291
+ // SessionStorage is only persistant through the current 'session' which is defined
292
+ // as the length that the current window is open. This means that data will survive
293
+ // refreshes but not close/open or multiple windows/tabs. For more info, check out
294
+ // the <tt>LocalStorage</tt> documentation and links.
295
+ Sammy.Store.SessionStorage = function(name, element) {
296
+ this.name = name;
297
+ this.element = element;
298
+ };
299
+ $.extend(Sammy.Store.SessionStorage.prototype, {
300
+ isAvailable: function() {
301
+ return ('sessionStorage' in window);
302
+ },
303
+ exists: function(key) {
304
+ return (this.get(key) != null);
305
+ },
306
+ set: function(key, value) {
307
+ return window.sessionStorage.setItem(this._key(key), value);
308
+ },
309
+ get: function(key) {
310
+ return window.sessionStorage.getItem(this._key(key));
311
+ },
312
+ clear: function(key) {
313
+ window.sessionStorage.removeItem(this._key(key));;
314
+ },
315
+ _key: function(key) {
316
+ return ['store', this.element, this.name, key].join('.');
317
+ }
318
+ });
319
+
320
+ // .Cookie ('cookie') storage uses browser cookies to store data. JavaScript
321
+ // has access to a single document.cookie variable, which is limited to 2Kb in
322
+ // size. Cookies are also considered 'unsecure' as the data can be read easily
323
+ // by other sites/JS. Cookies do have the advantage, though, of being widely
324
+ // supported and persistent through refresh and close/open. Where available,
325
+ // HTML5 DOM Storage like LocalStorage and SessionStorage should be used.
326
+ //
327
+ // .Cookie can also take additional options:
328
+ // +expires_in+:: Number of seconds to keep the cookie alive (default 2 weeks).
329
+ // +path+:: The path to activate the current cookie for (default '/').
330
+ //
331
+ // For more information about document.cookie, check out the pre-eminint article
332
+ // by ppk: [http://www.quirksmode.org/js/cookies.html]
333
+ //
334
+ Sammy.Store.Cookie = function(name, element, options) {
335
+ this.name = name;
336
+ this.element = element;
337
+ this.options = options || {};
338
+ this.path = this.options.path || '/';
339
+ // set the expires in seconds or default 14 days
340
+ this.expires_in = this.options.expires_in || (14 * 24 * 60 * 60);
341
+ };
342
+ $.extend(Sammy.Store.Cookie.prototype, {
343
+ isAvailable: function() {
344
+ return ('cookie' in document) && (window.location.protocol != 'file:');
345
+ },
346
+ exists: function(key) {
347
+ return (this.get(key) != null);
348
+ },
349
+ set: function(key, value) {
350
+ return this._setCookie(key, value);
351
+ },
352
+ get: function(key) {
353
+ return this._getCookie(key);
354
+ },
355
+ clear: function(key) {
356
+ this._setCookie(key, "", -1);
357
+ },
358
+ _key: function(key) {
359
+ return ['store', this.element, this.name, key].join('.');
360
+ },
361
+ _getCookie: function(key) {
362
+ var escaped = this._key(key).replace(/(\.|\*|\(|\)|\[|\])/g, '\\$1');
363
+ var match = document.cookie.match("(^|;\\s)" + escaped + "=([^;]*)(;|$)")
364
+ return (match ? match[2] : null);
365
+ },
366
+ _setCookie: function(key, value, expires) {
367
+ if (!expires) { expires = (this.expires_in * 1000) }
368
+ var date = new Date();
369
+ date.setTime(date.getTime() + expires);
370
+ var set_cookie = [
371
+ this._key(key), "=", value,
372
+ "; expires=", date.toGMTString(),
373
+ "; path=", this.path
374
+ ].join('');
375
+ document.cookie = set_cookie;
376
+ }
377
+ });
378
+
379
+ // Sammy.Storage is a plugin that provides shortcuts for creating and using
380
+ // Sammy.Store objects. Once included it provides the <tt>store()</tt> app level
381
+ // and helper methods. Depends on Sammy.JSON (or json2.js).
382
+ Sammy.Storage = function(app) {
383
+ this.use(Sammy.JSON);
384
+
385
+ this.stores = this.stores || {};
386
+
387
+ // <tt>store()</tt> creates and looks up existing <tt>Sammy.Store</tt> objects
388
+ // for the current application. The first time used for a given <tt>'name'</tt>
389
+ // initializes a <tt>Sammy.Store</tt> and also creates a helper under the store's
390
+ // name.
391
+ //
392
+ // === Example
393
+ //
394
+ // var app = $.sammy(function() {
395
+ // this.use(Sammy.Storage);
396
+ //
397
+ // // initializes the store on app creation.
398
+ // this.store('mystore', {type: 'cookie'});
399
+ //
400
+ // this.get('#/', function() {
401
+ // // returns the Sammy.Store object
402
+ // this.store('mystore');
403
+ // // sets 'foo' to 'bar' using the shortcut/helper
404
+ // // equivilent to this.store('mystore').set('foo', 'bar');
405
+ // this.mystore('foo', 'bar');
406
+ // // returns 'bar'
407
+ // // equivilent to this.store('mystore').get('foo');
408
+ // this.mystore('foo');
409
+ // // returns 'baz!'
410
+ // // equivilent to:
411
+ // // this.store('mystore').fetch('foo!', function() {
412
+ // // return 'baz!';
413
+ // // })
414
+ // this.mystore('foo!', function() {
415
+ // return 'baz!';
416
+ // });
417
+ //
418
+ // this.clearMystore();
419
+ // // equivilent to:
420
+ // // this.store('mystore').clearAll()
421
+ // });
422
+ //
423
+ // });
424
+ //
425
+ // === Arguments
426
+ //
427
+ // +name+:: The name of the store and helper. the name must be unique per application.
428
+ // +options+:: A JS object of options that can be passed to the Store constuctor on initialization.
429
+ //
430
+ this.store = function(name, options) {
431
+ // if the store has not been initialized
432
+ if (typeof this.stores[name] == 'undefined') {
433
+ // create initialize the store
434
+ var clear_method_name = "clear" + name.substr(0,1).toUpperCase() + name.substr(1);
435
+ this.stores[name] = new Sammy.Store($.extend({
436
+ name: name,
437
+ element: this.element_selector
438
+ }, options || {}));
439
+ // app.name()
440
+ this[name] = function(key, value) {
441
+ if (typeof value == 'undefined') {
442
+ return this.stores[name].get(key);
443
+ } else if ($.isFunction(value)) {
444
+ return this.stores[name].fetch(key, value);
445
+ } else {
446
+ return this.stores[name].set(key, value)
447
+ }
448
+ };
449
+ // app.clearName();
450
+ this[clear_method_name] = function() {
451
+ return this.stores[name].clearAll();
452
+ }
453
+ // context.name()
454
+ this.helper(name, function() {
455
+ return this.app[name].apply(this.app, arguments);
456
+ });
457
+ // context.clearName();
458
+ this.helper(clear_method_name, function() {
459
+ return this.app[clear_method_name]();
460
+ });
461
+ }
462
+ return this.stores[name];
463
+ };
464
+
465
+ this.helpers({
466
+ store: function() {
467
+ return this.app.store.apply(this.app, arguments);
468
+ }
469
+ });
470
+ };
471
+
472
+ // Sammy.Session is an additional plugin for creating a common 'session' store
473
+ // for the given app. It is a very simple wrapper around <tt>Sammy.Storage</tt>
474
+ // that provides a simple fallback mechanism for trying to provide the best
475
+ // possible storage type for the session. This means, <tt>LocalStorage</tt>
476
+ // if available, otherwise <tt>Cookie</tt>, otherwise <tt>Memory</tt>.
477
+ // It provides the <tt>session()</tt> helper through <tt>Sammy.Storage#store()</tt>.
478
+ //
479
+ // See the <tt>Sammy.Storage</tt> plugin for full documentation.
480
+ //
481
+ Sammy.Session = function(app, options) {
482
+ this.use(Sammy.Storage);
483
+ // check for local storage, then cookie storage, then just use memory
484
+ var type = 'memory';
485
+ if (Sammy.Store.isAvailable('local')) {
486
+ type = 'local';
487
+ } else if (Sammy.Store.isAvailable('cookie')) {
488
+ type = 'cookie';
489
+ }
490
+ this.store('session', $.extend({type: type}, options));
491
+ };
492
+
493
+ // Sammy.Cache provides helpers for caching data within the lifecycle of a
494
+ // Sammy app. The plugin provides two main methods on <tt>Sammy.Application<tt>,
495
+ // <tt>cache</tt> and <tt>clearCache</tt>. Each app has its own cache store so that
496
+ // you dont have to worry about collisions. As of 0.5 the original Sammy.Cache module
497
+ // has been deprecated in favor of this one based on Sammy.Storage. The exposed
498
+ // API is almost identical, but Sammy.Storage provides additional backends including
499
+ // HTML5 Storage. <tt>Sammy.Cache</tt> will try to use these backends when available
500
+ // (in this order) <tt>LocalStorage</tt>, <tt>SessionStorage</tt>, and <tt>Memory</tt>
501
+ Sammy.Cache = function(app, options) {
502
+ this.use(Sammy.Storage);
503
+ // set cache_partials to true
504
+ this.cache_partials = true;
505
+ // check for local storage, then session storage, then just use memory
506
+ var type = 'memory';
507
+ if (Sammy.Store.isAvailable('local')) {
508
+ type = 'local';
509
+ } else if (Sammy.Store.isAvailable('session')) {
510
+ type = 'session';
511
+ }
512
+ this.store('cache', $.extend({type: type}, options));
513
+ };
514
+
515
+ })(jQuery);
@@ -0,0 +1,117 @@
1
+ (function($) {
2
+
3
+ // Simple JavaScript Templating
4
+ // John Resig - http://ejohn.org/ - MIT Licensed
5
+ // adapted from: http://ejohn.org/blog/javascript-micro-templating/
6
+ // originally $.srender by Greg Borenstein http://ideasfordozens.com in Feb 2009
7
+ // modified for Sammy by Aaron Quint for caching templates by name
8
+ var srender_cache = {};
9
+ var srender = function(name, template, data) {
10
+ // target is an optional element; if provided, the result will be inserted into it
11
+ // otherwise the result will simply be returned to the caller
12
+ if (srender_cache[name]) {
13
+ fn = srender_cache[name];
14
+ } else {
15
+ if (typeof template == 'undefined') {
16
+ // was a cache check, return false
17
+ return false;
18
+ }
19
+ // Generate a reusable function that will serve as a template
20
+ // generator (and which will be cached).
21
+ fn = srender_cache[name] = new Function("obj",
22
+ "var p=[],print=function(){p.push.apply(p,arguments);};" +
23
+
24
+ // Introduce the data as local variables using with(){}
25
+ "with(obj){p.push(\"" +
26
+
27
+ // Convert the template into pure JavaScript
28
+ template
29
+ .replace(/[\r\t\n]/g, " ")
30
+ .replace(/\"/g, '\\"')
31
+ .split("<%").join("\t")
32
+ .replace(/((^|%>)[^\t]*)/g, "$1\r")
33
+ .replace(/\t=(.*?)%>/g, "\",$1,\"")
34
+ .split("\t").join("\");")
35
+ .split("%>").join("p.push(\"")
36
+ .split("\r").join("")
37
+ + "\");}return p.join('');");
38
+ }
39
+
40
+ if (typeof data != 'undefined') {
41
+ return fn(data);
42
+ } else {
43
+ return fn;
44
+ }
45
+ };
46
+
47
+ Sammy = Sammy || {};
48
+
49
+ // <tt>Sammy.Template</tt> is a simple plugin that provides a way to create
50
+ // and render client side templates. The rendering code is based on John Resig's
51
+ // quick templates and Greg Borenstien's srender plugin.
52
+ // This is also a great template/boilerplate for Sammy plugins.
53
+ //
54
+ // Templates use <% %> tags to denote embedded javascript.
55
+ //
56
+ // === Examples
57
+ //
58
+ // Here is an example template (user.template):
59
+ //
60
+ // <div class="user">
61
+ // <div class="user-name"><%= user.name %></div>
62
+ // <% if (user.photo_url) { %>
63
+ // <div class="photo"><img src="<%= user.photo_url %>" /></div>
64
+ // <% } %>
65
+ // </div>
66
+ //
67
+ // Given that is a publicly accesible file, you would render it like:
68
+ //
69
+ // $.sammy(function() {
70
+ // // include the plugin
71
+ // this.use(Sammy.Template);
72
+ //
73
+ // this.get('#/', function() {
74
+ // // the template is rendered in the current context.
75
+ // this.user = {name: 'Aaron Quint'};
76
+ // // partial calls template() because of the file extension
77
+ // this.partial('user.template');
78
+ // })
79
+ // });
80
+ //
81
+ // You can also pass a second argument to use() that will alias the template
82
+ // method and therefore allow you to use a different extension for template files
83
+ // in <tt>partial()</tt>
84
+ //
85
+ // // alias to 'tpl'
86
+ // this.use(Sammy.Template, 'tpl');
87
+ //
88
+ // // now .tpl files will be run through srender
89
+ // this.get('#/', function() {
90
+ // this.partial('myfile.tpl');
91
+ // });
92
+ //
93
+ Sammy.Template = function(app, method_alias) {
94
+
95
+ // *Helper:* Uses simple templating to parse ERB like templates.
96
+ //
97
+ // === Arguments
98
+ //
99
+ // +template+:: A String template. '<% %>' tags are evaluated as Javascript and replaced with the elements in data.
100
+ // +data+:: An Object containing the replacement values for the template.
101
+ // data is extended with the <tt>EventContext</tt> allowing you to call its methods within the template.
102
+ // +name+:: An optional String name to cache the template.
103
+ //
104
+ var template = function(template, data, name) {
105
+ // use name for caching
106
+ if (typeof name == 'undefined') name = template;
107
+ return srender(name, template, $.extend({}, this, data));
108
+ };
109
+
110
+ // set the default method name/extension
111
+ if (!method_alias) method_alias = 'template';
112
+ // create the helper at the method alias
113
+ app.helper(method_alias, template);
114
+
115
+ };
116
+
117
+ })(jQuery);