jim 0.1.2 → 0.2.0

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