backbonejs-rails 1.0.0 → 1.0.1
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.
- checksums.yaml +8 -8
- data/README.md +4 -50
- data/lib/backbonejs-rails/version.rb +1 -1
- data/lib/generators/backbonejs/install/install_generator.rb +10 -11
- data/{vendor/assets → lib/generators/backbonejs/install}/javascripts/backbone.js +0 -0
- data/{vendor/assets → lib/generators/backbonejs/install}/javascripts/json2.js +0 -0
- data/{vendor/assets → lib/generators/backbonejs/install}/javascripts/underscore.js +0 -0
- metadata +4 -5
- data/vendor/assets/javascripts/icanhaz.js +0 -542
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YWMxOTk2MjlkMDg0MGM0NjMyN2M1ZjBiMzEzODM4NDY5MWMwNjhlMw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MzMzMzNiYWQzOGI2NmFlNzk2ZjZjYTkwNjA1ZmIyY2M0NjY3NjZmNw==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NGEwOTQyODAzOTZhNTE4ZTYyODY1NTFkNzNlOGJhODgyNGMyZDNmOWY5NGYw
|
10
|
+
MTAyYmQwNDBlNzc1OWM2ZTBmNTQ2NjBiNTY5YWJlYjI3Zjc0NjlhNmNhMzhj
|
11
|
+
NGFjZmJiY2FkNGM2Y2U4NmY4NGU5YjQwYTJmZTIwNGE4ZjJlNjI=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZjFmZDM2OWY4ZjQyOGNkZDBkNGNkOTBiZDU4MDhmOWE4MDNmM2M1N2RlMWY4
|
14
|
+
NWM5Njk2MTExZWJlNTc0MTM5NjA3MmUzOTlhZWYzOGY4ZmRiMGRhMzg0ZGRh
|
15
|
+
NzA5MWM1MzU4ZWVlNGFhZTA0NzI0ZmJmYjQyNWYyMGZmNWE5Yjc=
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@ Installation
|
|
3
3
|
|
4
4
|
Add the following to your Gemfile:
|
5
5
|
|
6
|
-
gem "backbonejs-rails", "~> 0.0
|
6
|
+
gem "backbonejs-rails", "~> 1.0.0"
|
7
7
|
|
8
8
|
Then use Bundler to install:
|
9
9
|
|
@@ -20,66 +20,20 @@ Optionally you can add -ich to the end of that command to have icanhaz.js includ
|
|
20
20
|
What Does it do?
|
21
21
|
================
|
22
22
|
|
23
|
-
Rails
|
24
|
-
---------
|
25
|
-
|
26
|
-
backbonejs-rails adds the necessary libraries to your Rails app for using [backbone.js](http://documentcloud.github.com/backbone/). Also, under your assets/javascripts folder it will create the following folder structure:
|
27
|
-
|
28
|
-
/backone
|
29
|
-
/models
|
30
|
-
/routers
|
31
|
-
/views
|
32
|
-
|
33
|
-
The gem includes the following files in its vendor/assets/javascripts folder, which means you can use any of them in your application.js file by adding something like
|
34
|
-
|
35
|
-
//= require underscore
|
36
|
-
|
37
|
-
after this line:
|
38
|
-
|
39
|
-
//= require jquery
|
40
|
-
|
23
|
+
backbonejs-rails adds the necessary libraries to your Rails app for using [Backbone.js](http://backbonejs.org).
|
41
24
|
|
42
25
|
* backbone.js
|
43
26
|
* underscore.js
|
44
|
-
* icanhaz.js
|
45
27
|
* json2.js
|
46
28
|
|
47
|
-
|
48
|
-
---------
|
49
|
-
|
50
|
-
backbonejs-rails is similar to [jquery-rails](https://github.com/JangoSteve/jquery-rails). It adds the Javascript files that you need to create an application that uses [backbone.js](http://documentcloud.github.com/backbone/) as a JavaScript MVC. This gem will get the most recent version of these files from their master branches on github.
|
51
|
-
|
52
|
-
These are:
|
53
|
-
|
54
|
-
* backbone.js
|
55
|
-
* backbone.min.js
|
56
|
-
* underscore.js
|
57
|
-
* underscore.min.js
|
58
|
-
* json2.js
|
59
|
-
|
60
|
-
For templates I have included [ICanHaz.js](http://icanhazjs.com/) which you can optionally include by doing the following
|
29
|
+
For templates you can optionally include [ICanHaz.js](http://icanhazjs.com/)
|
61
30
|
|
62
31
|
$ rails g backbonejs:install -ich
|
63
32
|
|
64
|
-
* icanhaz.js
|
65
|
-
* icanhaz.min.js
|
66
|
-
|
67
|
-
Upon installation the files are added to your javascript defaults so that you can still use the following in your views/layouts/application.html.erb file:
|
68
33
|
|
69
|
-
<%= javascript_include_tag :defaults %>
|
70
34
|
|
71
|
-
|
35
|
+
Outdated Screencast? Yep I have one.
|
72
36
|
----------
|
73
37
|
|
74
|
-
It also creates a file called "config/initializers/backbone.rb" which contains the line:
|
75
|
-
|
76
|
-
ActiveRecord::Base.include_root_in_json = false
|
77
|
-
|
78
|
-
Which is what you need to return JSON to Backbone the way it likes it. Otherwise you would need to do something like this:
|
79
|
-
|
80
|
-
def create
|
81
|
-
render :json => Person.create(:name => params[:name], :age => params[:age])
|
82
|
-
end
|
83
|
-
|
84
38
|
You can find my [screencast on Backbone.js and Rails 3 here](http://andrewgertig.com/2011/05/rails-backbone-js-example-screencast/)
|
85
39
|
|
@@ -6,23 +6,22 @@ require 'uri'
|
|
6
6
|
module Backbonejs
|
7
7
|
module Generators
|
8
8
|
class InstallGenerator < ::Rails::Generators::Base
|
9
|
-
@@backbone_version = '0.9.1'
|
10
|
-
@@underscore_version = '1.3.1'
|
11
|
-
@@icanhaz_version = '0.10'
|
12
9
|
|
13
|
-
desc "This generator installs backbone.js
|
14
|
-
|
10
|
+
desc "This generator installs backbone.js, underscore.js, and json2.js"
|
11
|
+
source_root File.expand_path('../javascripts', __FILE__)
|
12
|
+
# class_option :ich, :type => :boolean, :aliases => "-i", :default => false, :desc => 'Include ICanHaz.js'
|
13
|
+
|
14
|
+
# Copy backbone, underscore, json2 to assets folder
|
15
|
+
def copy_backbone
|
16
|
+
copy_file "backbone.js", "app/assets/javascripts/backbone.js"
|
17
|
+
copy_file "underscore.js", "app/assets/javascripts/underscore.js"
|
18
|
+
copy_file "json2.js", "app/assets/javascripts/json2.js"
|
19
|
+
end
|
15
20
|
|
16
21
|
def insert_backbone_in_applicationjs
|
17
22
|
inject_into_file "app/assets/javascripts/application.js", :before => "//= require_tree" do
|
18
23
|
"//= require json2\n//= require underscore\n//= require backbone\n"
|
19
24
|
end
|
20
|
-
|
21
|
-
if options[:ich]
|
22
|
-
inject_into_file "app/assets/javascripts/application.js", :before => "//= require_tree" do
|
23
|
-
"//= require icanhaz\n"
|
24
|
-
end
|
25
|
-
end
|
26
25
|
end
|
27
26
|
|
28
27
|
# def create_dir_layout
|
File without changes
|
File without changes
|
File without changes
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: backbonejs-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Gertig
|
@@ -85,11 +85,10 @@ files:
|
|
85
85
|
- lib/backbonejs-rails/engine.rb
|
86
86
|
- lib/backbonejs-rails/version.rb
|
87
87
|
- lib/generators/backbonejs/install/install_generator.rb
|
88
|
+
- lib/generators/backbonejs/install/javascripts/backbone.js
|
89
|
+
- lib/generators/backbonejs/install/javascripts/json2.js
|
90
|
+
- lib/generators/backbonejs/install/javascripts/underscore.js
|
88
91
|
- lib/generators/backbonejs/uninstall/uninstall_generator.rb
|
89
|
-
- vendor/assets/javascripts/backbone.js
|
90
|
-
- vendor/assets/javascripts/icanhaz.js
|
91
|
-
- vendor/assets/javascripts/json2.js
|
92
|
-
- vendor/assets/javascripts/underscore.js
|
93
92
|
homepage: https://github.com/AndrewGertig/backbonejs-rails
|
94
93
|
licenses: []
|
95
94
|
metadata: {}
|
@@ -1,542 +0,0 @@
|
|
1
|
-
/*!
|
2
|
-
ICanHaz.js version 0.10 -- by @HenrikJoreteg
|
3
|
-
More info at: http://icanhazjs.com
|
4
|
-
*/
|
5
|
-
(function () {
|
6
|
-
/*
|
7
|
-
mustache.js — Logic-less templates in JavaScript
|
8
|
-
|
9
|
-
See http://mustache.github.com/ for more info.
|
10
|
-
*/
|
11
|
-
|
12
|
-
var Mustache = function () {
|
13
|
-
var _toString = Object.prototype.toString;
|
14
|
-
|
15
|
-
Array.isArray = Array.isArray || function (obj) {
|
16
|
-
return _toString.call(obj) == "[object Array]";
|
17
|
-
}
|
18
|
-
|
19
|
-
var _trim = String.prototype.trim, trim;
|
20
|
-
|
21
|
-
if (_trim) {
|
22
|
-
trim = function (text) {
|
23
|
-
return text == null ? "" : _trim.call(text);
|
24
|
-
}
|
25
|
-
} else {
|
26
|
-
var trimLeft, trimRight;
|
27
|
-
|
28
|
-
// IE doesn't match non-breaking spaces with \s.
|
29
|
-
if ((/\S/).test("\xA0")) {
|
30
|
-
trimLeft = /^[\s\xA0]+/;
|
31
|
-
trimRight = /[\s\xA0]+$/;
|
32
|
-
} else {
|
33
|
-
trimLeft = /^\s+/;
|
34
|
-
trimRight = /\s+$/;
|
35
|
-
}
|
36
|
-
|
37
|
-
trim = function (text) {
|
38
|
-
return text == null ? "" :
|
39
|
-
text.toString().replace(trimLeft, "").replace(trimRight, "");
|
40
|
-
}
|
41
|
-
}
|
42
|
-
|
43
|
-
var escapeMap = {
|
44
|
-
"&": "&",
|
45
|
-
"<": "<",
|
46
|
-
">": ">",
|
47
|
-
'"': '"',
|
48
|
-
"'": '''
|
49
|
-
};
|
50
|
-
|
51
|
-
function escapeHTML(string) {
|
52
|
-
return String(string).replace(/&(?!\w+;)|[<>"']/g, function (s) {
|
53
|
-
return escapeMap[s] || s;
|
54
|
-
});
|
55
|
-
}
|
56
|
-
|
57
|
-
var regexCache = {};
|
58
|
-
var Renderer = function () {};
|
59
|
-
|
60
|
-
Renderer.prototype = {
|
61
|
-
otag: "{{",
|
62
|
-
ctag: "}}",
|
63
|
-
pragmas: {},
|
64
|
-
buffer: [],
|
65
|
-
pragmas_implemented: {
|
66
|
-
"IMPLICIT-ITERATOR": true
|
67
|
-
},
|
68
|
-
context: {},
|
69
|
-
|
70
|
-
render: function (template, context, partials, in_recursion) {
|
71
|
-
// reset buffer & set context
|
72
|
-
if (!in_recursion) {
|
73
|
-
this.context = context;
|
74
|
-
this.buffer = []; // TODO: make this non-lazy
|
75
|
-
}
|
76
|
-
|
77
|
-
// fail fast
|
78
|
-
if (!this.includes("", template)) {
|
79
|
-
if (in_recursion) {
|
80
|
-
return template;
|
81
|
-
} else {
|
82
|
-
this.send(template);
|
83
|
-
return;
|
84
|
-
}
|
85
|
-
}
|
86
|
-
|
87
|
-
// get the pragmas together
|
88
|
-
template = this.render_pragmas(template);
|
89
|
-
|
90
|
-
// render the template
|
91
|
-
var html = this.render_section(template, context, partials);
|
92
|
-
|
93
|
-
// render_section did not find any sections, we still need to render the tags
|
94
|
-
if (html === false) {
|
95
|
-
html = this.render_tags(template, context, partials, in_recursion);
|
96
|
-
}
|
97
|
-
|
98
|
-
if (in_recursion) {
|
99
|
-
return html;
|
100
|
-
} else {
|
101
|
-
this.sendLines(html);
|
102
|
-
}
|
103
|
-
},
|
104
|
-
|
105
|
-
/*
|
106
|
-
Sends parsed lines
|
107
|
-
*/
|
108
|
-
send: function (line) {
|
109
|
-
if (line !== "") {
|
110
|
-
this.buffer.push(line);
|
111
|
-
}
|
112
|
-
},
|
113
|
-
|
114
|
-
sendLines: function (text) {
|
115
|
-
if (text) {
|
116
|
-
var lines = text.split("\n");
|
117
|
-
for (var i = 0; i < lines.length; i++) {
|
118
|
-
this.send(lines[i]);
|
119
|
-
}
|
120
|
-
}
|
121
|
-
},
|
122
|
-
|
123
|
-
/*
|
124
|
-
Looks for %PRAGMAS
|
125
|
-
*/
|
126
|
-
render_pragmas: function (template) {
|
127
|
-
// no pragmas
|
128
|
-
if (!this.includes("%", template)) {
|
129
|
-
return template;
|
130
|
-
}
|
131
|
-
|
132
|
-
var that = this;
|
133
|
-
var regex = this.getCachedRegex("render_pragmas", function (otag, ctag) {
|
134
|
-
return new RegExp(otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" + ctag, "g");
|
135
|
-
});
|
136
|
-
|
137
|
-
return template.replace(regex, function (match, pragma, options) {
|
138
|
-
if (!that.pragmas_implemented[pragma]) {
|
139
|
-
throw({message:
|
140
|
-
"This implementation of mustache doesn't understand the '" +
|
141
|
-
pragma + "' pragma"});
|
142
|
-
}
|
143
|
-
that.pragmas[pragma] = {};
|
144
|
-
if (options) {
|
145
|
-
var opts = options.split("=");
|
146
|
-
that.pragmas[pragma][opts[0]] = opts[1];
|
147
|
-
}
|
148
|
-
return "";
|
149
|
-
// ignore unknown pragmas silently
|
150
|
-
});
|
151
|
-
},
|
152
|
-
|
153
|
-
/*
|
154
|
-
Tries to find a partial in the curent scope and render it
|
155
|
-
*/
|
156
|
-
render_partial: function (name, context, partials) {
|
157
|
-
name = trim(name);
|
158
|
-
if (!partials || partials[name] === undefined) {
|
159
|
-
throw({message: "unknown_partial '" + name + "'"});
|
160
|
-
}
|
161
|
-
if (!context || typeof context[name] != "object") {
|
162
|
-
return this.render(partials[name], context, partials, true);
|
163
|
-
}
|
164
|
-
return this.render(partials[name], context[name], partials, true);
|
165
|
-
},
|
166
|
-
|
167
|
-
/*
|
168
|
-
Renders inverted (^) and normal (#) sections
|
169
|
-
*/
|
170
|
-
render_section: function (template, context, partials) {
|
171
|
-
if (!this.includes("#", template) && !this.includes("^", template)) {
|
172
|
-
// did not render anything, there were no sections
|
173
|
-
return false;
|
174
|
-
}
|
175
|
-
|
176
|
-
var that = this;
|
177
|
-
|
178
|
-
var regex = this.getCachedRegex("render_section", function (otag, ctag) {
|
179
|
-
// This regex matches _the first_ section ({{#foo}}{{/foo}}), and captures the remainder
|
180
|
-
return new RegExp(
|
181
|
-
"^([\\s\\S]*?)" + // all the crap at the beginning that is not {{*}} ($1)
|
182
|
-
|
183
|
-
otag + // {{
|
184
|
-
"(\\^|\\#)\\s*(.+)\\s*" + // #foo (# == $2, foo == $3)
|
185
|
-
ctag + // }}
|
186
|
-
|
187
|
-
"\n*([\\s\\S]*?)" + // between the tag ($2). leading newlines are dropped
|
188
|
-
|
189
|
-
otag + // {{
|
190
|
-
"\\/\\s*\\3\\s*" + // /foo (backreference to the opening tag).
|
191
|
-
ctag + // }}
|
192
|
-
|
193
|
-
"\\s*([\\s\\S]*)$", // everything else in the string ($4). leading whitespace is dropped.
|
194
|
-
|
195
|
-
"g");
|
196
|
-
});
|
197
|
-
|
198
|
-
|
199
|
-
// for each {{#foo}}{{/foo}} section do...
|
200
|
-
return template.replace(regex, function (match, before, type, name, content, after) {
|
201
|
-
// before contains only tags, no sections
|
202
|
-
var renderedBefore = before ? that.render_tags(before, context, partials, true) : "",
|
203
|
-
|
204
|
-
// after may contain both sections and tags, so use full rendering function
|
205
|
-
renderedAfter = after ? that.render(after, context, partials, true) : "",
|
206
|
-
|
207
|
-
// will be computed below
|
208
|
-
renderedContent,
|
209
|
-
|
210
|
-
value = that.find(name, context);
|
211
|
-
|
212
|
-
if (type === "^") { // inverted section
|
213
|
-
if (!value || Array.isArray(value) && value.length === 0) {
|
214
|
-
// false or empty list, render it
|
215
|
-
renderedContent = that.render(content, context, partials, true);
|
216
|
-
} else {
|
217
|
-
renderedContent = "";
|
218
|
-
}
|
219
|
-
} else if (type === "#") { // normal section
|
220
|
-
if (Array.isArray(value)) { // Enumerable, Let's loop!
|
221
|
-
renderedContent = that.map(value, function (row) {
|
222
|
-
return that.render(content, that.create_context(row), partials, true);
|
223
|
-
}).join("");
|
224
|
-
} else if (that.is_object(value)) { // Object, Use it as subcontext!
|
225
|
-
renderedContent = that.render(content, that.create_context(value),
|
226
|
-
partials, true);
|
227
|
-
} else if (typeof value == "function") {
|
228
|
-
// higher order section
|
229
|
-
renderedContent = value.call(context, content, function (text) {
|
230
|
-
return that.render(text, context, partials, true);
|
231
|
-
});
|
232
|
-
} else if (value) { // boolean section
|
233
|
-
renderedContent = that.render(content, context, partials, true);
|
234
|
-
} else {
|
235
|
-
renderedContent = "";
|
236
|
-
}
|
237
|
-
}
|
238
|
-
|
239
|
-
return renderedBefore + renderedContent + renderedAfter;
|
240
|
-
});
|
241
|
-
},
|
242
|
-
|
243
|
-
/*
|
244
|
-
Replace {{foo}} and friends with values from our view
|
245
|
-
*/
|
246
|
-
render_tags: function (template, context, partials, in_recursion) {
|
247
|
-
// tit for tat
|
248
|
-
var that = this;
|
249
|
-
|
250
|
-
var new_regex = function () {
|
251
|
-
return that.getCachedRegex("render_tags", function (otag, ctag) {
|
252
|
-
return new RegExp(otag + "(=|!|>|&|\\{|%)?([^#\\^]+?)\\1?" + ctag + "+", "g");
|
253
|
-
});
|
254
|
-
};
|
255
|
-
|
256
|
-
var regex = new_regex();
|
257
|
-
var tag_replace_callback = function (match, operator, name) {
|
258
|
-
switch(operator) {
|
259
|
-
case "!": // ignore comments
|
260
|
-
return "";
|
261
|
-
case "=": // set new delimiters, rebuild the replace regexp
|
262
|
-
that.set_delimiters(name);
|
263
|
-
regex = new_regex();
|
264
|
-
return "";
|
265
|
-
case ">": // render partial
|
266
|
-
return that.render_partial(name, context, partials);
|
267
|
-
case "{": // the triple mustache is unescaped
|
268
|
-
case "&": // & operator is an alternative unescape method
|
269
|
-
return that.find(name, context);
|
270
|
-
default: // escape the value
|
271
|
-
return escapeHTML(that.find(name, context));
|
272
|
-
}
|
273
|
-
};
|
274
|
-
var lines = template.split("\n");
|
275
|
-
for(var i = 0; i < lines.length; i++) {
|
276
|
-
lines[i] = lines[i].replace(regex, tag_replace_callback, this);
|
277
|
-
if (!in_recursion) {
|
278
|
-
this.send(lines[i]);
|
279
|
-
}
|
280
|
-
}
|
281
|
-
|
282
|
-
if (in_recursion) {
|
283
|
-
return lines.join("\n");
|
284
|
-
}
|
285
|
-
},
|
286
|
-
|
287
|
-
set_delimiters: function (delimiters) {
|
288
|
-
var dels = delimiters.split(" ");
|
289
|
-
this.otag = this.escape_regex(dels[0]);
|
290
|
-
this.ctag = this.escape_regex(dels[1]);
|
291
|
-
},
|
292
|
-
|
293
|
-
escape_regex: function (text) {
|
294
|
-
// thank you Simon Willison
|
295
|
-
if (!arguments.callee.sRE) {
|
296
|
-
var specials = [
|
297
|
-
'/', '.', '*', '+', '?', '|',
|
298
|
-
'(', ')', '[', ']', '{', '}', '\\'
|
299
|
-
];
|
300
|
-
arguments.callee.sRE = new RegExp(
|
301
|
-
'(\\' + specials.join('|\\') + ')', 'g'
|
302
|
-
);
|
303
|
-
}
|
304
|
-
return text.replace(arguments.callee.sRE, '\\$1');
|
305
|
-
},
|
306
|
-
|
307
|
-
/*
|
308
|
-
find `name` in current `context`. That is find me a value
|
309
|
-
from the view object
|
310
|
-
*/
|
311
|
-
find: function (name, context) {
|
312
|
-
name = trim(name);
|
313
|
-
|
314
|
-
// Checks whether a value is thruthy or false or 0
|
315
|
-
function is_kinda_truthy(bool) {
|
316
|
-
return bool === false || bool === 0 || bool;
|
317
|
-
}
|
318
|
-
|
319
|
-
var value;
|
320
|
-
|
321
|
-
// check for dot notation eg. foo.bar
|
322
|
-
if (name.match(/([a-z_]+)\./ig)) {
|
323
|
-
var childValue = this.walk_context(name, context);
|
324
|
-
if (is_kinda_truthy(childValue)) {
|
325
|
-
value = childValue;
|
326
|
-
}
|
327
|
-
} else {
|
328
|
-
if (is_kinda_truthy(context[name])) {
|
329
|
-
value = context[name];
|
330
|
-
} else if (is_kinda_truthy(this.context[name])) {
|
331
|
-
value = this.context[name];
|
332
|
-
}
|
333
|
-
}
|
334
|
-
|
335
|
-
if (typeof value == "function") {
|
336
|
-
return value.apply(context);
|
337
|
-
}
|
338
|
-
if (value !== undefined) {
|
339
|
-
return value;
|
340
|
-
}
|
341
|
-
// silently ignore unkown variables
|
342
|
-
return "";
|
343
|
-
},
|
344
|
-
|
345
|
-
walk_context: function (name, context) {
|
346
|
-
var path = name.split('.');
|
347
|
-
// if the var doesn't exist in current context, check the top level context
|
348
|
-
var value_context = (context[path[0]] != undefined) ? context : this.context;
|
349
|
-
var value = value_context[path.shift()];
|
350
|
-
while (value != undefined && path.length > 0) {
|
351
|
-
value_context = value;
|
352
|
-
value = value[path.shift()];
|
353
|
-
}
|
354
|
-
// if the value is a function, call it, binding the correct context
|
355
|
-
if (typeof value == "function") {
|
356
|
-
return value.apply(value_context);
|
357
|
-
}
|
358
|
-
return value;
|
359
|
-
},
|
360
|
-
|
361
|
-
// Utility methods
|
362
|
-
|
363
|
-
/* includes tag */
|
364
|
-
includes: function (needle, haystack) {
|
365
|
-
return haystack.indexOf(this.otag + needle) != -1;
|
366
|
-
},
|
367
|
-
|
368
|
-
// by @langalex, support for arrays of strings
|
369
|
-
create_context: function (_context) {
|
370
|
-
if (this.is_object(_context)) {
|
371
|
-
return _context;
|
372
|
-
} else {
|
373
|
-
var iterator = ".";
|
374
|
-
if (this.pragmas["IMPLICIT-ITERATOR"]) {
|
375
|
-
iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator;
|
376
|
-
}
|
377
|
-
var ctx = {};
|
378
|
-
ctx[iterator] = _context;
|
379
|
-
return ctx;
|
380
|
-
}
|
381
|
-
},
|
382
|
-
|
383
|
-
is_object: function (a) {
|
384
|
-
return a && typeof a == "object";
|
385
|
-
},
|
386
|
-
|
387
|
-
/*
|
388
|
-
Why, why, why? Because IE. Cry, cry cry.
|
389
|
-
*/
|
390
|
-
map: function (array, fn) {
|
391
|
-
if (typeof array.map == "function") {
|
392
|
-
return array.map(fn);
|
393
|
-
} else {
|
394
|
-
var r = [];
|
395
|
-
var l = array.length;
|
396
|
-
for(var i = 0; i < l; i++) {
|
397
|
-
r.push(fn(array[i]));
|
398
|
-
}
|
399
|
-
return r;
|
400
|
-
}
|
401
|
-
},
|
402
|
-
|
403
|
-
getCachedRegex: function (name, generator) {
|
404
|
-
var byOtag = regexCache[this.otag];
|
405
|
-
if (!byOtag) {
|
406
|
-
byOtag = regexCache[this.otag] = {};
|
407
|
-
}
|
408
|
-
|
409
|
-
var byCtag = byOtag[this.ctag];
|
410
|
-
if (!byCtag) {
|
411
|
-
byCtag = byOtag[this.ctag] = {};
|
412
|
-
}
|
413
|
-
|
414
|
-
var regex = byCtag[name];
|
415
|
-
if (!regex) {
|
416
|
-
regex = byCtag[name] = generator(this.otag, this.ctag);
|
417
|
-
}
|
418
|
-
|
419
|
-
return regex;
|
420
|
-
}
|
421
|
-
};
|
422
|
-
|
423
|
-
return({
|
424
|
-
name: "mustache.js",
|
425
|
-
version: "0.4.0",
|
426
|
-
|
427
|
-
/*
|
428
|
-
Turns a template and view into HTML
|
429
|
-
*/
|
430
|
-
to_html: function (template, view, partials, send_fun) {
|
431
|
-
var renderer = new Renderer();
|
432
|
-
if (send_fun) {
|
433
|
-
renderer.send = send_fun;
|
434
|
-
}
|
435
|
-
renderer.render(template, view || {}, partials);
|
436
|
-
if (!send_fun) {
|
437
|
-
return renderer.buffer.join("\n");
|
438
|
-
}
|
439
|
-
}
|
440
|
-
});
|
441
|
-
}();
|
442
|
-
/*!
|
443
|
-
ICanHaz.js -- by @HenrikJoreteg
|
444
|
-
*/
|
445
|
-
/*global */
|
446
|
-
(function () {
|
447
|
-
function trim(stuff) {
|
448
|
-
if (''.trim) return stuff.trim();
|
449
|
-
else return stuff.replace(/^\s+/, '').replace(/\s+$/, '');
|
450
|
-
}
|
451
|
-
var ich = {
|
452
|
-
VERSION: "0.10",
|
453
|
-
templates: {},
|
454
|
-
|
455
|
-
// grab jquery or zepto if it's there
|
456
|
-
$: (typeof window !== 'undefined') ? window.jQuery || window.Zepto || null : null,
|
457
|
-
|
458
|
-
// public function for adding templates
|
459
|
-
// can take a name and template string arguments
|
460
|
-
// or can take an object with name/template pairs
|
461
|
-
// We're enforcing uniqueness to avoid accidental template overwrites.
|
462
|
-
// If you want a different template, it should have a different name.
|
463
|
-
addTemplate: function (name, templateString) {
|
464
|
-
if (typeof name === 'object') {
|
465
|
-
for (var template in name) {
|
466
|
-
this.addTemplate(template, name[template]);
|
467
|
-
}
|
468
|
-
return;
|
469
|
-
}
|
470
|
-
if (ich[name]) {
|
471
|
-
console.error("Invalid name: " + name + ".");
|
472
|
-
} else if (ich.templates[name]) {
|
473
|
-
console.error("Template \"" + name + " \" exists");
|
474
|
-
} else {
|
475
|
-
ich.templates[name] = templateString;
|
476
|
-
ich[name] = function (data, raw) {
|
477
|
-
data = data || {};
|
478
|
-
var result = Mustache.to_html(ich.templates[name], data, ich.templates);
|
479
|
-
return (ich.$ && !raw) ? ich.$(result) : result;
|
480
|
-
};
|
481
|
-
}
|
482
|
-
},
|
483
|
-
|
484
|
-
// clears all retrieval functions and empties cache
|
485
|
-
clearAll: function () {
|
486
|
-
for (var key in ich.templates) {
|
487
|
-
delete ich[key];
|
488
|
-
}
|
489
|
-
ich.templates = {};
|
490
|
-
},
|
491
|
-
|
492
|
-
// clears/grabs
|
493
|
-
refresh: function () {
|
494
|
-
ich.clearAll();
|
495
|
-
ich.grabTemplates();
|
496
|
-
},
|
497
|
-
|
498
|
-
// grabs templates from the DOM and caches them.
|
499
|
-
// Loop through and add templates.
|
500
|
-
// Whitespace at beginning and end of all templates inside <script> tags will
|
501
|
-
// be trimmed. If you want whitespace around a partial, add it in the parent,
|
502
|
-
// not the partial. Or do it explicitly using <br/> or
|
503
|
-
grabTemplates: function () {
|
504
|
-
var i,
|
505
|
-
scripts = document.getElementsByTagName('script'),
|
506
|
-
script,
|
507
|
-
trash = [];
|
508
|
-
for (i = 0, l = scripts.length; i < l; i++) {
|
509
|
-
script = scripts[i];
|
510
|
-
if (script && script.innerHTML && script.id && (script.type === "text/html" || script.type === "text/x-icanhaz")) {
|
511
|
-
ich.addTemplate(script.id, trim(script.innerHTML));
|
512
|
-
trash.unshift(script);
|
513
|
-
}
|
514
|
-
}
|
515
|
-
for (i = 0, l = trash.length; i < l; i++) {
|
516
|
-
trash[i].parentNode.removeChild(trash[i]);
|
517
|
-
}
|
518
|
-
}
|
519
|
-
};
|
520
|
-
|
521
|
-
// Use CommonJS if applicable
|
522
|
-
if (typeof require !== 'undefined') {
|
523
|
-
module.exports = ich;
|
524
|
-
} else {
|
525
|
-
// else attach it to the window
|
526
|
-
window.ich = ich;
|
527
|
-
}
|
528
|
-
|
529
|
-
if (typeof document !== 'undefined') {
|
530
|
-
if (ich.$) {
|
531
|
-
ich.$(function () {
|
532
|
-
ich.grabTemplates();
|
533
|
-
});
|
534
|
-
} else {
|
535
|
-
document.addEventListener('DOMContentLoaded', function () {
|
536
|
-
ich.grabTemplates();
|
537
|
-
}, true);
|
538
|
-
}
|
539
|
-
}
|
540
|
-
|
541
|
-
})();
|
542
|
-
})();
|