eyeballs 0.5.7.2 → 0.5.8

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -27,7 +27,7 @@ begin
27
27
  require 'jeweler'
28
28
  Jeweler::Tasks.new do |s|
29
29
  s.name = "eyeballs"
30
- s.version = "0.5.7.2"
30
+ s.version = "0.5.8"
31
31
  s.author = "Paul Campbell"
32
32
  s.email = "paul@rslw.com"
33
33
  s.homepage = "http://www.github.com/paulca/eyeballs.js"
@@ -1,12 +1,7 @@
1
1
  /*
2
- Shameless port of http://github.com/defunkt/mustache
3
- by Jan Lehnardt <jan@apache.org>,
4
- Alexander Lang <alex@upstream-berlin.com>,
5
- Sebastian Cohnen <sebastian.cohnen@googlemail.com>
2
+ mustache.js Logic-less templates in JavaScript
6
3
 
7
- Thanks @defunkt for the awesome code.
8
-
9
- See http://github.com/defunkt/mustache for more info.
4
+ See http://mustache.github.com/ for more info.
10
5
  */
11
6
 
12
7
  var Mustache = function() {
@@ -20,10 +15,17 @@ var Mustache = function() {
20
15
  pragmas_implemented: {
21
16
  "IMPLICIT-ITERATOR": true
22
17
  },
18
+ context: {},
23
19
 
24
20
  render: function(template, context, partials, in_recursion) {
21
+ // reset buffer & set context
22
+ if(!in_recursion) {
23
+ this.context = context;
24
+ this.buffer = []; // TODO: make this non-lazy
25
+ }
26
+
25
27
  // fail fast
26
- if(template.indexOf(this.otag) == -1) {
28
+ if(!this.includes("", template)) {
27
29
  if(in_recursion) {
28
30
  return template;
29
31
  } else {
@@ -32,10 +34,6 @@ var Mustache = function() {
32
34
  }
33
35
  }
34
36
 
35
- if(!in_recursion) {
36
- this.buffer = [];
37
- }
38
-
39
37
  template = this.render_pragmas(template);
40
38
  var html = this.render_section(template, context, partials);
41
39
  if(in_recursion) {
@@ -59,17 +57,18 @@ var Mustache = function() {
59
57
  */
60
58
  render_pragmas: function(template) {
61
59
  // no pragmas
62
- if(template.indexOf(this.otag + "%") == -1) {
60
+ if(!this.includes("%", template)) {
63
61
  return template;
64
62
  }
65
63
 
66
64
  var that = this;
67
- var regex = new RegExp(this.otag + "%([\\w_-]+) ?([\\w]+=[\\w]+)?"
68
- + this.ctag);
65
+ var regex = new RegExp(this.otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" +
66
+ this.ctag);
69
67
  return template.replace(regex, function(match, pragma, options) {
70
68
  if(!that.pragmas_implemented[pragma]) {
71
- throw({message: "This implementation of mustache doesn't understand the '"
72
- + pragma + "' pragma"});
69
+ throw({message:
70
+ "This implementation of mustache doesn't understand the '" +
71
+ pragma + "' pragma"});
73
72
  }
74
73
  that.pragmas[pragma] = {};
75
74
  if(options) {
@@ -82,42 +81,62 @@ var Mustache = function() {
82
81
  },
83
82
 
84
83
  /*
85
- Tries to find a partial in the global scope and render it
84
+ Tries to find a partial in the curent scope and render it
86
85
  */
87
86
  render_partial: function(name, context, partials) {
88
- if(!partials || !partials[name]) {
87
+ name = this.trim(name);
88
+ if(!partials || partials[name] === undefined) {
89
89
  throw({message: "unknown_partial '" + name + "'"});
90
90
  }
91
91
  if(typeof(context[name]) != "object") {
92
- return partials[name];
92
+ return this.render(partials[name], context, partials, true);
93
93
  }
94
94
  return this.render(partials[name], context[name], partials, true);
95
95
  },
96
96
 
97
97
  /*
98
- Renders boolean and enumerable sections
98
+ Renders inverted (^) and normal (#) sections
99
99
  */
100
100
  render_section: function(template, context, partials) {
101
- if(template.indexOf(this.otag + "#") == -1) {
101
+ if(!this.includes("#", template) && !this.includes("^", template)) {
102
102
  return template;
103
103
  }
104
+
104
105
  var that = this;
105
106
  // CSW - Added "+?" so it finds the tighest bound, not the widest
106
- var regex = new RegExp(this.otag + "\\#(.+)" + this.ctag +
107
- "\\s*([\\s\\S]+?)" + this.otag + "\\/\\1" + this.ctag + "\\s*", "mg");
107
+ var regex = new RegExp(this.otag + "(\\^|\\#)\\s*(.+)\\s*" + this.ctag +
108
+ "\n*([\\s\\S]+?)" + this.otag + "\\/\\s*\\2\\s*" + this.ctag +
109
+ "\\s*", "mg");
108
110
 
109
111
  // for each {{#foo}}{{/foo}} section do...
110
- return template.replace(regex, function(match, name, content) {
112
+ return template.replace(regex, function(match, type, name, content) {
111
113
  var value = that.find(name, context);
112
- if(that.is_array(value)) { // Enumerable, Let's loop!
113
- return that.map(value, function(row) {
114
- return that.render(content, that.merge(context,
115
- that.create_context(row)), partials, true);
116
- }).join("");
117
- } else if(value) { // boolean section
118
- return that.render(content, context, partials, true);
119
- } else {
120
- return "";
114
+ if(type == "^") { // inverted section
115
+ if(!value || that.is_array(value) && value.length === 0) {
116
+ // false or empty list, render it
117
+ return that.render(content, context, partials, true);
118
+ } else {
119
+ return "";
120
+ }
121
+ } else if(type == "#") { // normal section
122
+ if(that.is_array(value)) { // Enumerable, Let's loop!
123
+ return that.map(value, function(row) {
124
+ return that.render(content, that.create_context(row),
125
+ partials, true);
126
+ }).join("");
127
+ } else if(that.is_object(value)) { // Object, Use it as subcontext!
128
+ return that.render(content, that.create_context(value),
129
+ partials, true);
130
+ } else if(typeof value === "function") {
131
+ // higher order section
132
+ return value.call(context, content, function(text) {
133
+ return that.render(text, context, partials, true);
134
+ });
135
+ } else if(value) { // boolean section
136
+ return that.render(content, context, partials, true);
137
+ } else {
138
+ return "";
139
+ }
121
140
  }
122
141
  });
123
142
  },
@@ -130,37 +149,38 @@ var Mustache = function() {
130
149
  var that = this;
131
150
 
132
151
  var new_regex = function() {
133
- return new RegExp(that.otag + "(=|!|>|\\{|%)?([^\/#]+?)\\1?" +
152
+ return new RegExp(that.otag + "(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?" +
134
153
  that.ctag + "+", "g");
135
154
  };
136
155
 
137
156
  var regex = new_regex();
157
+ var tag_replace_callback = function(match, operator, name) {
158
+ switch(operator) {
159
+ case "!": // ignore comments
160
+ return "";
161
+ case "=": // set new delimiters, rebuild the replace regexp
162
+ that.set_delimiters(name);
163
+ regex = new_regex();
164
+ return "";
165
+ case ">": // render partial
166
+ return that.render_partial(name, context, partials);
167
+ case "{": // the triple mustache is unescaped
168
+ return that.find(name, context);
169
+ default: // escape the value
170
+ return that.escape(that.find(name, context));
171
+ }
172
+ };
138
173
  var lines = template.split("\n");
139
- for (var i=0; i < lines.length; i++) {
140
- lines[i] = lines[i].replace(regex, function(match, operator, name) {
141
- switch(operator) {
142
- case "!": // ignore comments
143
- return match;
144
- case "=": // set new delimiters, rebuild the replace regexp
145
- that.set_delimiters(name);
146
- regex = new_regex();
147
- return "";
148
- case ">": // render partial
149
- return that.render_partial(name, context, partials);
150
- case "{": // the triple mustache is unescaped
151
- return that.find(name, context);
152
- default: // escape the value
153
- return that.escape(that.find(name, context));
154
- }
155
- }, this);
156
- if(!in_recursion) {
157
- this.send(lines[i]);
158
- }
159
- }
160
-
161
- if(in_recursion) {
162
- return lines.join("\n");
163
- }
174
+ for(var i = 0; i < lines.length; i++) {
175
+ lines[i] = lines[i].replace(regex, tag_replace_callback, this);
176
+ if(!in_recursion) {
177
+ this.send(lines[i]);
178
+ }
179
+ }
180
+
181
+ if(in_recursion) {
182
+ return lines.join("\n");
183
+ }
164
184
  },
165
185
 
166
186
  set_delimiters: function(delimiters) {
@@ -180,7 +200,7 @@ var Mustache = function() {
180
200
  '(\\' + specials.join('|\\') + ')', 'g'
181
201
  );
182
202
  }
183
- return text.replace(arguments.callee.sRE, '\\$1');
203
+ return text.replace(arguments.callee.sRE, '\\$1');
184
204
  },
185
205
 
186
206
  /*
@@ -189,11 +209,24 @@ var Mustache = function() {
189
209
  */
190
210
  find: function(name, context) {
191
211
  name = this.trim(name);
192
- if(typeof context[name] === "function") {
193
- return context[name].apply(context);
212
+
213
+ // Checks whether a value is thruthy or false or 0
214
+ function is_kinda_truthy(bool) {
215
+ return bool === false || bool === 0 || bool;
194
216
  }
195
- if(context[name] !== undefined) {
196
- return context[name];
217
+
218
+ var value;
219
+ if(is_kinda_truthy(context[name])) {
220
+ value = context[name];
221
+ } else if(is_kinda_truthy(this.context[name])) {
222
+ value = this.context[name];
223
+ }
224
+
225
+ if(typeof value === "function") {
226
+ return value.apply(context);
227
+ }
228
+ if(value !== undefined) {
229
+ return value;
197
230
  }
198
231
  // silently ignore unkown variables
199
232
  return "";
@@ -201,47 +234,37 @@ var Mustache = function() {
201
234
 
202
235
  // Utility methods
203
236
 
237
+ /* includes tag */
238
+ includes: function(needle, haystack) {
239
+ return haystack.indexOf(this.otag + needle) != -1;
240
+ },
241
+
204
242
  /*
205
243
  Does away with nasty characters
206
244
  */
207
245
  escape: function(s) {
208
- return ((s == null) ? "" : s).toString().replace(/[&"<>\\]/g, function(s) {
246
+ s = String(s === null ? "" : s);
247
+ return s.replace(/&(?!\w+;)|["<>\\]/g, function(s) {
209
248
  switch(s) {
210
- case "&": return "&amp;";
211
- case "\\": return "\\\\";;
212
- case '"': return '\"';;
213
- case "<": return "&lt;";
214
- case ">": return "&gt;";
215
- default: return s;
249
+ case "&": return "&amp;";
250
+ case "\\": return "\\\\";
251
+ case '"': return '\"';
252
+ case "<": return "&lt;";
253
+ case ">": return "&gt;";
254
+ default: return s;
216
255
  }
217
256
  });
218
257
  },
219
258
 
220
- /*
221
- Merges all properties of object `b` into object `a`.
222
- `b.property` overwrites a.property`
223
- */
224
- merge: function(a, b) {
225
- var _new = {};
226
- for(var name in a) {
227
- if(a.hasOwnProperty(name)) {
228
- _new[name] = a[name];
229
- }
230
- };
231
- for(var name in b) {
232
- if(b.hasOwnProperty(name)) {
233
- _new[name] = b[name];
234
- }
235
- };
236
- return _new;
237
- },
238
-
239
259
  // by @langalex, support for arrays of strings
240
260
  create_context: function(_context) {
241
261
  if(this.is_object(_context)) {
242
262
  return _context;
243
- } else if(this.pragmas["IMPLICIT-ITERATOR"]) {
244
- var iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator || ".";
263
+ } else {
264
+ var iterator = ".";
265
+ if(this.pragmas["IMPLICIT-ITERATOR"]) {
266
+ iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator;
267
+ }
245
268
  var ctx = {};
246
269
  ctx[iterator] = _context;
247
270
  return ctx;
@@ -272,7 +295,7 @@ var Mustache = function() {
272
295
  } else {
273
296
  var r = [];
274
297
  var l = array.length;
275
- for(var i=0;i<l;i++) {
298
+ for(var i = 0; i < l; i++) {
276
299
  r.push(fn(array[i]));
277
300
  }
278
301
  return r;
@@ -282,7 +305,7 @@ var Mustache = function() {
282
305
 
283
306
  return({
284
307
  name: "mustache.js",
285
- version: "0.2.3",
308
+ version: "0.3.0",
286
309
 
287
310
  /*
288
311
  Turns a template and view into HTML
data/eyeballs.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{eyeballs}
8
- s.version = "0.5.7.2"
8
+ s.version = "0.5.8"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Paul Campbell"]
12
- s.date = %q{2010-08-08}
12
+ s.date = %q{2010-08-23}
13
13
  s.default_executable = %q{eyeballs}
14
14
  s.email = %q{paul@rslw.com}
15
15
  s.executables = ["eyeballs"]
@@ -28,7 +28,7 @@ Gem::Specification.new do |s|
28
28
  "config.ru",
29
29
  "dist/jquery/jquery-1.4.2.min.js",
30
30
  "dist/jquery/jquery.ba-hashchange.js",
31
- "dist/mustache/mustache.0.2.3.js",
31
+ "dist/mustache/mustache.0.3.0.js",
32
32
  "eyeballs.gemspec",
33
33
  "lib/eyeballs.rb",
34
34
  "lib/eyeballs/app_detector.rb",
@@ -18,7 +18,7 @@ module Eyeballs
18
18
  def build_the_app
19
19
  directory "templates/app_root", new_app_path
20
20
  copy_file 'dist/jquery/jquery-1.4.2.min.js', "#{new_app_path}/vendor/jquery/jquery-1.4.2.min.js"
21
- copy_file 'dist/mustache/mustache.0.2.3.js', "#{new_app_path}/vendor/mustache/mustache.0.2.3.js"
21
+ copy_file 'dist/mustache/mustache.0.3.0.js', "#{new_app_path}/vendor/mustache/mustache.0.3.0.js"
22
22
  directory "src", "#{new_app_path}/vendor/eyeballs/"
23
23
  template "templates/initializer.js", "#{new_app_path}/config/initializer.js"
24
24
  end
@@ -17,6 +17,7 @@ module Eyeballs
17
17
 
18
18
  def build_the_model
19
19
  template "templates/controller.js", "#{app_path}/app/controllers/#{name.downcase}_controller.js"
20
+ empty_directory "#{app_path}/app/views/#{name.downcase}"
20
21
  end
21
22
 
22
23
  def farewell
@@ -20,7 +20,7 @@ describe Eyeballs::AppGenerator do
20
20
 
21
21
  let(:jquery_file) { file('test', 'vendor', 'jquery', 'jquery-1.4.2.min.js') }
22
22
  let(:livequery_file) { file('test', 'vendor', 'jquery', 'jquery.livequery.js') }
23
- let(:mustache_file) { file('test', 'vendor', 'mustache', 'mustache.0.2.3.js') }
23
+ let(:mustache_file) { file('test', 'vendor', 'mustache', 'mustache.0.3.0.js') }
24
24
  let(:index_file) { file('test', 'index.html') }
25
25
  let(:initializer_file) { file('test', 'config', 'initializer.js')}
26
26
  let(:routes_file) { file('test', 'config', 'routes.js')}
@@ -9,6 +9,7 @@ describe Eyeballs::ControllerGenerator do
9
9
  end
10
10
 
11
11
  let(:controller_file) { file('app/controllers/paul_controller.js') }
12
+ let(:controller_view_dir) { file('app/views/paul') }
12
13
 
13
14
  it "should create my controller" do
14
15
  controller_file.should exist
@@ -18,6 +19,10 @@ describe Eyeballs::ControllerGenerator do
18
19
  controller_file.read.should include("o_O('PaulController', {")
19
20
  end
20
21
 
22
+ it "should create an empty dir for views" do
23
+ controller_view_dir.should exist
24
+ end
25
+
21
26
  after(:all) do
22
27
  remove_test_root
23
28
  end
@@ -34,6 +34,10 @@ o_O.render = function(template, data, options){
34
34
  {
35
35
  $(options.prepend).prepend(rendered);
36
36
  }
37
+ if(options.replace)
38
+ {
39
+ $(options.replace).replaceWith(rendered);
40
+ }
37
41
  }
38
42
  });
39
43
  }
@@ -3,6 +3,12 @@
3
3
  <% if rack_app? %>
4
4
  o_O.model.adapter = o_O.rest;
5
5
  o_O.config.authenticity_token = $('meta[name=csrf-token]').attr('content')
6
+ o_O.config.template_path = '/javascripts/app/views';
7
+
8
+ jQuery.ajaxSetup({
9
+ 'beforeSend': function(xhr) {xhr.setRequestHeader("Accept",
10
+ "text/javascript")}
11
+ })
6
12
  <% else %>
7
13
  o_O.model.adapter = o_O.localstorage;
8
14
  <% end %>
@@ -29,7 +29,7 @@
29
29
  </div>
30
30
  </body>
31
31
  <script src="<%= prefix %>vendor/jquery/jquery-1.4.2.min.js"></script>
32
- <script src="<%= prefix %>vendor/mustache/mustache.0.2.3.js"></script>
32
+ <script src="<%= prefix %>vendor/mustache/mustache.0.3.0.js"></script>
33
33
  <script src="<%= prefix %>vendor/eyeballs/o_O.js"></script>
34
34
  <script src="<%= prefix %>vendor/eyeballs/modules/o_O.model.js"></script>
35
35
  <script src="<%= prefix %>vendor/eyeballs/modules/o_O.validations.js"></script>
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eyeballs
3
3
  version: !ruby/object:Gem::Version
4
- hash: 127
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 5
9
- - 7
10
- - 2
11
- version: 0.5.7.2
9
+ - 8
10
+ version: 0.5.8
12
11
  platform: ruby
13
12
  authors:
14
13
  - Paul Campbell
@@ -16,7 +15,7 @@ autorequire:
16
15
  bindir: bin
17
16
  cert_chain: []
18
17
 
19
- date: 2010-08-08 00:00:00 +01:00
18
+ date: 2010-08-23 00:00:00 +01:00
20
19
  default_executable: eyeballs
21
20
  dependencies:
22
21
  - !ruby/object:Gem::Dependency
@@ -67,7 +66,7 @@ files:
67
66
  - config.ru
68
67
  - dist/jquery/jquery-1.4.2.min.js
69
68
  - dist/jquery/jquery.ba-hashchange.js
70
- - dist/mustache/mustache.0.2.3.js
69
+ - dist/mustache/mustache.0.3.0.js
71
70
  - eyeballs.gemspec
72
71
  - lib/eyeballs.rb
73
72
  - lib/eyeballs/app_detector.rb