soca 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ # A sample Gemfile
2
+ source "http://rubygems.org"
3
+
4
+ gem 'json', '~>1.4.6'
5
+ gem 'mime-types', '~>1.16'
6
+ gem 'typhoeus', '~>0.2'
7
+ gem 'thor', '~>0.14.0'
8
+ gem 'jim', '~>0.3.1'
9
+ gem 'compass', '~>0.10.5'
10
+ gem 'mustache', '~>0.11.2'
11
+ gem 'coffee-script', '~> 2.1.2'
12
+ group :development do
13
+ gem 'rake'
14
+ gem 'jeweler'
15
+ gem "shoulda", ">= 0"
16
+ gem "yard", ">= 0"
17
+ end
@@ -0,0 +1,74 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ archive-tar-minitar (0.5.2)
5
+ coffee-script (2.1.3)
6
+ coffee-script-source
7
+ coffee-script-source (1.0.1)
8
+ compass (0.10.6)
9
+ haml (>= 3.0.4)
10
+ downlow (0.1.4)
11
+ archive-tar-minitar (>= 0.5.2)
12
+ rubyzip (>= 0.9.4)
13
+ fakeweb (1.3.0)
14
+ fssm (0.2.5)
15
+ git (1.2.5)
16
+ haml (3.0.25)
17
+ jeweler (1.5.2)
18
+ bundler (~> 1.0.0)
19
+ git (>= 1.2.5)
20
+ rake
21
+ jim (0.3.1)
22
+ downlow (~> 0.1.4)
23
+ downlow (~> 0.1.3)
24
+ fakeweb (>= 1.2.8)
25
+ fssm
26
+ fssm (~> 0.2.0)
27
+ jeweler
28
+ leftright
29
+ mocha
30
+ rack-test
31
+ rake
32
+ shoulda
33
+ test-unit
34
+ thor (~> 0.14.4)
35
+ thor
36
+ version_sorter (~> 1.1.0)
37
+ version_sorter (~> 1.1.0)
38
+ yajl-ruby
39
+ yajl-ruby
40
+ json (1.4.6)
41
+ leftright (0.9.0)
42
+ mime-types (1.16)
43
+ mocha (0.9.10)
44
+ rake
45
+ mustache (0.11.2)
46
+ rack (1.2.1)
47
+ rack-test (0.5.7)
48
+ rack (>= 1.0)
49
+ rake (0.8.7)
50
+ rubyzip (0.9.4)
51
+ shoulda (2.11.3)
52
+ test-unit (2.1.2)
53
+ thor (0.14.6)
54
+ typhoeus (0.2.0)
55
+ version_sorter (1.1.0)
56
+ yajl-ruby (0.8.0)
57
+ yard (0.6.4)
58
+
59
+ PLATFORMS
60
+ ruby
61
+
62
+ DEPENDENCIES
63
+ coffee-script (~> 2.1.2)
64
+ compass (~> 0.10.5)
65
+ jeweler
66
+ jim (~> 0.3.1)
67
+ json (~> 1.4.6)
68
+ mime-types (~> 1.16)
69
+ mustache (~> 0.11.2)
70
+ rake
71
+ shoulda
72
+ thor (~> 0.14.0)
73
+ typhoeus (~> 0.2)
74
+ yard
data/HISTORY CHANGED
@@ -1,3 +1,15 @@
1
+ == 0.2.0 [03-02-11]
2
+
3
+ - Allow rewrite rules to be pushed with rewrites.js
4
+ - Upgrade to jim 0.3.1 and the new Jimfile format
5
+ - Added CoffeScript plugin and tools (rmetzler and andrzejsliwa)
6
+ - Added python CouchApp style macros (!json, !code, etc) in the macro plugin (narkisr)
7
+ - Added proper mapping for `index.html` in `config.js` for the `test/testapp` (karmi)
8
+ - Fix for Thor swallowing --debug option (candlerb)
9
+ - Show path matching in debug output (candlerb)
10
+ - Make mapped_directories an array, for processing in order on ruby 1.8 (candlerb)
11
+ - Upgraded to Sammy 0.6.3
12
+
1
13
  == 0.1.2 [10-26-10]
2
14
 
3
15
  - Added mustache plugin for interpolating env and config data into static HTML
@@ -13,4 +25,4 @@
13
25
 
14
26
  == 0.1.0 [09-26-10]
15
27
 
16
- - Initial Release
28
+ - Initial Release
data/Rakefile CHANGED
@@ -1,5 +1,7 @@
1
1
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
2
- require 'lib/soca'
2
+ require 'soca'
3
+ require 'bundler'
4
+ Bundler.require
3
5
 
4
6
  begin
5
7
  require 'jeweler'
@@ -13,11 +15,12 @@ begin
13
15
  gem.authors = ["Aaron Quint"]
14
16
  gem.add_dependency 'json', '~>1.4.6'
15
17
  gem.add_dependency 'mime-types', '~>1.16'
16
- gem.add_dependency 'typhoeus', '~>0.1.31'
18
+ gem.add_dependency 'typhoeus', '~>0.2'
17
19
  gem.add_dependency 'thor', '~>0.14.0'
18
- gem.add_dependency 'jim', '~>0.2.3'
20
+ gem.add_dependency 'jim', '~>0.3.1'
19
21
  gem.add_dependency 'compass', '~>0.10.5'
20
22
  gem.add_dependency 'mustache', '~>0.11.2'
23
+ gem.add_dependency 'coffee-script', '~> 2.1.2'
21
24
  gem.add_development_dependency "shoulda", ">= 0"
22
25
  gem.add_development_dependency "yard", ">= 0"
23
26
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
@@ -47,7 +50,6 @@ rescue LoadError
47
50
  end
48
51
  end
49
52
 
50
- task :test => :check_dependencies
51
53
 
52
54
  task :default => :test
53
55
 
@@ -7,7 +7,7 @@ require 'logger'
7
7
  $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__))))
8
8
 
9
9
  module Soca
10
- VERSION = '0.1.2'
10
+ VERSION = '0.2.0'
11
11
 
12
12
  class << self
13
13
  attr_accessor :debug
@@ -39,7 +39,7 @@ module Soca
39
39
  end
40
40
  self.appdir = options[:appdir] || File.expand_path(Dir.pwd)
41
41
  self.config_file = options[:config]
42
- self.debug = options[:debug]
42
+ self.debug = self.class.debugging || options[:debug]
43
43
  if debug
44
44
  Soca.debug = true
45
45
  logger.level = Logger::DEBUG
@@ -79,6 +79,7 @@ module Soca
79
79
  directory('db')
80
80
  template('Jimfile')
81
81
  template('index.html.erb', 'index.html')
82
+ template('rewrites.js.erb', 'rewrites.js')
82
83
  @dir_mappings = {
83
84
  "config.js" => "",
84
85
  "index.html" => "_attachments/index.html",
@@ -0,0 +1,43 @@
1
+ require 'coffee-script'
2
+
3
+ module Soca
4
+ module Plugins
5
+ class CoffeeScript < Soca::Plugin
6
+
7
+ name 'coffeescript'
8
+
9
+ # Run the coffeescript plugin.
10
+ # Available options:
11
+ #
12
+ # * :files - Run these files through CoffeeScript. Can be an array of patterns
13
+ # or a single file. The default is '*.coffee'.
14
+ # * :vars - Additional variables to interpolate. By default the `env` and
15
+ # `config` are interpolated.
16
+ #
17
+ def run(options = {})
18
+ file_patterns = options[:files] || '**/*.coffee'
19
+ files = Dir[*[file_patterns].flatten]
20
+ vars = {
21
+ :env => pusher.env,
22
+ :config => pusher.config
23
+ }.merge(options[:vars] || {})
24
+ Soca.logger.debug "CoffeeScript vars: #{vars.inspect}"
25
+
26
+ files.each do |file|
27
+ Soca.logger.debug "Running #{file} through CoffeeScript."
28
+ basename = File.basename(file)
29
+ dir = File.dirname(file)
30
+ parts = basename.split(/\./)
31
+ new_file = (parts.length > 2 ? parts[0..-2].join('.') : parts[0]) + ".js"
32
+
33
+ File.open(File.join(dir, new_file), 'w') do |f|
34
+ f << ::CoffeeScript.compile(File.read(file), vars)
35
+ end
36
+ Soca.logger.debug "Wrote to #{new_file}"
37
+
38
+ end
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,25 @@
1
+ # see http://tinyurl.com/6ab5svl views in coucdb < 1.1.x does not allow require of modules therfor we need to use macors
2
+ module Soca
3
+ module Plugins
4
+ class Macro < Soca::Plugin
5
+
6
+ name 'macro'
7
+
8
+ def run(options = {})
9
+ @pusher.document['views'].each do |view,code|
10
+ ['map','reduce'].each{|part| macro_expand_on(part,code) if code[part]}
11
+ end
12
+ end
13
+
14
+ def macro_expand_on(part,code)
15
+ code[part] = code[part].split("\n").inject(" ") do |res,line|
16
+ if line =~ /\/\/ !code (.*)/
17
+ res += "\n#{File.read($1)}\n"
18
+ else
19
+ res += "#{line}\n"
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -27,7 +27,7 @@ module Soca
27
27
  basename = File.basename(file)
28
28
  dir = File.dirname(file)
29
29
  parts = basename.split(/\./)
30
- new_file = parts.length > 2 ? parts[0..-2].join('.') : basename[0] + ".html"
30
+ new_file = parts.length > 2 ? parts[0..-2].join('.') : parts[0] + ".html"
31
31
  File.open(File.join(dir, new_file), 'w') do |f|
32
32
  f << ::Mustache.render(File.read(file), vars)
33
33
  end
@@ -129,6 +129,7 @@ module Soca
129
129
  file_data = File.read(path)
130
130
  base_path = path.gsub(app_dir, '')
131
131
  if map = mapped_directories.detect {|k,v| k =~ base_path }
132
+ logger.debug "Matched #{path} against #{map.inspect}"
132
133
  if map[1]
133
134
  base_path = base_path.gsub(map[0], map[1])
134
135
  else
@@ -138,6 +139,8 @@ module Soca
138
139
  if base_path =~ /^_attachments/
139
140
  hash['_attachments'] ||= {}
140
141
  hash['_attachments'][base_path.gsub(/_attachments\//, '')] = make_attachment(path, file_data)
142
+ elsif base_path == 'rewrites.js'
143
+ hash['rewrites'] = JSON.parse(file_data)
141
144
  else
142
145
  parts = base_path.gsub(/^\//, '').gsub(/\.js$/, '').split('/')
143
146
  current_hash = hash
@@ -166,8 +169,7 @@ module Soca
166
169
 
167
170
  def mapped_directories
168
171
  return @mapped_directories if @mapped_directories
169
- map = {}
170
- config['mapDirectories'].collect {|k,v| map[/^#{k}/] = v }
172
+ map = config['mapDirectories'].collect {|k,v| [/^#{k}/, v] }
171
173
  @mapped_directories = map
172
174
  end
173
175
 
@@ -175,7 +177,11 @@ module Soca
175
177
  logger.debug "PUT #{url}"
176
178
  logger.debug "body: #{body[0..80]} ..."
177
179
  response = Typhoeus::Request.put(url, :body => body)
178
- logger.debug "Response: #{response.code} #{response.body[0..200]}"
180
+ if response.success? || response.code == 412
181
+ logger.debug "Response: #{response.code} #{response.body[0..200]}"
182
+ else
183
+ logger.error "Response: #{response.code} #{response.body[0..200]}"
184
+ end
179
185
  response
180
186
  end
181
187
 
@@ -1,12 +1,15 @@
1
- // bundled_path: js/default.js
2
- // compressed_path: js/production.js
3
- // vendor_dir: js/vendor
4
-
5
- / start adding your requirements below:
6
-
7
- sha1
8
- jquery 1.4.2
9
- jquery.couch 0.11
10
- sammy 0.6.2
11
- sammy.couch 0.1.0
12
- js/app
1
+ {
2
+ "bundle_dir": "js",
3
+ "compressed_suffix": ".min",
4
+ "vendor_dir": "js/vendor",
5
+ "bundles": {
6
+ "default": [
7
+ "sha1",
8
+ [ "jquery", "1.4.2" ],
9
+ [ "jquery.couch", "0.11" ],
10
+ [ "sammy", "0.6.3" ],
11
+ [ "sammy.couch", "0.1.0" ],
12
+ "js/app"
13
+ ]
14
+ }
15
+ }
@@ -1,2 +1,3 @@
1
1
  # any pre build scripting or plugins should go here
2
+ plugin 'coffeescript'
2
3
  plugin 'jim'
@@ -1,5 +1,7 @@
1
1
  // name: sammy
2
- // version: 0.6.2
2
+ // version: 0.6.3
3
+
4
+ // Sammy.js / http://sammyjs.org
3
5
 
4
6
  (function($, window) {
5
7
 
@@ -12,9 +14,10 @@
12
14
  // borrowed from jQuery
13
15
  _isFunction = function( obj ) { return Object.prototype.toString.call(obj) === "[object Function]"; },
14
16
  _isArray = function( obj ) { return Object.prototype.toString.call(obj) === "[object Array]"; },
15
- _decode = decodeURIComponent,
17
+ _decode = function( str ) { return decodeURIComponent(str.replace(/\+/g, ' ')); },
18
+ _encode = encodeURIComponent,
16
19
  _escapeHTML = function(s) {
17
- return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
20
+ return String(s).replace(/&(?!\w+;)/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
18
21
  },
19
22
  _routeWrapper = function(verb) {
20
23
  return function(path, callback) { return this.route.apply(this, [verb, path, callback]); };
@@ -70,7 +73,7 @@
70
73
  }
71
74
  };
72
75
 
73
- Sammy.VERSION = '0.6.2';
76
+ Sammy.VERSION = '0.6.3';
74
77
 
75
78
  // Add to the global logger pool. Takes a function that accepts an
76
79
  // unknown number of arguments and should print them or send them somewhere
@@ -140,8 +143,9 @@
140
143
  // Does not render functions.
141
144
  // For example. Given this Sammy.Object:
142
145
  //
143
- // var s = new Sammy.Object({first_name: 'Sammy', last_name: 'Davis Jr.'});
144
- // s.toHTML() //=> '<strong>first_name</strong> Sammy<br /><strong>last_name</strong> Davis Jr.<br />'
146
+ // var s = new Sammy.Object({first_name: 'Sammy', last_name: 'Davis Jr.'});
147
+ // s.toHTML()
148
+ // //=> '<strong>first_name</strong> Sammy<br /><strong>last_name</strong> Davis Jr.<br />'
145
149
  //
146
150
  toHTML: function() {
147
151
  var display = "";
@@ -271,7 +275,7 @@
271
275
  current_location != Sammy.HashLocationProxy._last_location) {
272
276
  window.setTimeout(function() {
273
277
  $(window).trigger('hashchange', [true]);
274
- }, 13);
278
+ }, 0);
275
279
  }
276
280
  Sammy.HashLocationProxy._last_location = current_location;
277
281
  };
@@ -318,18 +322,7 @@
318
322
 
319
323
  // An array of the default events triggered by the
320
324
  // application during its lifecycle
321
- APP_EVENTS: ['run',
322
- 'unload',
323
- 'lookup-route',
324
- 'run-route',
325
- 'route-found',
326
- 'event-context-before',
327
- 'event-context-after',
328
- 'changed',
329
- 'error',
330
- 'check-form-submission',
331
- 'redirect',
332
- 'location-changed'],
325
+ APP_EVENTS: ['run', 'unload', 'lookup-route', 'run-route', 'route-found', 'event-context-before', 'event-context-after', 'changed', 'error', 'check-form-submission', 'redirect', 'location-changed'],
333
326
 
334
327
  _last_route: null,
335
328
  _location_proxy: null,
@@ -364,8 +357,8 @@
364
357
  },
365
358
 
366
359
  // returns a jQuery object of the Applications bound element.
367
- $element: function() {
368
- return $(this.element_selector);
360
+ $element: function(selector) {
361
+ return selector ? $(this.element_selector).find(selector) : $(this.element_selector);
369
362
  },
370
363
 
371
364
  // `use()` is the entry point for including Sammy plugins.
@@ -376,7 +369,7 @@
376
369
  // Any additional arguments are passed to the app function sequentially.
377
370
  //
378
371
  // For much more detail about plugins, check out:
379
- // http://code.quirkey.com/sammy/doc/plugins.html
372
+ // [http://sammyjs.org/docs/plugins](http://sammyjs.org/docs/plugins)
380
373
  //
381
374
  // ### Example
382
375
  //
@@ -464,7 +457,8 @@
464
457
  },
465
458
 
466
459
  // `route()` is the main method for defining routes within an application.
467
- // For great detail on routes, check out: http://code.quirkey.com/sammy/doc/routes.html
460
+ // For great detail on routes, check out:
461
+ // [http://sammyjs.org/docs/routes](http://sammyjs.org/docs/routes)
468
462
  //
469
463
  // This method also has aliases for each of the different verbs (eg. `get()`, `post()`, etc.)
470
464
  //
@@ -551,16 +545,16 @@
551
545
  //
552
546
  // ### Example
553
547
  //
554
- // var app = $.sammy(function() {
548
+ // var app = $.sammy(function() {
555
549
  //
556
- // this.mapRoutes([
557
- // ['get', '#/', function() { this.log('index'); }],
558
- // // strings in callbacks are looked up as methods on the app
559
- // ['post', '#/create', 'addUser'],
560
- // // No verb assumes 'any' as the verb
561
- // [/dowhatever/, function() { this.log(this.verb, this.path)}];
562
- // ]);
563
- // })
550
+ // this.mapRoutes([
551
+ // ['get', '#/', function() { this.log('index'); }],
552
+ // // strings in callbacks are looked up as methods on the app
553
+ // ['post', '#/create', 'addUser'],
554
+ // // No verb assumes 'any' as the verb
555
+ // [/dowhatever/, function() { this.log(this.verb, this.path)}];
556
+ // ]);
557
+ // });
564
558
  //
565
559
  mapRoutes: function(route_array) {
566
560
  var app = this;
@@ -583,8 +577,6 @@
583
577
  // * Events are not actually bound until the application is started with `run()`
584
578
  // * callbacks are evaluated within the context of a Sammy.EventContext
585
579
  //
586
- // See http://code.quirkey.com/sammy/docs/events.html for more info.
587
- //
588
580
  bind: function(name, data, callback) {
589
581
  var app = this;
590
582
  // build the callback
@@ -745,20 +737,20 @@
745
737
  //
746
738
  // ### Example
747
739
  //
748
- // var app = $.sammy(function() {
740
+ // var app = $.sammy(function() {
749
741
  //
750
- // helpers({
751
- // upcase: function(text) {
752
- // return text.toString().toUpperCase();
753
- // }
754
- // });
742
+ // helpers({
743
+ // upcase: function(text) {
744
+ // return text.toString().toUpperCase();
745
+ // }
746
+ // });
755
747
  //
756
- // get('#/', function() { with(this) {
757
- // // inside of this context I can use the helpers
758
- // $('#main').html(upcase($('#main').text());
759
- // }});
748
+ // get('#/', function() { with(this) {
749
+ // // inside of this context I can use the helpers
750
+ // $('#main').html(upcase($('#main').text());
751
+ // }});
760
752
  //
761
- // });
753
+ // });
762
754
  //
763
755
  //
764
756
  // ### Arguments
@@ -805,8 +797,8 @@
805
797
  //
806
798
  // ### Example
807
799
  //
808
- // var app = $.sammy(function() { ... }); // your application
809
- // $(function() { // document.ready
800
+ // var app = $.sammy(function() { ... }); // your application
801
+ // $(function() { // document.ready
810
802
  // app.run();
811
803
  // });
812
804
  //
@@ -1101,19 +1093,19 @@
1101
1093
  //
1102
1094
  // ### Example
1103
1095
  //
1104
- // var app = $.sammy(function() {
1096
+ // var app = $.sammy(function() {
1097
+ //
1098
+ // // implements a 'fade out'/'fade in'
1099
+ // this.swap = function(content) {
1100
+ // this.$element().hide('slow').html(content).show('slow');
1101
+ // }
1105
1102
  //
1106
- // // implements a 'fade out'/'fade in'
1107
- // this.swap = function(content) {
1108
- // this.$element().hide('slow').html(content).show('slow');
1109
- // }
1103
+ // get('#/', function() {
1104
+ // this.partial('index.html.erb') // will fade out and in
1105
+ // });
1110
1106
  //
1111
- // get('#/', function() {
1112
- // this.partial('index.html.erb') // will fade out and in
1113
1107
  // });
1114
1108
  //
1115
- // });
1116
- //
1117
1109
  swap: function(content) {
1118
1110
  return this.$element().html(content);
1119
1111
  },
@@ -1178,6 +1170,7 @@
1178
1170
  $_method = $form.find('input[name="_method"]');
1179
1171
  if ($_method.length > 0) { verb = $_method.val(); }
1180
1172
  if (!verb) { verb = $form[0].getAttribute('method'); }
1173
+ if (!verb || verb == '') { verb = 'get'; }
1181
1174
  return $.trim(verb.toString().toLowerCase());
1182
1175
  },
1183
1176
 
@@ -1187,10 +1180,9 @@
1187
1180
  $form = $(form);
1188
1181
  path = $form.attr('action');
1189
1182
  verb = this._getFormVerb($form);
1190
- if (!verb || verb == '') { verb = 'get'; }
1191
1183
  this.log('_checkFormSubmission', $form, path, verb);
1192
1184
  if (verb === 'get') {
1193
- this.setLocation(path + '?' + $form.serialize());
1185
+ this.setLocation(path + '?' + this._serializeFormParams($form));
1194
1186
  returned = false;
1195
1187
  } else {
1196
1188
  params = $.extend({}, this._parseFormParams($form));
@@ -1199,6 +1191,23 @@
1199
1191
  return (typeof returned == 'undefined') ? false : returned;
1200
1192
  },
1201
1193
 
1194
+ _serializeFormParams: function($form) {
1195
+ var queryString = "",
1196
+ fields = $form.serializeArray(),
1197
+ i;
1198
+ if (fields.length > 0) {
1199
+ queryString = this._encodeFormPair(fields[0].name, fields[0].value);
1200
+ for (i = 1; i < fields.length; i++) {
1201
+ queryString = queryString + "&" + this._encodeFormPair(fields[i].name, fields[i].value);
1202
+ }
1203
+ }
1204
+ return queryString;
1205
+ },
1206
+
1207
+ _encodeFormPair: function(name, value){
1208
+ return _encode(name) + "=" + _encode(value);
1209
+ },
1210
+
1202
1211
  _parseFormParams: function($form) {
1203
1212
  var params = {},
1204
1213
  form_fields = $form.serializeArray(),
@@ -1217,7 +1226,7 @@
1217
1226
  pairs = parts[1].split('&');
1218
1227
  for (i = 0; i < pairs.length; i++) {
1219
1228
  pair = pairs[i].split('=');
1220
- params = this._parseParamPair(params, _decode(pair[0]), _decode(pair[1]));
1229
+ params = this._parseParamPair(params, _decode(pair[0]), _decode(pair[1] || ""));
1221
1230
  }
1222
1231
  }
1223
1232
  return params;
@@ -1326,7 +1335,7 @@
1326
1335
  if (returned !== false) {
1327
1336
  context.next(returned);
1328
1337
  }
1329
- }, 13);
1338
+ }, 0);
1330
1339
  }
1331
1340
  return this;
1332
1341
  },
@@ -1460,7 +1469,6 @@
1460
1469
  if (_isFunction(location) && !data) {
1461
1470
  return this.then(location);
1462
1471
  } else {
1463
- if (!data && this.content) { data = this.content; }
1464
1472
  return this.load(location)
1465
1473
  .interpolate(data, location)
1466
1474
  .then(callback);
@@ -1479,12 +1487,12 @@
1479
1487
  // asynchronous functions into the queue. The content passed to the
1480
1488
  // callback is passed as `content` to the next item in the queue.
1481
1489
  //
1482
- // === Example
1490
+ // ### Example
1483
1491
  //
1484
- // this.send($.getJSON, '/app.json')
1485
- // .then(function(json) {
1486
- // $('#message).text(json['message']);
1487
- // });
1492
+ // this.send($.getJSON, '/app.json')
1493
+ // .then(function(json) {
1494
+ // $('#message).text(json['message']);
1495
+ // });
1488
1496
  //
1489
1497
  //
1490
1498
  send: function() {
@@ -1623,17 +1631,17 @@
1623
1631
  //
1624
1632
  // ### Example
1625
1633
  //
1626
- // $.sammy(function() {
1627
- // // The context here is this Sammy.Application
1628
- // this.get('#/:name', function() {
1629
- // // The context here is a new Sammy.EventContext
1630
- // if (this.params['name'] == 'sammy') {
1631
- // this.partial('name.html.erb', {name: 'Sammy'});
1632
- // } else {
1633
- // this.redirect('#/somewhere-else')
1634
- // }
1635
- // });
1636
- // });
1634
+ // $.sammy(function() {
1635
+ // // The context here is this Sammy.Application
1636
+ // this.get('#/:name', function() {
1637
+ // // The context here is a new Sammy.EventContext
1638
+ // if (this.params['name'] == 'sammy') {
1639
+ // this.partial('name.html.erb', {name: 'Sammy'});
1640
+ // } else {
1641
+ // this.redirect('#/somewhere-else')
1642
+ // }
1643
+ // });
1644
+ // });
1637
1645
  //
1638
1646
  // Initialize a new EventContext
1639
1647
  //
@@ -1660,7 +1668,7 @@
1660
1668
 
1661
1669
  // A shortcut to the app's `$element()`
1662
1670
  $element: function() {
1663
- return this.app.$element();
1671
+ return this.app.$element(_makeArray(arguments).shift());
1664
1672
  },
1665
1673
 
1666
1674
  // Look up a templating engine within the current app and context.
@@ -1678,7 +1686,7 @@
1678
1686
  // if path is actually an engine function just return it
1679
1687
  if (_isFunction(engine)) { return engine; }
1680
1688
  // lookup engine name by path extension
1681
- engine = engine.toString();
1689
+ engine = (engine || context.app.template_engine).toString();
1682
1690
  if ((engine_match = engine.match(/\.([^\.]+)$/))) {
1683
1691
  engine = engine_match[1];
1684
1692
  }