eyeballs 0.5.7.2 → 0.5.8

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/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