jim 0.2.3 → 0.3.0.pre
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.
- data/Gemfile +2 -1
- data/Gemfile.lock +2 -0
- data/HISTORY +13 -0
- data/README.md +148 -0
- data/Rakefile +6 -3
- data/bin/jim +1 -2
- data/default +0 -0
- data/jim.gemspec +142 -105
- data/lib/jim.rb +1 -1
- data/lib/jim/bundler.rb +168 -73
- data/lib/jim/cli.rb +200 -151
- data/lib/jim/index.rb +20 -9
- data/lib/jim/installer.rb +46 -46
- data/lib/jim/rack.rb +57 -20
- data/lib/jim/templates/jimfile +11 -5
- data/lib/jim/version_parser.rb +3 -3
- data/test/fixtures/infoincomments.js +1 -1
- data/test/fixtures/jimfile +14 -7
- data/test/fixtures/jquery-1.4.1.js +3 -6057
- data/test/fixtures/jquery.color.js +1 -1
- data/test/fixtures/localfile.js +1 -1
- data/test/fixtures/mustache.js/package.json +1 -1
- data/test/fixtures/noversion.js +1 -1
- data/test/fixtures/old_jimfile +7 -0
- data/test/fixtures/sammy-0.5.0/examples/backend/app.rb +4 -4
- data/test/fixtures/sammy-0.5.0/examples/backend/public/javascripts/app.js +18 -18
- data/test/fixtures/sammy-0.5.0/examples/backend/public/javascripts/jquery.cloudkit.js +1 -1
- data/test/fixtures/sammy-0.5.0/examples/backend/public/javascripts/jquery.js +1 -1
- data/test/fixtures/sammy-0.5.0/examples/backend/public/javascripts/sammy.js +161 -161
- data/test/fixtures/sammy-0.5.0/examples/backend/public/templates/task.html.erb +1 -1
- data/test/fixtures/sammy-0.5.0/examples/backend/public/templates/task_details.html.erb +1 -1
- data/test/fixtures/sammy-0.5.0/examples/backend/views/app.sass +6 -6
- data/test/fixtures/sammy-0.5.0/examples/backend/views/index.haml +5 -5
- data/test/fixtures/sammy-0.5.0/examples/form_handling/index.html +16 -16
- data/test/fixtures/sammy-0.5.0/examples/hello_world/index.html +13 -13
- data/test/fixtures/sammy-0.5.0/examples/location_override/data.html +28 -28
- data/test/fixtures/sammy-0.5.0/examples/location_override/index.html +18 -18
- data/test/fixtures/sammy-0.5.0/examples/location_override/test.html +36 -36
- data/test/fixtures/sammy-0.5.0/lib/min/sammy-0.5.0.min.js +1 -1
- data/test/fixtures/sammy-0.5.0/lib/min/sammy-lastest.min.js +1 -1
- data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.cache.js +13 -13
- data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.haml.js +2 -2
- data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.json.js +15 -15
- data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.mustache.js +46 -46
- data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.nested_params.js +29 -29
- data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.storage.js +54 -54
- data/test/fixtures/sammy-0.5.0/lib/plugins/sammy.template.js +17 -17
- data/test/fixtures/sammy-0.5.0/lib/sammy.js +220 -220
- data/test/fixtures/sammy-0.5.0/test/fixtures/partial.html +1 -1
- data/test/fixtures/sammy-0.5.0/test/index.html +26 -26
- data/test/fixtures/sammy-0.5.0/test/test_sammy_application.js +60 -60
- data/test/fixtures/sammy-0.5.0/test/test_sammy_event_context.js +21 -21
- data/test/fixtures/sammy-0.5.0/test/test_sammy_location_proxy.js +3 -3
- data/test/fixtures/sammy-0.5.0/test/test_sammy_plugins.js +17 -17
- data/test/fixtures/sammy-0.5.0/test/test_sammy_storage.js +4 -4
- data/test/helper.rb +15 -0
- data/test/test_jim_bundler.rb +114 -74
- data/test/test_jim_cli.rb +34 -18
- data/test/test_jim_index.rb +19 -19
- data/test/test_jim_installer.rb +13 -13
- data/test/test_jim_rack.rb +41 -0
- data/test/test_jim_version_parser.rb +4 -4
- metadata +204 -41
- data/.gitignore +0 -24
- data/README.rdoc +0 -105
- data/lib/jim/templates/commands +0 -58
@@ -4,12 +4,12 @@
|
|
4
4
|
|
5
5
|
// Sammy.Store is an abstract adapter class that wraps the multitude of in
|
6
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
|
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
9
|
// stored strings.
|
10
|
-
//
|
10
|
+
//
|
11
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.
|
12
|
+
// easier to use the <tt>Sammy.Storage</tt> plugin and its helper methods.
|
13
13
|
//
|
14
14
|
// Sammy.Store also supports the KVO pattern, by firing DOM/jQuery Events when
|
15
15
|
// a key is set.
|
@@ -28,18 +28,18 @@
|
|
28
28
|
// store.keys(); //=> ['json']
|
29
29
|
// store.clearAll();
|
30
30
|
// store.keys(); //=> []
|
31
|
-
//
|
31
|
+
//
|
32
32
|
// === Arguments
|
33
33
|
//
|
34
34
|
// The constructor takes a single argument which is a Object containing these possible options.
|
35
|
-
//
|
35
|
+
//
|
36
36
|
// +name+:: The name/namespace of this store. Stores are unique by name/type. (default 'store')
|
37
37
|
// +element+:: A selector for the element that the store is bound to. (default 'body')
|
38
38
|
// +type+:: The type of storage/proxy to use (default 'memory')
|
39
|
-
//
|
39
|
+
//
|
40
40
|
// Extra options are passed to the storage constructor.
|
41
41
|
// Sammy.Store supports the following methods of storage:
|
42
|
-
//
|
42
|
+
//
|
43
43
|
// +memory+:: Basic object storage
|
44
44
|
// +data+:: jQuery.data DOM Storage
|
45
45
|
// +cookie+:: Access to document.cookie. Limited to 2K
|
@@ -79,14 +79,14 @@
|
|
79
79
|
},
|
80
80
|
// Sets the value of <tt>key<tt> with <tt>value</tt>. If <tt>value<tt> is an
|
81
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
|
82
|
+
// It also tries to conform to the KVO pattern triggering jQuery events on the
|
83
83
|
// element that the store is bound to.
|
84
|
-
//
|
84
|
+
//
|
85
85
|
// === Example
|
86
86
|
//
|
87
87
|
// var store = new Sammy.Store({name: 'kvo'});
|
88
|
-
// $('body').bind('set-kvo.foo', function() {
|
89
|
-
// alert('foo changed!')
|
88
|
+
// $('body').bind('set-kvo.foo', function() {
|
89
|
+
// alert('foo changed!')
|
90
90
|
// });
|
91
91
|
// store.set('foo', 'bar'); // alerted: foo changed!
|
92
92
|
//
|
@@ -94,13 +94,13 @@
|
|
94
94
|
var string_value = (typeof value == 'string') ? value : JSON.stringify(value);
|
95
95
|
key = key.toString();
|
96
96
|
this.storage.set(key, string_value);
|
97
|
-
if (key != this.meta_key) {
|
98
|
-
this._addKey(key);
|
97
|
+
if (key != this.meta_key) {
|
98
|
+
this._addKey(key);
|
99
99
|
this.$element.trigger('set-' + this.name + '.' + key, [key, value]);
|
100
100
|
};
|
101
101
|
return string_value;
|
102
102
|
},
|
103
|
-
// Returns the set value at <tt>key</tt>, parsing with <tt>JSON.parse</tt> and
|
103
|
+
// Returns the set value at <tt>key</tt>, parsing with <tt>JSON.parse</tt> and
|
104
104
|
// turning into an object if possible
|
105
105
|
get: function(key) {
|
106
106
|
var value = this.storage.get(key);
|
@@ -132,9 +132,9 @@
|
|
132
132
|
},
|
133
133
|
// Returns the value at <tt>key</tt> if set, otherwise, runs the callback
|
134
134
|
// and sets the value to the value returned in the callback.
|
135
|
-
//
|
135
|
+
//
|
136
136
|
// === Example
|
137
|
-
//
|
137
|
+
//
|
138
138
|
// var store = new Sammy.Store;
|
139
139
|
// store.exists('foo'); //=> false
|
140
140
|
// store.fetch('foo', function() {
|
@@ -144,7 +144,7 @@
|
|
144
144
|
// store.fetch('foo', function() {
|
145
145
|
// return 'baz!';
|
146
146
|
// }); //=> 'bar!
|
147
|
-
//
|
147
|
+
//
|
148
148
|
fetch: function(key, callback) {
|
149
149
|
if (!this.exists(key)) {
|
150
150
|
return this.set(key, callback.apply(this));
|
@@ -153,20 +153,20 @@
|
|
153
153
|
}
|
154
154
|
},
|
155
155
|
// loads the response of a request to <tt>path</tt> into <tt>key</tt>.
|
156
|
-
//
|
156
|
+
//
|
157
157
|
// === Example
|
158
|
-
//
|
158
|
+
//
|
159
159
|
// In /mytemplate.tpl:
|
160
|
-
//
|
160
|
+
//
|
161
161
|
// My Template
|
162
|
-
//
|
162
|
+
//
|
163
163
|
// In app.js:
|
164
|
-
//
|
164
|
+
//
|
165
165
|
// var store = new Sammy.Store;
|
166
166
|
// store.load('mytemplate', '/mytemplate.tpl', function() {
|
167
167
|
// s.get('mytemplate') //=> My Template
|
168
168
|
// });
|
169
|
-
//
|
169
|
+
//
|
170
170
|
load: function(key, path, callback) {
|
171
171
|
var s = this;
|
172
172
|
$.get(path, function(response) {
|
@@ -186,7 +186,7 @@
|
|
186
186
|
this.set(this.meta_key, keys);
|
187
187
|
}
|
188
188
|
});
|
189
|
-
|
189
|
+
|
190
190
|
// Tests if the type of storage is available/works in the current browser/config.
|
191
191
|
// Especially useful for testing the availability of the awesome, but not widely
|
192
192
|
// supported HTML5 DOM storage
|
@@ -198,7 +198,7 @@
|
|
198
198
|
}
|
199
199
|
};
|
200
200
|
|
201
|
-
// Memory ('memory') is the basic/default store. It stores data in a global
|
201
|
+
// Memory ('memory') is the basic/default store. It stores data in a global
|
202
202
|
// JS object. Data is lost on refresh.
|
203
203
|
Sammy.Store.Memory = function(name, element) {
|
204
204
|
this.name = name;
|
@@ -252,12 +252,12 @@
|
|
252
252
|
});
|
253
253
|
|
254
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
|
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
257
|
// cookies accessed via JS. The great disadvantage, though, is its only available
|
258
|
-
// on the latest and greatest browsers.
|
258
|
+
// on the latest and greatest browsers.
|
259
259
|
//
|
260
|
-
// For more info on DOM Storage:
|
260
|
+
// For more info on DOM Storage:
|
261
261
|
// [https://developer.mozilla.org/en/DOM/Storage]
|
262
262
|
// [http://www.w3.org/TR/2009/WD-webstorage-20091222/]
|
263
263
|
//
|
@@ -284,10 +284,10 @@
|
|
284
284
|
_key: function(key) {
|
285
285
|
return ['store', this.element, this.name, key].join('.');
|
286
286
|
}
|
287
|
-
});
|
287
|
+
});
|
288
288
|
|
289
289
|
// .SessionStorage ('session') is similar to LocalStorage (part of the same API)
|
290
|
-
// and shares similar browser support/availability. The difference is that
|
290
|
+
// and shares similar browser support/availability. The difference is that
|
291
291
|
// SessionStorage is only persistant through the current 'session' which is defined
|
292
292
|
// as the length that the current window is open. This means that data will survive
|
293
293
|
// refreshes but not close/open or multiple windows/tabs. For more info, check out
|
@@ -328,7 +328,7 @@
|
|
328
328
|
// +expires_in+:: Number of seconds to keep the cookie alive (default 2 weeks).
|
329
329
|
// +path+:: The path to activate the current cookie for (default '/').
|
330
330
|
//
|
331
|
-
// For more information about document.cookie, check out the pre-eminint article
|
331
|
+
// For more information about document.cookie, check out the pre-eminint article
|
332
332
|
// by ppk: [http://www.quirksmode.org/js/cookies.html]
|
333
333
|
//
|
334
334
|
Sammy.Store.Cookie = function(name, element, options) {
|
@@ -337,7 +337,7 @@
|
|
337
337
|
this.options = options || {};
|
338
338
|
this.path = this.options.path || '/';
|
339
339
|
// set the expires in seconds or default 14 days
|
340
|
-
this.expires_in = this.options.expires_in || (14 * 24 * 60 * 60);
|
340
|
+
this.expires_in = this.options.expires_in || (14 * 24 * 60 * 60);
|
341
341
|
};
|
342
342
|
$.extend(Sammy.Store.Cookie.prototype, {
|
343
343
|
isAvailable: function() {
|
@@ -368,13 +368,13 @@
|
|
368
368
|
var date = new Date();
|
369
369
|
date.setTime(date.getTime() + expires);
|
370
370
|
var set_cookie = [
|
371
|
-
this._key(key), "=", value,
|
372
|
-
"; expires=", date.toGMTString(),
|
371
|
+
this._key(key), "=", value,
|
372
|
+
"; expires=", date.toGMTString(),
|
373
373
|
"; path=", this.path
|
374
374
|
].join('');
|
375
375
|
document.cookie = set_cookie;
|
376
376
|
}
|
377
|
-
});
|
377
|
+
});
|
378
378
|
|
379
379
|
// Sammy.Storage is a plugin that provides shortcuts for creating and using
|
380
380
|
// Sammy.Store objects. Once included it provides the <tt>store()</tt> app level
|
@@ -387,26 +387,26 @@
|
|
387
387
|
// <tt>store()</tt> creates and looks up existing <tt>Sammy.Store</tt> objects
|
388
388
|
// for the current application. The first time used for a given <tt>'name'</tt>
|
389
389
|
// initializes a <tt>Sammy.Store</tt> and also creates a helper under the store's
|
390
|
-
// name.
|
390
|
+
// name.
|
391
391
|
//
|
392
392
|
// === Example
|
393
393
|
//
|
394
394
|
// var app = $.sammy(function() {
|
395
395
|
// this.use(Sammy.Storage);
|
396
|
-
//
|
396
|
+
//
|
397
397
|
// // initializes the store on app creation.
|
398
398
|
// this.store('mystore', {type: 'cookie'});
|
399
|
-
//
|
399
|
+
//
|
400
400
|
// this.get('#/', function() {
|
401
401
|
// // returns the Sammy.Store object
|
402
|
-
// this.store('mystore');
|
402
|
+
// this.store('mystore');
|
403
403
|
// // sets 'foo' to 'bar' using the shortcut/helper
|
404
404
|
// // equivilent to this.store('mystore').set('foo', 'bar');
|
405
|
-
// this.mystore('foo', 'bar');
|
405
|
+
// this.mystore('foo', 'bar');
|
406
406
|
// // returns 'bar'
|
407
407
|
// // equivilent to this.store('mystore').get('foo');
|
408
408
|
// this.mystore('foo');
|
409
|
-
// // returns 'baz!'
|
409
|
+
// // returns 'baz!'
|
410
410
|
// // equivilent to:
|
411
411
|
// // this.store('mystore').fetch('foo!', function() {
|
412
412
|
// // return 'baz!';
|
@@ -415,11 +415,11 @@
|
|
415
415
|
// return 'baz!';
|
416
416
|
// });
|
417
417
|
//
|
418
|
-
// this.clearMystore();
|
418
|
+
// this.clearMystore();
|
419
419
|
// // equivilent to:
|
420
420
|
// // this.store('mystore').clearAll()
|
421
421
|
// });
|
422
|
-
//
|
422
|
+
//
|
423
423
|
// });
|
424
424
|
//
|
425
425
|
// === Arguments
|
@@ -429,11 +429,11 @@
|
|
429
429
|
//
|
430
430
|
this.store = function(name, options) {
|
431
431
|
// if the store has not been initialized
|
432
|
-
if (typeof this.stores[name] == 'undefined') {
|
432
|
+
if (typeof this.stores[name] == 'undefined') {
|
433
433
|
// create initialize the store
|
434
434
|
var clear_method_name = "clear" + name.substr(0,1).toUpperCase() + name.substr(1);
|
435
435
|
this.stores[name] = new Sammy.Store($.extend({
|
436
|
-
name: name,
|
436
|
+
name: name,
|
437
437
|
element: this.element_selector
|
438
438
|
}, options || {}));
|
439
439
|
// app.name()
|
@@ -461,18 +461,18 @@
|
|
461
461
|
}
|
462
462
|
return this.stores[name];
|
463
463
|
};
|
464
|
-
|
464
|
+
|
465
465
|
this.helpers({
|
466
466
|
store: function() {
|
467
467
|
return this.app.store.apply(this.app, arguments);
|
468
468
|
}
|
469
469
|
});
|
470
470
|
};
|
471
|
-
|
471
|
+
|
472
472
|
// Sammy.Session is an additional plugin for creating a common 'session' store
|
473
473
|
// for the given app. It is a very simple wrapper around <tt>Sammy.Storage</tt>
|
474
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>
|
475
|
+
// possible storage type for the session. This means, <tt>LocalStorage</tt>
|
476
476
|
// if available, otherwise <tt>Cookie</tt>, otherwise <tt>Memory</tt>.
|
477
477
|
// It provides the <tt>session()</tt> helper through <tt>Sammy.Storage#store()</tt>.
|
478
478
|
//
|
@@ -489,8 +489,8 @@
|
|
489
489
|
}
|
490
490
|
this.store('session', $.extend({type: type}, options));
|
491
491
|
};
|
492
|
-
|
493
|
-
// Sammy.Cache provides helpers for caching data within the lifecycle of a
|
492
|
+
|
493
|
+
// Sammy.Cache provides helpers for caching data within the lifecycle of a
|
494
494
|
// Sammy app. The plugin provides two main methods on <tt>Sammy.Application<tt>,
|
495
495
|
// <tt>cache</tt> and <tt>clearCache</tt>. Each app has its own cache store so that
|
496
496
|
// you dont have to worry about collisions. As of 0.5 the original Sammy.Cache module
|
@@ -511,5 +511,5 @@
|
|
511
511
|
}
|
512
512
|
this.store('cache', $.extend({type: type}, options));
|
513
513
|
};
|
514
|
-
|
515
|
-
})(jQuery);
|
514
|
+
|
515
|
+
})(jQuery);
|
@@ -1,5 +1,5 @@
|
|
1
1
|
(function($) {
|
2
|
-
|
2
|
+
|
3
3
|
// Simple JavaScript Templating
|
4
4
|
// John Resig - http://ejohn.org/ - MIT Licensed
|
5
5
|
// adapted from: http://ejohn.org/blog/javascript-micro-templating/
|
@@ -8,7 +8,7 @@
|
|
8
8
|
var srender_cache = {};
|
9
9
|
var srender = function(name, template, data) {
|
10
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
|
11
|
+
// otherwise the result will simply be returned to the caller
|
12
12
|
if (srender_cache[name]) {
|
13
13
|
fn = srender_cache[name];
|
14
14
|
} else {
|
@@ -43,15 +43,15 @@
|
|
43
43
|
return fn;
|
44
44
|
}
|
45
45
|
};
|
46
|
-
|
46
|
+
|
47
47
|
Sammy = Sammy || {};
|
48
48
|
|
49
49
|
// <tt>Sammy.Template</tt> is a simple plugin that provides a way to create
|
50
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.
|
51
|
+
// quick templates and Greg Borenstien's srender plugin.
|
52
|
+
// This is also a great template/boilerplate for Sammy plugins.
|
53
53
|
//
|
54
|
-
// Templates use <% %> tags to denote embedded javascript.
|
54
|
+
// Templates use <% %> tags to denote embedded javascript.
|
55
55
|
//
|
56
56
|
// === Examples
|
57
57
|
//
|
@@ -65,11 +65,11 @@
|
|
65
65
|
// </div>
|
66
66
|
//
|
67
67
|
// Given that is a publicly accesible file, you would render it like:
|
68
|
-
//
|
68
|
+
//
|
69
69
|
// $.sammy(function() {
|
70
70
|
// // include the plugin
|
71
71
|
// this.use(Sammy.Template);
|
72
|
-
//
|
72
|
+
//
|
73
73
|
// this.get('#/', function() {
|
74
74
|
// // the template is rendered in the current context.
|
75
75
|
// this.user = {name: 'Aaron Quint'};
|
@@ -79,9 +79,9 @@
|
|
79
79
|
// });
|
80
80
|
//
|
81
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
|
82
|
+
// method and therefore allow you to use a different extension for template files
|
83
83
|
// in <tt>partial()</tt>
|
84
|
-
//
|
84
|
+
//
|
85
85
|
// // alias to 'tpl'
|
86
86
|
// this.use(Sammy.Template, 'tpl');
|
87
87
|
//
|
@@ -91,13 +91,13 @@
|
|
91
91
|
// });
|
92
92
|
//
|
93
93
|
Sammy.Template = function(app, method_alias) {
|
94
|
-
|
94
|
+
|
95
95
|
// *Helper:* Uses simple templating to parse ERB like templates.
|
96
96
|
//
|
97
97
|
// === Arguments
|
98
|
-
//
|
98
|
+
//
|
99
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.
|
100
|
+
// +data+:: An Object containing the replacement values for the template.
|
101
101
|
// data is extended with the <tt>EventContext</tt> allowing you to call its methods within the template.
|
102
102
|
// +name+:: An optional String name to cache the template.
|
103
103
|
//
|
@@ -106,12 +106,12 @@
|
|
106
106
|
if (typeof name == 'undefined') name = template;
|
107
107
|
return srender(name, template, $.extend({}, this, data));
|
108
108
|
};
|
109
|
-
|
109
|
+
|
110
110
|
// set the default method name/extension
|
111
|
-
if (!method_alias) method_alias = 'template';
|
111
|
+
if (!method_alias) method_alias = 'template';
|
112
112
|
// create the helper at the method alias
|
113
113
|
app.helper(method_alias, template);
|
114
|
-
|
114
|
+
|
115
115
|
};
|
116
116
|
|
117
|
-
})(jQuery);
|
117
|
+
})(jQuery);
|
@@ -2,7 +2,7 @@
|
|
2
2
|
// version: 0.5.0
|
3
3
|
|
4
4
|
;(function($) {
|
5
|
-
|
5
|
+
|
6
6
|
var PATH_REPLACER = "([^\/]+)",
|
7
7
|
PATH_NAME_MATCHER = /:([\w\d]+)/g,
|
8
8
|
QUERY_STRING_MATCHER = /\?([^#]*)$/,
|
@@ -11,9 +11,9 @@
|
|
11
11
|
return function(path, callback) { return this.route.apply(this, [verb, path, callback]); }
|
12
12
|
},
|
13
13
|
loggers = [];
|
14
|
-
|
15
|
-
|
16
|
-
// <tt>Sammy</tt> (also aliased as $.sammy) is not only the namespace for a
|
14
|
+
|
15
|
+
|
16
|
+
// <tt>Sammy</tt> (also aliased as $.sammy) is not only the namespace for a
|
17
17
|
// number of prototypes, its also a top level method that allows for easy
|
18
18
|
// creation/management of <tt>Sammy.Application</tt> instances. There are a
|
19
19
|
// number of different forms for <tt>Sammy()</tt> but each returns an instance
|
@@ -21,24 +21,24 @@
|
|
21
21
|
// <tt>Sammy</tt> it is added to an Object called <tt>Sammy.apps</tt>. This
|
22
22
|
// provides for an easy way to get at existing Sammy applications. Only one
|
23
23
|
// instance is allowed per <tt>element_selector</tt> so when calling
|
24
|
-
// <tt>Sammy('selector')</tt> multiple times, the first time will create
|
24
|
+
// <tt>Sammy('selector')</tt> multiple times, the first time will create
|
25
25
|
// the application and the following times will extend the application
|
26
26
|
// already added to that selector.
|
27
27
|
//
|
28
28
|
// === Example
|
29
29
|
//
|
30
30
|
// // returns the app at #main or a new app
|
31
|
-
// Sammy('#main')
|
31
|
+
// Sammy('#main')
|
32
32
|
//
|
33
33
|
// // equivilent to "new Sammy.Application", except appends to apps
|
34
34
|
// Sammy();
|
35
|
-
// Sammy(function() { ... });
|
35
|
+
// Sammy(function() { ... });
|
36
36
|
//
|
37
37
|
// // extends the app at '#main' with function.
|
38
38
|
// Sammy('#main', function() { ... });
|
39
39
|
//
|
40
40
|
Sammy = function() {
|
41
|
-
var args = $.makeArray(arguments),
|
41
|
+
var args = $.makeArray(arguments),
|
42
42
|
app, selector;
|
43
43
|
Sammy.apps = Sammy.apps || {};
|
44
44
|
if (args.length == 0 || args[0] && $.isFunction(args[0])) { // Sammy()
|
@@ -59,29 +59,29 @@
|
|
59
59
|
return app;
|
60
60
|
}
|
61
61
|
};
|
62
|
-
|
62
|
+
|
63
63
|
Sammy.VERSION = '0.5.0';
|
64
|
-
|
65
|
-
// Add to the global logger pool. Takes a function that accepts an
|
64
|
+
|
65
|
+
// Add to the global logger pool. Takes a function that accepts an
|
66
66
|
// unknown number of arguments and should print them or send them somewhere
|
67
67
|
// The first argument is always a timestamp.
|
68
68
|
Sammy.addLogger = function(logger) {
|
69
69
|
loggers.push(logger);
|
70
70
|
};
|
71
|
-
|
71
|
+
|
72
72
|
// Sends a log message to each logger listed in the global
|
73
73
|
// loggers pool. Can take any number of arguments.
|
74
74
|
// Also prefixes the arguments with a timestamp.
|
75
|
-
Sammy.log = function()
|
75
|
+
Sammy.log = function() {
|
76
76
|
var args = $.makeArray(arguments);
|
77
77
|
args.unshift("[" + Date() + "]");
|
78
78
|
$.each(loggers, function(i, logger) {
|
79
79
|
logger.apply(Sammy, args);
|
80
80
|
});
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
81
|
+
};
|
82
|
+
|
83
|
+
if (typeof window.console != 'undefined') {
|
84
|
+
if ($.isFunction(console.log.apply)) {
|
85
85
|
Sammy.addLogger(function() {
|
86
86
|
window.console.log.apply(console, arguments);
|
87
87
|
});
|
@@ -95,18 +95,18 @@
|
|
95
95
|
console.log.apply(console, arguments);
|
96
96
|
});
|
97
97
|
}
|
98
|
-
|
99
|
-
// Sammy.Object is the base for all other Sammy classes. It provides some useful
|
98
|
+
|
99
|
+
// Sammy.Object is the base for all other Sammy classes. It provides some useful
|
100
100
|
// functionality, including cloning, iterating, etc.
|
101
101
|
Sammy.Object = function(obj) { // constructor
|
102
102
|
return $.extend(this, obj || {});
|
103
103
|
};
|
104
|
-
|
105
|
-
$.extend(Sammy.Object.prototype, {
|
106
|
-
|
104
|
+
|
105
|
+
$.extend(Sammy.Object.prototype, {
|
106
|
+
|
107
107
|
// Returns a copy of the object with Functions removed.
|
108
108
|
toHash: function() {
|
109
|
-
var json = {};
|
109
|
+
var json = {};
|
110
110
|
$.each(this, function(k,v) {
|
111
111
|
if (!$.isFunction(v)) {
|
112
112
|
json[k] = v
|
@@ -114,11 +114,11 @@
|
|
114
114
|
});
|
115
115
|
return json;
|
116
116
|
},
|
117
|
-
|
117
|
+
|
118
118
|
// Renders a simple HTML version of this Objects attributes.
|
119
119
|
// Does not render functions.
|
120
120
|
// For example. Given this Sammy.Object:
|
121
|
-
//
|
121
|
+
//
|
122
122
|
// var s = new Sammy.Object({first_name: 'Sammy', last_name: 'Davis Jr.'});
|
123
123
|
// s.toHTML() //=> '<strong>first_name</strong> Sammy<br /><strong>last_name</strong> Davis Jr.<br />'
|
124
124
|
//
|
@@ -131,7 +131,7 @@
|
|
131
131
|
});
|
132
132
|
return display;
|
133
133
|
},
|
134
|
-
|
134
|
+
|
135
135
|
// Generates a unique identifing string. Used for application namespaceing.
|
136
136
|
uuid: function() {
|
137
137
|
if (typeof this._uuid == 'undefined' || !this._uuid) {
|
@@ -139,8 +139,8 @@
|
|
139
139
|
}
|
140
140
|
return this._uuid;
|
141
141
|
},
|
142
|
-
|
143
|
-
// Returns an array of keys for this object. If <tt>attributes_only</tt>
|
142
|
+
|
143
|
+
// Returns an array of keys for this object. If <tt>attributes_only</tt>
|
144
144
|
// is true will not return keys that map to a <tt>function()</tt>
|
145
145
|
keys: function(attributes_only) {
|
146
146
|
var keys = [];
|
@@ -151,45 +151,45 @@
|
|
151
151
|
}
|
152
152
|
return keys;
|
153
153
|
},
|
154
|
-
|
154
|
+
|
155
155
|
// Checks if the object has a value at <tt>key</tt> and that the value is not empty
|
156
156
|
has: function(key) {
|
157
157
|
return this[key] && $.trim(this[key].toString()) != '';
|
158
158
|
},
|
159
|
-
|
160
|
-
// convenience method to join as many arguments as you want
|
159
|
+
|
160
|
+
// convenience method to join as many arguments as you want
|
161
161
|
// by the first argument - useful for making paths
|
162
162
|
join: function() {
|
163
163
|
var args = $.makeArray(arguments);
|
164
164
|
var delimiter = args.shift();
|
165
165
|
return args.join(delimiter);
|
166
166
|
},
|
167
|
-
|
167
|
+
|
168
168
|
// Shortcut to Sammy.log
|
169
169
|
log: function() {
|
170
170
|
Sammy.log.apply(Sammy, arguments);
|
171
171
|
},
|
172
|
-
|
173
|
-
// Returns a string representation of this object.
|
174
|
-
// if <tt>include_functions</tt> is true, it will also toString() the
|
172
|
+
|
173
|
+
// Returns a string representation of this object.
|
174
|
+
// if <tt>include_functions</tt> is true, it will also toString() the
|
175
175
|
// methods of this object. By default only prints the attributes.
|
176
176
|
toString: function(include_functions) {
|
177
177
|
var s = []
|
178
178
|
$.each(this, function(k, v) {
|
179
|
-
|
179
|
+
if (!$.isFunction(v) || include_functions) {
|
180
180
|
s.push('"' + k + '": ' + v.toString());
|
181
|
-
|
181
|
+
}
|
182
182
|
});
|
183
|
-
return "Sammy.Object: {" + s.join(',') + "}";
|
183
|
+
return "Sammy.Object: {" + s.join(',') + "}";
|
184
184
|
}
|
185
185
|
});
|
186
|
-
|
186
|
+
|
187
187
|
// The HashLocationProxy is the default location proxy for all Sammy applications.
|
188
188
|
// A location proxy is a prototype that conforms to a simple interface. The purpose
|
189
189
|
// of a location proxy is to notify the Sammy.Application its bound to when the location
|
190
190
|
// or 'external state' changes. The HashLocationProxy considers the state to be
|
191
191
|
// changed when the 'hash' (window.location.hash / '#') changes. It does this in two
|
192
|
-
// different ways depending on what browser you are using. The newest browsers
|
192
|
+
// different ways depending on what browser you are using. The newest browsers
|
193
193
|
// (IE, Safari > 4, FF >= 3.6) support a 'onhashchange' DOM event, thats fired whenever
|
194
194
|
// the location.hash changes. In this situation the HashLocationProxy just binds
|
195
195
|
// to this event and delegates it to the application. In the case of older browsers
|
@@ -198,7 +198,7 @@
|
|
198
198
|
// need for multiple pollers even when thier are multiple apps on the page.
|
199
199
|
Sammy.HashLocationProxy = function(app, run_interval_every) {
|
200
200
|
this.app = app;
|
201
|
-
|
201
|
+
|
202
202
|
// check for native hash support
|
203
203
|
if ('onhashchange' in window) {
|
204
204
|
Sammy.log('native hash change exists, using');
|
@@ -209,7 +209,7 @@
|
|
209
209
|
this._startPolling(run_interval_every);
|
210
210
|
}
|
211
211
|
};
|
212
|
-
|
212
|
+
|
213
213
|
Sammy.HashLocationProxy.prototype = {
|
214
214
|
// bind the proxy events to the current app.
|
215
215
|
bind: function() {
|
@@ -234,7 +234,7 @@
|
|
234
234
|
setLocation: function(new_location) {
|
235
235
|
return window.location = new_location;
|
236
236
|
},
|
237
|
-
|
237
|
+
|
238
238
|
_startPolling: function(every) {
|
239
239
|
// set up interval
|
240
240
|
var proxy = this;
|
@@ -243,7 +243,7 @@
|
|
243
243
|
var hashCheck = function() {
|
244
244
|
current_location = proxy.getLocation();
|
245
245
|
// Sammy.log('getLocation', current_location);
|
246
|
-
if (!Sammy.HashLocationProxy._last_location ||
|
246
|
+
if (!Sammy.HashLocationProxy._last_location ||
|
247
247
|
current_location != Sammy.HashLocationProxy._last_location) {
|
248
248
|
setTimeout(function() {
|
249
249
|
$(window).trigger('hashchange');
|
@@ -259,18 +259,18 @@
|
|
259
259
|
}
|
260
260
|
}
|
261
261
|
};
|
262
|
-
|
262
|
+
|
263
263
|
// The DataLocationProxy is an optional location proxy prototype. As opposed to
|
264
264
|
// the <tt>HashLocationProxy</tt> it gets its location from a jQuery.data attribute
|
265
265
|
// tied to the application's element. You can set the name of the attribute by
|
266
266
|
// passing a string as the second argument to the constructor. The default attribute
|
267
|
-
// name is 'sammy-location'. To read more about location proxies, check out the
|
267
|
+
// name is 'sammy-location'. To read more about location proxies, check out the
|
268
268
|
// documentation for <tt>Sammy.HashLocationProxy</tt>
|
269
269
|
Sammy.DataLocationProxy = function(app, data_name) {
|
270
270
|
this.app = app;
|
271
271
|
this.data_name = data_name || 'sammy-location';
|
272
272
|
};
|
273
|
-
|
273
|
+
|
274
274
|
Sammy.DataLocationProxy.prototype = {
|
275
275
|
bind: function() {
|
276
276
|
var proxy = this;
|
@@ -280,20 +280,20 @@
|
|
280
280
|
}
|
281
281
|
});
|
282
282
|
},
|
283
|
-
|
283
|
+
|
284
284
|
unbind: function() {
|
285
285
|
this.app.$element().die('setData');
|
286
286
|
},
|
287
|
-
|
287
|
+
|
288
288
|
getLocation: function() {
|
289
289
|
return this.app.$element().data(this.data_name);
|
290
290
|
},
|
291
|
-
|
291
|
+
|
292
292
|
setLocation: function(new_location) {
|
293
293
|
return this.app.$element().data(this.data_name, new_location);
|
294
294
|
}
|
295
295
|
};
|
296
|
-
|
296
|
+
|
297
297
|
// Sammy.Application is the Base prototype for defining 'applications'.
|
298
298
|
// An 'application' is a collection of 'routes' and bound events that is
|
299
299
|
// attached to an element when <tt>run()</tt> is called.
|
@@ -321,72 +321,72 @@
|
|
321
321
|
});
|
322
322
|
}
|
323
323
|
};
|
324
|
-
|
324
|
+
|
325
325
|
Sammy.Application.prototype = $.extend({}, Sammy.Object.prototype, {
|
326
|
-
|
326
|
+
|
327
327
|
// the four route verbs
|
328
328
|
ROUTE_VERBS: ['get','post','put','delete'],
|
329
|
-
|
330
|
-
// An array of the default events triggered by the
|
329
|
+
|
330
|
+
// An array of the default events triggered by the
|
331
331
|
// application during its lifecycle
|
332
332
|
APP_EVENTS: ['run','unload','lookup-route','run-route','route-found','event-context-before','event-context-after','changed','error-404','check-form-submission','redirect'],
|
333
|
-
|
333
|
+
|
334
334
|
_last_route: null,
|
335
335
|
_running: false,
|
336
|
-
|
336
|
+
|
337
337
|
// On <tt>run()</tt> the application object is stored in a <tt>$.data</tt> entry
|
338
338
|
// assocciated with the application's <tt>$element()</tt>
|
339
339
|
data_store_name: 'sammy-app',
|
340
|
-
|
341
|
-
// Defines what element the application is bound to. Provide a selector
|
340
|
+
|
341
|
+
// Defines what element the application is bound to. Provide a selector
|
342
342
|
// (parseable by <tt>jQuery()</tt>) and this will be used by <tt>$element()</tt>
|
343
343
|
element_selector: 'body',
|
344
|
-
|
344
|
+
|
345
345
|
// When set to true, logs all of the default events using <tt>log()</tt>
|
346
346
|
debug: false,
|
347
|
-
|
347
|
+
|
348
348
|
// When set to false, will throw a javascript error when a route is invoked
|
349
349
|
// and can not be found.
|
350
350
|
silence_404: true,
|
351
|
-
|
351
|
+
|
352
352
|
// The time in milliseconds that the URL is queried for changes
|
353
|
-
run_interval_every: 50,
|
354
|
-
|
353
|
+
run_interval_every: 50,
|
354
|
+
|
355
355
|
// The location proxy for the current app. By default this is set to a new
|
356
356
|
// <tt>Sammy.HashLocationProxy</tt> on initialization. However, you can set
|
357
357
|
// the location_proxy inside you're app function to give youre app a custom
|
358
358
|
// location mechanism
|
359
359
|
location_proxy: null,
|
360
|
-
|
361
|
-
// The default template engine to use when using <tt>partial()</tt> in an
|
362
|
-
// <tt>EventContext</tt>. <tt>template_engine</tt> can either be a string that
|
360
|
+
|
361
|
+
// The default template engine to use when using <tt>partial()</tt> in an
|
362
|
+
// <tt>EventContext</tt>. <tt>template_engine</tt> can either be a string that
|
363
363
|
// corresponds to the name of a method/helper on EventContext or it can be a function
|
364
364
|
// that takes two arguments, the content of the unrendered partial and an optional
|
365
365
|
// JS object that contains interpolation data. Template engine is only called/refered
|
366
366
|
// to if the extension of the partial is null or unknown. See <tt>partial()</tt>
|
367
367
|
// for more information
|
368
368
|
template_engine: null,
|
369
|
-
|
369
|
+
|
370
370
|
// //=> Sammy.Application: body
|
371
371
|
toString: function() {
|
372
372
|
return 'Sammy.Application:' + this.element_selector;
|
373
373
|
},
|
374
|
-
|
374
|
+
|
375
375
|
// returns a jQuery object of the Applications bound element.
|
376
376
|
$element: function() {
|
377
377
|
return $(this.element_selector);
|
378
378
|
},
|
379
|
-
|
379
|
+
|
380
380
|
// <tt>use()</tt> is the entry point for including Sammy plugins.
|
381
|
-
// The first argument to use should be a function() that is evaluated
|
381
|
+
// The first argument to use should be a function() that is evaluated
|
382
382
|
// in the context of the current application, just like the <tt>app_function</tt>
|
383
383
|
// argument to the <tt>Sammy.Application</tt> constructor.
|
384
384
|
//
|
385
385
|
// Any additional arguments are passed to the app function sequentially.
|
386
386
|
//
|
387
|
-
// For much more detail about plugins, check out:
|
387
|
+
// For much more detail about plugins, check out:
|
388
388
|
// http://code.quirkey.com/sammy/doc/plugins.html
|
389
|
-
//
|
389
|
+
//
|
390
390
|
// === Example
|
391
391
|
//
|
392
392
|
// var MyPlugin = function(app, prepend) {
|
@@ -396,15 +396,15 @@
|
|
396
396
|
// alert(prepend + " " + text);
|
397
397
|
// }
|
398
398
|
// });
|
399
|
-
//
|
399
|
+
//
|
400
400
|
// };
|
401
401
|
//
|
402
402
|
// var app = $.sammy(function() {
|
403
|
-
//
|
403
|
+
//
|
404
404
|
// this.use(MyPlugin, 'This is my plugin');
|
405
|
-
//
|
405
|
+
//
|
406
406
|
// this.get('#/', function() {
|
407
|
-
// this.myhelper('and dont you forget it!');
|
407
|
+
// this.myhelper('and dont you forget it!');
|
408
408
|
// //=> Alerts: This is my plugin and dont you forget it!
|
409
409
|
// });
|
410
410
|
//
|
@@ -428,7 +428,7 @@
|
|
428
428
|
}
|
429
429
|
return this;
|
430
430
|
},
|
431
|
-
|
431
|
+
|
432
432
|
// <tt>route()</tt> is the main method for defining routes within an application.
|
433
433
|
// For great detail on routes, check out: http://code.quirkey.com/sammy/doc/routes.html
|
434
434
|
//
|
@@ -437,7 +437,7 @@
|
|
437
437
|
// === Arguments
|
438
438
|
//
|
439
439
|
// +verb+:: A String in the set of ROUTE_VERBS or 'any'. 'any' will add routes for each
|
440
|
-
// of the ROUTE_VERBS. If only two arguments are passed,
|
440
|
+
// of the ROUTE_VERBS. If only two arguments are passed,
|
441
441
|
// the first argument is the path, the second is the callback and the verb
|
442
442
|
// is assumed to be 'any'.
|
443
443
|
// +path+:: A Regexp or a String representing the path to match to invoke this verb.
|
@@ -447,7 +447,7 @@
|
|
447
447
|
//
|
448
448
|
route: function(verb, path, callback) {
|
449
449
|
var app = this, param_names = [], add_route;
|
450
|
-
|
450
|
+
|
451
451
|
// if the method signature is just (path, callback)
|
452
452
|
// assume the verb is 'any'
|
453
453
|
if (!callback && $.isFunction(path)) {
|
@@ -455,17 +455,17 @@
|
|
455
455
|
callback = path;
|
456
456
|
verb = 'any';
|
457
457
|
}
|
458
|
-
|
458
|
+
|
459
459
|
verb = verb.toLowerCase(); // ensure verb is lower case
|
460
|
-
|
460
|
+
|
461
461
|
// if path is a string turn it into a regex
|
462
462
|
if (path.constructor == String) {
|
463
|
-
|
463
|
+
|
464
464
|
// Needs to be explicitly set because IE will maintain the index unless NULL is returned,
|
465
465
|
// which means that with two consecutive routes that contain params, the second set of params will not be found and end up in splat instead of params
|
466
|
-
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/RegExp/lastIndex
|
466
|
+
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/RegExp/lastIndex
|
467
467
|
PATH_NAME_MATCHER.lastIndex = 0;
|
468
|
-
|
468
|
+
|
469
469
|
// find the names
|
470
470
|
while ((path_match = PATH_NAME_MATCHER.exec(path)) != null) {
|
471
471
|
param_names.push(path_match[1]);
|
@@ -477,7 +477,7 @@
|
|
477
477
|
if (typeof callback == 'string') {
|
478
478
|
callback = app[callback];
|
479
479
|
}
|
480
|
-
|
480
|
+
|
481
481
|
add_route = function(with_verb) {
|
482
482
|
var r = {verb: with_verb, path: path, callback: callback, param_names: param_names};
|
483
483
|
// add route to routes array
|
@@ -485,32 +485,32 @@
|
|
485
485
|
// place routes in order of definition
|
486
486
|
app.routes[with_verb].push(r);
|
487
487
|
}
|
488
|
-
|
488
|
+
|
489
489
|
if (verb === 'any') {
|
490
490
|
$.each(this.ROUTE_VERBS, function(i, v) { add_route(v) });
|
491
491
|
} else {
|
492
492
|
add_route(verb)
|
493
493
|
}
|
494
|
-
|
494
|
+
|
495
495
|
// return the app
|
496
496
|
return this;
|
497
497
|
},
|
498
|
-
|
498
|
+
|
499
499
|
// Alias for route('get', ...)
|
500
500
|
get: _routeWrapper('get'),
|
501
|
-
|
501
|
+
|
502
502
|
// Alias for route('post', ...)
|
503
503
|
post: _routeWrapper('post'),
|
504
504
|
|
505
505
|
// Alias for route('put', ...)
|
506
506
|
put: _routeWrapper('put'),
|
507
|
-
|
507
|
+
|
508
508
|
// Alias for route('delete', ...)
|
509
509
|
del: _routeWrapper('delete'),
|
510
|
-
|
510
|
+
|
511
511
|
// Alias for route('any', ...)
|
512
512
|
any: _routeWrapper('any'),
|
513
|
-
|
513
|
+
|
514
514
|
// <tt>mapRoutes</tt> takes an array of arrays, each array being passed to route()
|
515
515
|
// as arguments, this allows for mass definition of routes. Another benefit is
|
516
516
|
// this makes it possible/easier to load routes via remote JSON.
|
@@ -518,7 +518,7 @@
|
|
518
518
|
// === Example
|
519
519
|
//
|
520
520
|
// var app = $.sammy(function() {
|
521
|
-
//
|
521
|
+
//
|
522
522
|
// this.mapRoutes([
|
523
523
|
// ['get', '#/', function() { this.log('index'); }],
|
524
524
|
// // strings in callbacks are looked up as methods on the app
|
@@ -535,13 +535,13 @@
|
|
535
535
|
});
|
536
536
|
return this;
|
537
537
|
},
|
538
|
-
|
538
|
+
|
539
539
|
// A unique event namespace defined per application.
|
540
540
|
// All events bound with <tt>bind()</tt> are automatically bound within this space.
|
541
541
|
eventNamespace: function() {
|
542
542
|
return [this.data_store_name, this.namespace].join('-');
|
543
543
|
},
|
544
|
-
|
544
|
+
|
545
545
|
// Works just like <tt>jQuery.fn.bind()</tt> with a couple noteable differences.
|
546
546
|
//
|
547
547
|
// * It binds all events to the application element
|
@@ -558,9 +558,9 @@
|
|
558
558
|
if (typeof callback == 'undefined') callback = data;
|
559
559
|
var listener_callback = function() {
|
560
560
|
// pull off the context from the arguments to the callback
|
561
|
-
var e, context, data;
|
561
|
+
var e, context, data;
|
562
562
|
e = arguments[0];
|
563
|
-
data = arguments[1];
|
563
|
+
data = arguments[1];
|
564
564
|
if (data && data['context']) {
|
565
565
|
context = data['context']
|
566
566
|
delete data['context'];
|
@@ -570,7 +570,7 @@
|
|
570
570
|
e.cleaned_type = e.type.replace(app.eventNamespace(), '');
|
571
571
|
callback.apply(context, [e, data]);
|
572
572
|
};
|
573
|
-
|
573
|
+
|
574
574
|
// it could be that the app element doesnt exist yet
|
575
575
|
// so attach to the listeners array and then run()
|
576
576
|
// will actually bind the event.
|
@@ -583,58 +583,58 @@
|
|
583
583
|
}
|
584
584
|
return this;
|
585
585
|
},
|
586
|
-
|
586
|
+
|
587
587
|
// Triggers custom events defined with <tt>bind()</tt>
|
588
588
|
//
|
589
589
|
// === Arguments
|
590
|
-
//
|
590
|
+
//
|
591
591
|
// +name+:: The name of the event. Automatically prefixed with the <tt>eventNamespace()</tt>
|
592
592
|
// +data+:: An optional Object that can be passed to the bound callback.
|
593
|
-
// +context+:: An optional context/Object in which to execute the bound callback.
|
593
|
+
// +context+:: An optional context/Object in which to execute the bound callback.
|
594
594
|
// If no context is supplied a the context is a new <tt>Sammy.EventContext</tt>
|
595
595
|
//
|
596
596
|
trigger: function(name, data) {
|
597
597
|
this.$element().trigger([name, this.eventNamespace()].join('.'), [data]);
|
598
598
|
return this;
|
599
599
|
},
|
600
|
-
|
600
|
+
|
601
601
|
// Reruns the current route
|
602
602
|
refresh: function() {
|
603
603
|
this.last_location = null;
|
604
604
|
this.trigger('location-changed');
|
605
605
|
return this;
|
606
606
|
},
|
607
|
-
|
607
|
+
|
608
608
|
// Takes a single callback that is pushed on to a stack.
|
609
|
-
// Before any route is run, the callbacks are evaluated in order within
|
609
|
+
// Before any route is run, the callbacks are evaluated in order within
|
610
610
|
// the current <tt>Sammy.EventContext</tt>
|
611
611
|
//
|
612
|
-
// If any of the callbacks explicitly return false, execution of any
|
612
|
+
// If any of the callbacks explicitly return false, execution of any
|
613
613
|
// further callbacks and the route itself is halted.
|
614
|
-
//
|
614
|
+
//
|
615
615
|
// You can also provide a set of options that will define when to run this
|
616
|
-
// before based on the route it proceeds.
|
616
|
+
// before based on the route it proceeds.
|
617
617
|
//
|
618
618
|
// === Example
|
619
619
|
//
|
620
620
|
// var app = $.sammy(function() {
|
621
|
-
//
|
621
|
+
//
|
622
622
|
// // will run at #/route but not at #/
|
623
623
|
// this.before('#/route', function() {
|
624
624
|
// //...
|
625
625
|
// });
|
626
|
-
//
|
626
|
+
//
|
627
627
|
// // will run at #/ but not at #/route
|
628
628
|
// this.before({except: {path: '#/route'}}, function() {
|
629
629
|
// this.log('not before #/route');
|
630
630
|
// });
|
631
|
-
//
|
631
|
+
//
|
632
632
|
// this.get('#/', function() {});
|
633
|
-
//
|
633
|
+
//
|
634
634
|
// this.get('#/route', function() {});
|
635
|
-
//
|
635
|
+
//
|
636
636
|
// });
|
637
|
-
//
|
637
|
+
//
|
638
638
|
// See <tt>contextMatchesOptions()</tt> for a full list of supported options
|
639
639
|
//
|
640
640
|
before: function(options, callback) {
|
@@ -645,18 +645,18 @@
|
|
645
645
|
this.befores.push([options, callback]);
|
646
646
|
return this;
|
647
647
|
},
|
648
|
-
|
648
|
+
|
649
649
|
// A shortcut for binding a callback to be run after a route is executed.
|
650
650
|
// After callbacks have no guarunteed order.
|
651
651
|
after: function(callback) {
|
652
652
|
return this.bind('event-context-after', callback);
|
653
653
|
},
|
654
|
-
|
655
|
-
|
654
|
+
|
655
|
+
|
656
656
|
// Adds an around filter to the application. around filters are functions
|
657
|
-
// that take a single argument <tt>callback</tt> which is the entire route
|
657
|
+
// that take a single argument <tt>callback</tt> which is the entire route
|
658
658
|
// execution path wrapped up in a closure. This means you can decide whether
|
659
|
-
// or not to proceed with execution by not invoking <tt>callback</tt> or,
|
659
|
+
// or not to proceed with execution by not invoking <tt>callback</tt> or,
|
660
660
|
// more usefuly wrapping callback inside the result of an asynchronous execution.
|
661
661
|
//
|
662
662
|
// === Example
|
@@ -665,11 +665,11 @@
|
|
665
665
|
// and executing the route within the functions callback:
|
666
666
|
//
|
667
667
|
// var app = $.sammy(function() {
|
668
|
-
//
|
668
|
+
//
|
669
669
|
// var current_user = false;
|
670
|
-
//
|
670
|
+
//
|
671
671
|
// function checkLoggedIn(callback) {
|
672
|
-
// // /session returns a JSON representation of the logged in user
|
672
|
+
// // /session returns a JSON representation of the logged in user
|
673
673
|
// // or an empty object
|
674
674
|
// if (!current_user) {
|
675
675
|
// $.getJSON('/session', function(json) {
|
@@ -690,74 +690,74 @@
|
|
690
690
|
// callback();
|
691
691
|
// }
|
692
692
|
// };
|
693
|
-
//
|
693
|
+
//
|
694
694
|
// this.around(checkLoggedIn);
|
695
|
-
//
|
695
|
+
//
|
696
696
|
// });
|
697
697
|
//
|
698
698
|
around: function(callback) {
|
699
699
|
this.arounds.push(callback);
|
700
700
|
return this;
|
701
701
|
},
|
702
|
-
|
702
|
+
|
703
703
|
// Returns a boolean of weather the current application is running.
|
704
704
|
isRunning: function() {
|
705
705
|
return this._running;
|
706
706
|
},
|
707
|
-
|
707
|
+
|
708
708
|
// Helpers extends the EventContext prototype specific to this app.
|
709
709
|
// This allows you to define app specific helper functions that can be used
|
710
710
|
// whenever you're inside of an event context (templates, routes, bind).
|
711
|
-
//
|
711
|
+
//
|
712
712
|
// === Example
|
713
713
|
//
|
714
714
|
// var app = $.sammy(function() {
|
715
|
-
//
|
715
|
+
//
|
716
716
|
// helpers({
|
717
717
|
// upcase: function(text) {
|
718
718
|
// return text.toString().toUpperCase();
|
719
719
|
// }
|
720
720
|
// });
|
721
|
-
//
|
721
|
+
//
|
722
722
|
// get('#/', function() { with(this) {
|
723
723
|
// // inside of this context I can use the helpers
|
724
724
|
// $('#main').html(upcase($('#main').text());
|
725
725
|
// }});
|
726
|
-
//
|
726
|
+
//
|
727
727
|
// });
|
728
728
|
//
|
729
|
-
//
|
729
|
+
//
|
730
730
|
// === Arguments
|
731
|
-
//
|
731
|
+
//
|
732
732
|
// +extensions+:: An object collection of functions to extend the context.
|
733
|
-
//
|
733
|
+
//
|
734
734
|
helpers: function(extensions) {
|
735
735
|
$.extend(this.context_prototype.prototype, extensions);
|
736
736
|
return this;
|
737
737
|
},
|
738
|
-
|
738
|
+
|
739
739
|
// Helper extends the event context just like <tt>helpers()</tt> but does it
|
740
|
-
// a single method at a time. This is especially useful for dynamically named
|
740
|
+
// a single method at a time. This is especially useful for dynamically named
|
741
741
|
// helpers
|
742
|
-
//
|
742
|
+
//
|
743
743
|
// === Example
|
744
|
-
//
|
744
|
+
//
|
745
745
|
// // Trivial example that adds 3 helper methods to the context dynamically
|
746
746
|
// var app = $.sammy(function(app) {
|
747
|
-
//
|
747
|
+
//
|
748
748
|
// $.each([1,2,3], function(i, num) {
|
749
749
|
// app.helper('helper' + num, function() {
|
750
750
|
// this.log("I'm helper number " + num);
|
751
|
-
// });
|
751
|
+
// });
|
752
752
|
// });
|
753
|
-
//
|
753
|
+
//
|
754
754
|
// this.get('#/', function() {
|
755
755
|
// this.helper2(); //=> I'm helper number 2
|
756
756
|
// });
|
757
757
|
// });
|
758
|
-
//
|
758
|
+
//
|
759
759
|
// === Arguments
|
760
|
-
//
|
760
|
+
//
|
761
761
|
// +name+:: The name of the method
|
762
762
|
// +method+:: The function to be added to the prototype at <tt>name</tt>
|
763
763
|
//
|
@@ -765,12 +765,12 @@
|
|
765
765
|
this.context_prototype.prototype[name] = method;
|
766
766
|
return this;
|
767
767
|
},
|
768
|
-
|
768
|
+
|
769
769
|
// Actually starts the application's lifecycle. <tt>run()</tt> should be invoked
|
770
770
|
// within a document.ready block to ensure the DOM exists before binding events, etc.
|
771
771
|
//
|
772
772
|
// === Example
|
773
|
-
//
|
773
|
+
//
|
774
774
|
// var app = $.sammy(function() { ... }); // your application
|
775
775
|
// $(function() { // document.ready
|
776
776
|
// app.run();
|
@@ -778,19 +778,19 @@
|
|
778
778
|
//
|
779
779
|
// === Arguments
|
780
780
|
//
|
781
|
-
// +start_url+:: "value", Optionally, a String can be passed which the App will redirect to
|
781
|
+
// +start_url+:: "value", Optionally, a String can be passed which the App will redirect to
|
782
782
|
// after the events/routes have been bound.
|
783
783
|
run: function(start_url) {
|
784
784
|
if (this.isRunning()) return false;
|
785
785
|
var app = this;
|
786
|
-
|
786
|
+
|
787
787
|
// actually bind all the listeners
|
788
788
|
$.each(this.listeners.toHash(), function(name, callbacks) {
|
789
789
|
$.each(callbacks, function(i, listener_callback) {
|
790
790
|
app._listen(name, listener_callback);
|
791
791
|
});
|
792
792
|
});
|
793
|
-
|
793
|
+
|
794
794
|
this.trigger('run', {start_url: start_url});
|
795
795
|
this._running = true;
|
796
796
|
// set data for app
|
@@ -799,14 +799,14 @@
|
|
799
799
|
this.last_location = null;
|
800
800
|
if (this.getLocation() == '' && typeof start_url != 'undefined') {
|
801
801
|
this.setLocation(start_url);
|
802
|
-
}
|
802
|
+
}
|
803
803
|
// check url
|
804
804
|
this._checkLocation();
|
805
805
|
this.location_proxy.bind();
|
806
806
|
this.bind('location-changed', function() {
|
807
807
|
app._checkLocation();
|
808
808
|
});
|
809
|
-
|
809
|
+
|
810
810
|
// bind to submit to capture post/put/delete routes
|
811
811
|
this.bind('submit', function(e) {
|
812
812
|
var returned = app._checkFormSubmission($(e.target).closest('form'));
|
@@ -817,11 +817,11 @@
|
|
817
817
|
$('body').bind('onunload', function() {
|
818
818
|
app.unload();
|
819
819
|
});
|
820
|
-
|
820
|
+
|
821
821
|
// trigger html changed
|
822
822
|
return this.trigger('changed');
|
823
823
|
},
|
824
|
-
|
824
|
+
|
825
825
|
// The opposite of <tt>run()</tt>, un-binds all event listeners and intervals
|
826
826
|
// <tt>run()</tt> Automaticaly binds a <tt>onunload</tt> event to run this when
|
827
827
|
// the document is closed.
|
@@ -844,11 +844,11 @@
|
|
844
844
|
this._running = false;
|
845
845
|
return this;
|
846
846
|
},
|
847
|
-
|
848
|
-
// Will bind a single callback function to every event that is already
|
847
|
+
|
848
|
+
// Will bind a single callback function to every event that is already
|
849
849
|
// being listened to in the app. This includes all the <tt>APP_EVENTS</tt>
|
850
850
|
// as well as any custom events defined with <tt>bind()</tt>.
|
851
|
-
//
|
851
|
+
//
|
852
852
|
// Used internally for debug logging.
|
853
853
|
bindToAllEvents: function(callback) {
|
854
854
|
var app = this;
|
@@ -870,9 +870,9 @@
|
|
870
870
|
routablePath: function(path) {
|
871
871
|
return path.replace(QUERY_STRING_MATCHER, '');
|
872
872
|
},
|
873
|
-
|
873
|
+
|
874
874
|
// Given a verb and a String path, will return either a route object or false
|
875
|
-
// if a matching route can be found within the current defined set.
|
875
|
+
// if a matching route can be found within the current defined set.
|
876
876
|
lookupRoute: function(verb, path) {
|
877
877
|
var app = this, routed = false;
|
878
878
|
this.trigger('lookup-route', {verb: verb, path: path});
|
@@ -887,16 +887,16 @@
|
|
887
887
|
return routed;
|
888
888
|
},
|
889
889
|
|
890
|
-
// First, invokes <tt>lookupRoute()</tt> and if a route is found, parses the
|
890
|
+
// First, invokes <tt>lookupRoute()</tt> and if a route is found, parses the
|
891
891
|
// possible URL params and then invokes the route's callback within a new
|
892
|
-
// <tt>Sammy.EventContext</tt>. If the route can not be found, it calls
|
892
|
+
// <tt>Sammy.EventContext</tt>. If the route can not be found, it calls
|
893
893
|
// <tt>notFound()</tt> and raise an error. If <tt>silence_404</tt> is <tt>true</tt>
|
894
894
|
// this error will be caught be the internal methods that call <tt>runRoute</tt>.
|
895
895
|
//
|
896
896
|
// You probably will never have to call this directly.
|
897
897
|
//
|
898
898
|
// === Arguments
|
899
|
-
//
|
899
|
+
//
|
900
900
|
// +verb+:: A String for the verb.
|
901
901
|
// +path+:: A String path to lookup.
|
902
902
|
// +params+:: An Object of Params pulled from the URI or passed directly.
|
@@ -911,7 +911,7 @@
|
|
911
911
|
if (typeof params == 'undefined') params = {};
|
912
912
|
|
913
913
|
$.extend(params, this._parseQueryString(path));
|
914
|
-
|
914
|
+
|
915
915
|
var app = this, context, wrapped_route, arounds, around, befores, before,
|
916
916
|
route = this.lookupRoute(verb, path);
|
917
917
|
if (route) {
|
@@ -933,12 +933,12 @@
|
|
933
933
|
}
|
934
934
|
});
|
935
935
|
}
|
936
|
-
|
936
|
+
|
937
937
|
// set event context
|
938
938
|
context = new this.context_prototype(this, verb, path, params);
|
939
939
|
// ensure arrays
|
940
|
-
arounds = this.arounds.slice(0);
|
941
|
-
befores = this.befores.slice(0);
|
940
|
+
arounds = this.arounds.slice(0);
|
941
|
+
befores = this.befores.slice(0);
|
942
942
|
// wrap the route up with the before filters
|
943
943
|
wrapped_route = function() {
|
944
944
|
var returned;
|
@@ -965,18 +965,18 @@
|
|
965
965
|
this.notFound(verb, path);
|
966
966
|
}
|
967
967
|
},
|
968
|
-
|
968
|
+
|
969
969
|
// Matches an object of options against an <tt>EventContext</tt> like object that
|
970
970
|
// contains <tt>path</tt> and <tt>verb</tt> attributes. Internally Sammy uses this
|
971
|
-
// for matching <tt>before()</tt> filters against specific options. You can set the
|
971
|
+
// for matching <tt>before()</tt> filters against specific options. You can set the
|
972
972
|
// object to _only_ match certain paths or verbs, or match all paths or verbs _except_
|
973
973
|
// those that match the options.
|
974
974
|
//
|
975
975
|
// === Example
|
976
|
-
//
|
976
|
+
//
|
977
977
|
// var app = $.sammy(),
|
978
978
|
// context = {verb: 'get', path: '#/mypath'};
|
979
|
-
//
|
979
|
+
//
|
980
980
|
// // match against a path string
|
981
981
|
// app.contextMatchesOptions(context, '#/mypath'); //=> true
|
982
982
|
// app.contextMatchesOptions(context, '#/otherpath'); //=> false
|
@@ -995,7 +995,7 @@
|
|
995
995
|
// // match all except a path
|
996
996
|
// app.contextMatchesOptions(context, {except: {path:'#/otherpath'}}); //=> true
|
997
997
|
// app.contextMatchesOptions(context, {except: {path:'#/mypath'}}); //=> false
|
998
|
-
//
|
998
|
+
//
|
999
999
|
contextMatchesOptions: function(context, match_options, positive) {
|
1000
1000
|
// empty options always match
|
1001
1001
|
var options = match_options;
|
@@ -1012,7 +1012,7 @@
|
|
1012
1012
|
if (options.only) {
|
1013
1013
|
return this.contextMatchesOptions(context, options.only, true);
|
1014
1014
|
} else if (options.except) {
|
1015
|
-
return this.contextMatchesOptions(context, options.except, false);
|
1015
|
+
return this.contextMatchesOptions(context, options.except, false);
|
1016
1016
|
}
|
1017
1017
|
var path_matched = true, verb_matched = true;
|
1018
1018
|
if (options.path) {
|
@@ -1028,55 +1028,55 @@
|
|
1028
1028
|
}
|
1029
1029
|
return positive ? (verb_matched && path_matched) : !(verb_matched && path_matched);
|
1030
1030
|
},
|
1031
|
-
|
1031
|
+
|
1032
1032
|
|
1033
1033
|
// Delegates to the <tt>location_proxy</tt> to get the current location.
|
1034
1034
|
// See <tt>Sammy.HashLocationProxy</tt> for more info on location proxies.
|
1035
1035
|
getLocation: function() {
|
1036
1036
|
return this.location_proxy.getLocation()
|
1037
1037
|
},
|
1038
|
-
|
1038
|
+
|
1039
1039
|
// Delegates to the <tt>location_proxy</tt> to set the current location.
|
1040
1040
|
// See <tt>Sammy.HashLocationProxy</tt> for more info on location proxies.
|
1041
1041
|
//
|
1042
1042
|
// === Arguments
|
1043
|
-
//
|
1043
|
+
//
|
1044
1044
|
// +new_location+:: A new location string (e.g. '#/')
|
1045
1045
|
//
|
1046
1046
|
setLocation: function(new_location) {
|
1047
1047
|
return this.location_proxy.setLocation(new_location);
|
1048
1048
|
},
|
1049
|
-
|
1049
|
+
|
1050
1050
|
// Swaps the content of <tt>$element()</tt> with <tt>content</tt>
|
1051
1051
|
// You can override this method to provide an alternate swap behavior
|
1052
1052
|
// for <tt>EventContext.partial()</tt>.
|
1053
|
-
//
|
1053
|
+
//
|
1054
1054
|
// === Example
|
1055
1055
|
//
|
1056
1056
|
// var app = $.sammy(function() {
|
1057
|
-
//
|
1057
|
+
//
|
1058
1058
|
// // implements a 'fade out'/'fade in'
|
1059
1059
|
// this.swap = function(content) {
|
1060
1060
|
// this.$element().hide('slow').html(content).show('slow');
|
1061
1061
|
// }
|
1062
|
-
//
|
1062
|
+
//
|
1063
1063
|
// get('#/', function() {
|
1064
1064
|
// this.partial('index.html.erb') // will fade out and in
|
1065
1065
|
// });
|
1066
|
-
//
|
1066
|
+
//
|
1067
1067
|
// });
|
1068
1068
|
//
|
1069
1069
|
swap: function(content) {
|
1070
1070
|
return this.$element().html(content);
|
1071
1071
|
},
|
1072
|
-
|
1072
|
+
|
1073
1073
|
// This thows a '404 Not Found' error. Override this method to provide custom
|
1074
1074
|
// 404 behavior (i.e redirecting to / or showing a warning)
|
1075
1075
|
notFound: function(verb, path) {
|
1076
1076
|
this.trigger('error-404', {verb: verb, path: path});
|
1077
1077
|
throw('404 Not Found ' + verb + ' ' + path);
|
1078
1078
|
},
|
1079
|
-
|
1079
|
+
|
1080
1080
|
_checkLocation: function() {
|
1081
1081
|
try { // try, catch 404s
|
1082
1082
|
// get current location
|
@@ -1101,7 +1101,7 @@
|
|
1101
1101
|
}
|
1102
1102
|
return returned;
|
1103
1103
|
},
|
1104
|
-
|
1104
|
+
|
1105
1105
|
_checkFormSubmission: function(form) {
|
1106
1106
|
var $form, path, verb, params, returned;
|
1107
1107
|
this.trigger('check-form-submission', {form: form});
|
@@ -1122,7 +1122,7 @@
|
|
1122
1122
|
}
|
1123
1123
|
return (typeof returned == 'undefined') ? false : returned;
|
1124
1124
|
},
|
1125
|
-
|
1125
|
+
|
1126
1126
|
_parseFormParams: function($form) {
|
1127
1127
|
var params = {};
|
1128
1128
|
$.each($form.serializeArray(), function(i, field) {
|
@@ -1138,7 +1138,7 @@
|
|
1138
1138
|
});
|
1139
1139
|
return params;
|
1140
1140
|
},
|
1141
|
-
|
1141
|
+
|
1142
1142
|
_parseQueryString: function(path) {
|
1143
1143
|
var query = {}, parts, pairs, pair, i;
|
1144
1144
|
|
@@ -1153,21 +1153,21 @@
|
|
1153
1153
|
|
1154
1154
|
return query;
|
1155
1155
|
},
|
1156
|
-
|
1156
|
+
|
1157
1157
|
_listen: function(name, callback) {
|
1158
1158
|
return this.$element().bind([name, this.eventNamespace()].join('.'), callback);
|
1159
1159
|
},
|
1160
|
-
|
1160
|
+
|
1161
1161
|
_unlisten: function(name, callback) {
|
1162
1162
|
return this.$element().unbind([name, this.eventNamespace()].join('.'), callback);
|
1163
1163
|
}
|
1164
1164
|
|
1165
1165
|
});
|
1166
|
-
|
1167
|
-
// <tt>Sammy.EventContext</tt> objects are created every time a route is run or a
|
1166
|
+
|
1167
|
+
// <tt>Sammy.EventContext</tt> objects are created every time a route is run or a
|
1168
1168
|
// bound event is triggered. The callbacks for these events are evaluated within a <tt>Sammy.EventContext</tt>
|
1169
1169
|
// This within these callbacks the special methods of <tt>EventContext</tt> are available.
|
1170
|
-
//
|
1170
|
+
//
|
1171
1171
|
// === Example
|
1172
1172
|
//
|
1173
1173
|
// $.sammy(function() { with(this) {
|
@@ -1197,21 +1197,21 @@
|
|
1197
1197
|
this.path = path;
|
1198
1198
|
this.params = new Sammy.Object(params);
|
1199
1199
|
}
|
1200
|
-
|
1200
|
+
|
1201
1201
|
Sammy.EventContext.prototype = $.extend({}, Sammy.Object.prototype, {
|
1202
|
-
|
1202
|
+
|
1203
1203
|
// A shortcut to the app's <tt>$element()</tt>
|
1204
1204
|
$element: function() {
|
1205
1205
|
return this.app.$element();
|
1206
1206
|
},
|
1207
|
-
|
1207
|
+
|
1208
1208
|
// Used for rendering remote templates or documents within the current application/DOM.
|
1209
1209
|
// By default Sammy and <tt>partial()</tt> know nothing about how your templates
|
1210
1210
|
// should be interpeted/rendered. This is easy to change, though. <tt>partial()</tt> looks
|
1211
1211
|
// for a method in <tt>EventContext</tt> that matches the extension of the file you're
|
1212
1212
|
// fetching (e.g. 'myfile.template' will look for a template() method, 'myfile.haml' => haml(), etc.)
|
1213
|
-
// If no matching render method is found it just takes the file contents as is.
|
1214
|
-
//
|
1213
|
+
// If no matching render method is found it just takes the file contents as is.
|
1214
|
+
//
|
1215
1215
|
// If you're templates have different (or no) extensions, and you want to render them all
|
1216
1216
|
// through the same engine, you can set the default/fallback template engine on the app level
|
1217
1217
|
// by setting <tt>app.template_engine</tt> to the name of the engine or a <tt>function() {}</tt>
|
@@ -1224,38 +1224,38 @@
|
|
1224
1224
|
// === Example
|
1225
1225
|
//
|
1226
1226
|
// There are a couple different ways to use <tt>partial()</tt>:
|
1227
|
-
//
|
1227
|
+
//
|
1228
1228
|
// partial('doc.html');
|
1229
1229
|
// //=> Replaces $element() with the contents of doc.html
|
1230
1230
|
//
|
1231
|
-
// use(Sammy.Template);
|
1231
|
+
// use(Sammy.Template);
|
1232
1232
|
// //=> includes the template() method
|
1233
|
-
// partial('doc.template', {name: 'Sammy'});
|
1233
|
+
// partial('doc.template', {name: 'Sammy'});
|
1234
1234
|
// //=> Replaces $element() with the contents of doc.template run through <tt>template()</tt>
|
1235
1235
|
//
|
1236
1236
|
// partial('doc.html', function(data) {
|
1237
1237
|
// // data is the contents of the template.
|
1238
|
-
// $('.other-selector').html(data);
|
1238
|
+
// $('.other-selector').html(data);
|
1239
1239
|
// });
|
1240
1240
|
//
|
1241
1241
|
// === Iteration/Arrays
|
1242
1242
|
//
|
1243
|
-
// If the data object passed to <tt>partial()</tt> is an Array, <tt>partial()</tt>
|
1244
|
-
// will itterate over each element in data calling the callback with the
|
1243
|
+
// If the data object passed to <tt>partial()</tt> is an Array, <tt>partial()</tt>
|
1244
|
+
// will itterate over each element in data calling the callback with the
|
1245
1245
|
// results of interpolation and the index of the element in the array.
|
1246
|
-
//
|
1246
|
+
//
|
1247
1247
|
// use(Sammy.Template);
|
1248
1248
|
// // item.template => "<li>I'm an item named <%= name %></li>"
|
1249
1249
|
// partial('item.template', [{name: "Item 1"}, {name: "Item 2"}])
|
1250
|
-
// //=> Replaces $element() with:
|
1250
|
+
// //=> Replaces $element() with:
|
1251
1251
|
// // <li>I'm an item named Item 1</li><li>I'm an item named Item 2</li>
|
1252
1252
|
// partial('item.template', [{name: "Item 1"}, {name: "Item 2"}], function(rendered, i) {
|
1253
1253
|
// rendered; //=> <li>I'm an item named Item 1</li> // for each element in the Array
|
1254
1254
|
// i; // the 0 based index of the itteration
|
1255
1255
|
// });
|
1256
|
-
//
|
1256
|
+
//
|
1257
1257
|
partial: function(path, data, callback) {
|
1258
|
-
var file_data,
|
1258
|
+
var file_data,
|
1259
1259
|
wrapped_callback,
|
1260
1260
|
engine,
|
1261
1261
|
data_array,
|
@@ -1268,8 +1268,8 @@
|
|
1268
1268
|
if ((!engine || !$.isFunction(context[engine])) && this.app.template_engine) {
|
1269
1269
|
engine = this.app.template_engine;
|
1270
1270
|
}
|
1271
|
-
if (engine && !$.isFunction(engine) && $.isFunction(context[engine])) {
|
1272
|
-
engine = context[engine];
|
1271
|
+
if (engine && !$.isFunction(engine) && $.isFunction(context[engine])) {
|
1272
|
+
engine = context[engine];
|
1273
1273
|
}
|
1274
1274
|
if (!callback && $.isFunction(data)) {
|
1275
1275
|
// callback is in the data position
|
@@ -1282,17 +1282,17 @@
|
|
1282
1282
|
all_content = "";
|
1283
1283
|
$.each(data_array, function(i, idata) {
|
1284
1284
|
// extend the data object with the context
|
1285
|
-
$.extend(idata, context);
|
1285
|
+
$.extend(idata, context);
|
1286
1286
|
if ($.isFunction(engine)) {
|
1287
1287
|
new_content = engine.apply(context, [response, idata]);
|
1288
|
-
}
|
1288
|
+
}
|
1289
1289
|
// collect the content
|
1290
1290
|
all_content += new_content;
|
1291
1291
|
// if callback exists call it for each iteration
|
1292
|
-
if (callback) {
|
1293
|
-
// return the result of the callback
|
1292
|
+
if (callback) {
|
1293
|
+
// return the result of the callback
|
1294
1294
|
// (you can bail the loop by returning false)
|
1295
|
-
return callback.apply(context, [new_content, i]);
|
1295
|
+
return callback.apply(context, [new_content, i]);
|
1296
1296
|
}
|
1297
1297
|
});
|
1298
1298
|
if (!callback) { context.app.swap(all_content); }
|
@@ -1309,8 +1309,8 @@
|
|
1309
1309
|
});
|
1310
1310
|
}
|
1311
1311
|
},
|
1312
|
-
|
1313
|
-
// Changes the location of the current window. If <tt>to</tt> begins with
|
1312
|
+
|
1313
|
+
// Changes the location of the current window. If <tt>to</tt> begins with
|
1314
1314
|
// '#' it only changes the document's hash. If passed more than 1 argument
|
1315
1315
|
// redirect will join them together with forward slashes.
|
1316
1316
|
//
|
@@ -1321,7 +1321,7 @@
|
|
1321
1321
|
// redirect('#', 'other', 'route');
|
1322
1322
|
//
|
1323
1323
|
redirect: function() {
|
1324
|
-
var to, args = $.makeArray(arguments),
|
1324
|
+
var to, args = $.makeArray(arguments),
|
1325
1325
|
current_location = this.app.getLocation();
|
1326
1326
|
if (args.length > 1) {
|
1327
1327
|
args.unshift('/');
|
@@ -1336,32 +1336,32 @@
|
|
1336
1336
|
this.app.trigger('location-changed');
|
1337
1337
|
}
|
1338
1338
|
},
|
1339
|
-
|
1339
|
+
|
1340
1340
|
// Triggers events on <tt>app</tt> within the current context.
|
1341
1341
|
trigger: function(name, data) {
|
1342
|
-
if (typeof data == 'undefined') data = {};
|
1342
|
+
if (typeof data == 'undefined') data = {};
|
1343
1343
|
if (!data.context) data.context = this;
|
1344
1344
|
return this.app.trigger(name, data);
|
1345
1345
|
},
|
1346
|
-
|
1346
|
+
|
1347
1347
|
// A shortcut to app's <tt>eventNamespace()</tt>
|
1348
1348
|
eventNamespace: function() {
|
1349
1349
|
return this.app.eventNamespace();
|
1350
1350
|
},
|
1351
|
-
|
1351
|
+
|
1352
1352
|
// Raises a possible <tt>notFound()</tt> error for the current path.
|
1353
1353
|
notFound: function() {
|
1354
1354
|
return this.app.notFound(this.verb, this.path);
|
1355
1355
|
},
|
1356
|
-
|
1356
|
+
|
1357
1357
|
// //=> Sammy.EventContext: get #/ {}
|
1358
1358
|
toString: function() {
|
1359
1359
|
return "Sammy.EventContext: " + [this.verb, this.path, this.params].join(' ');
|
1360
1360
|
}
|
1361
|
-
|
1361
|
+
|
1362
1362
|
});
|
1363
|
-
|
1363
|
+
|
1364
1364
|
// An alias to Sammy
|
1365
1365
|
$.sammy = Sammy;
|
1366
1366
|
|
1367
|
-
})(jQuery);
|
1367
|
+
})(jQuery);
|