ice 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +18 -0
- data/{LICENSE → MIT-LICENSE} +1 -1
- data/README.markdown +49 -77
- data/Rakefile +21 -34
- data/lib/ice.rb +8 -4
- data/lib/ice/base_cube.rb +32 -2
- data/lib/ice/cube_helpers.rb +29 -0
- data/lib/ice/cubeable.rb +12 -12
- data/lib/ice/eco_template/base.rb +17 -0
- data/lib/ice/eco_template/context.rb +76 -0
- data/lib/ice/eco_template/handler.rb +30 -0
- data/lib/ice/railtie.rb +6 -10
- metadata +22 -79
- data/.gitignore +0 -23
- data/.specification +0 -135
- data/VERSION +0 -1
- data/ice.gemspec +0 -87
- data/ice_js/History.md +0 -5
- data/ice_js/Readme.md +0 -29
- data/ice_js/lib/form_tag_inputs.js +0 -91
- data/ice_js/lib/path_helper.js +0 -49
- data/ice_js/spec/commands/example_command.rb +0 -19
- data/ice_js/spec/dom.html +0 -23
- data/ice_js/spec/node.js +0 -10
- data/ice_js/spec/rhino.js +0 -10
- data/ice_js/spec/server.html +0 -18
- data/ice_js/spec/server.rb +0 -4
- data/ice_js/spec/support/js.jar +0 -0
- data/ice_js/spec/unit/spec.helper.js +0 -0
- data/ice_js/spec/unit/spec.js +0 -180
- data/init.rb +0 -6
- data/lib/extras/ice_view.rb +0 -166
- data/lib/ice/base.rb +0 -50
- data/lib/parser.js +0 -320
- data/spec/base_cube_spec.rb +0 -45
- data/spec/cube_spec.rb +0 -119
- data/spec/ice_spec.rb +0 -97
- data/spec/spec.opts +0 -1
- data/spec/spec_helper.rb +0 -12
- data/togo +0 -60
data/init.rb
DELETED
data/lib/extras/ice_view.rb
DELETED
@@ -1,166 +0,0 @@
|
|
1
|
-
# IceView is a action view extension class. You can register it with rails
|
2
|
-
# and use ice as an template system for .ice files
|
3
|
-
#
|
4
|
-
# Example
|
5
|
-
#
|
6
|
-
# ActionView::Base::register_template_handler :ice, IceView
|
7
|
-
|
8
|
-
module RoutesJs
|
9
|
-
|
10
|
-
def get_routes
|
11
|
-
|
12
|
-
response = rails_route_function
|
13
|
-
|
14
|
-
Rails.application.routes.routes.collect do |route|
|
15
|
-
|
16
|
-
puts route.class.to_s
|
17
|
-
puts route.path
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
puts route.inspect
|
22
|
-
|
23
|
-
path = route.path
|
24
|
-
puts "%%%"
|
25
|
-
puts route.conditions.inspect
|
26
|
-
puts route.requirements
|
27
|
-
|
28
|
-
named_route = Rails.application.routes.
|
29
|
-
named_routes.routes.key(route).to_s
|
30
|
-
|
31
|
-
if named_route != ''
|
32
|
-
puts named_route + " kkyy " + route.path
|
33
|
-
|
34
|
-
if path.match /(.*)\(\.\:format\)$/
|
35
|
-
path = $1
|
36
|
-
end
|
37
|
-
|
38
|
-
response << route_function("#{named_route}_path", path)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
# puts response
|
42
|
-
response
|
43
|
-
end
|
44
|
-
|
45
|
-
private
|
46
|
-
|
47
|
-
def rails_route_function
|
48
|
-
<<EOF
|
49
|
-
function rails_route(path, var_pairs) {
|
50
|
-
var pair_index = 0,
|
51
|
-
path_copy = path;
|
52
|
-
for(; pair_index < var_pairs.length; pair_index++) {
|
53
|
-
path_copy = path_copy.replace(
|
54
|
-
':' + var_pairs[pair_index][0],
|
55
|
-
var_pairs[pair_index][1]
|
56
|
-
);
|
57
|
-
}
|
58
|
-
return(
|
59
|
-
path_copy
|
60
|
-
.replace(/[(][.]:.+[)][?]/g, '')
|
61
|
-
.replace(/[(]|[)][?]/g, '')
|
62
|
-
);
|
63
|
-
}
|
64
|
-
EOF
|
65
|
-
end
|
66
|
-
|
67
|
-
def route_function name, path
|
68
|
-
<<EOF
|
69
|
-
function #{name}(variables) {
|
70
|
-
var var_pairs = [];
|
71
|
-
for(var key in variables) {
|
72
|
-
var_pairs.push([key, variables[key]]);
|
73
|
-
}
|
74
|
-
return(rails_route('#{path}', var_pairs));
|
75
|
-
}
|
76
|
-
EOF
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
class IceView
|
81
|
-
include RoutesJs
|
82
|
-
include ActionView::Template::Handlers::Compilable
|
83
|
-
PROTECTED_ASSIGNS = %w( template_root response _session template_class action_name request_origin session template
|
84
|
-
_response url _request _cookies variables_added _flash params _headers request cookies
|
85
|
-
ignore_missing_templates flash _params logger before_filter_chain_aborted headers )
|
86
|
-
PROTECTED_INSTANCE_VARIABLES = %w( @_request @controller @_first_render @_memoized__pick_template @view_paths
|
87
|
-
@helpers @assigns_added @template @_render_stack @template_format @assigns )
|
88
|
-
|
89
|
-
# attr_accessor :controller
|
90
|
-
|
91
|
-
# def self.call(template)
|
92
|
-
# "IceView.new(self).render(#{template})"
|
93
|
-
# end
|
94
|
-
|
95
|
-
def initialize(view = nil)
|
96
|
-
@view = view
|
97
|
-
end
|
98
|
-
|
99
|
-
def compile(template)
|
100
|
-
|
101
|
-
"IceView.new(self).render('#{template.inspect}' )"
|
102
|
-
end
|
103
|
-
|
104
|
-
def render(template, local_assigns = {})
|
105
|
-
|
106
|
-
@view.controller.headers["Content-Type"] ||= 'text/html; charset=utf-8'
|
107
|
-
source = open(Rails.root + template).read
|
108
|
-
|
109
|
-
assigns = @view.assigns.reject{ |k,v| PROTECTED_ASSIGNS.include?(k) }
|
110
|
-
if content_for_layout = @view.instance_variable_get("@content_for_layout")
|
111
|
-
assigns['content_for_layout'] = content_for_layout
|
112
|
-
end
|
113
|
-
assigns.merge!(local_assigns.stringify_keys)
|
114
|
-
route_functions = "<% " + get_routes + " %>\n"
|
115
|
-
|
116
|
-
path_helper_code = File.read(File.dirname(__FILE__) + "/../../ice_js/lib/path_helper.js")
|
117
|
-
path_helper = "<% " + path_helper_code + " %>\n"
|
118
|
-
|
119
|
-
|
120
|
-
source = route_functions + path_helper + source
|
121
|
-
# puts source
|
122
|
-
|
123
|
-
Ice.convert_template(source, assigns)
|
124
|
-
=begin
|
125
|
-
|
126
|
-
|
127
|
-
puts "hhhhhhhooooootttt"
|
128
|
-
# Rails 2.2 Template has source, but not locals
|
129
|
-
if template.respond_to?(:source) && !template.respond_to?(:locals)
|
130
|
-
assigns = (@view.instance_variables - PROTECTED_INSTANCE_VARIABLES).inject({}) do |hash, ivar|
|
131
|
-
hash[ivar[1..-1]] = @view.instance_variable_get(ivar)
|
132
|
-
hash
|
133
|
-
end
|
134
|
-
else
|
135
|
-
assigns = @view.assigns.reject{ |k,v| PROTECTED_ASSIGNS.include?(k) }
|
136
|
-
end
|
137
|
-
|
138
|
-
source = template.respond_to?(:source) ? template.source : template
|
139
|
-
local_assigns = (template.respond_to?(:locals) ? template.locals : local_assigns) || {}
|
140
|
-
|
141
|
-
if content_for_layout = @view.instance_variable_get("@content_for_layout")
|
142
|
-
assigns['content_for_layout'] = content_for_layout
|
143
|
-
end
|
144
|
-
assigns.merge!(local_assigns.stringify_keys)
|
145
|
-
|
146
|
-
route_functions = "<% " + get_routes + " %>"
|
147
|
-
|
148
|
-
path_helper_code = File.read(File.dirname(__FILE__) + "/../../ice_js/lib/path_helper.js")
|
149
|
-
path_helper = "<% " + path_helper_code + " %>"
|
150
|
-
source = route_functions + path_helper + source
|
151
|
-
|
152
|
-
puts "ooooootttt"
|
153
|
-
Ice.convert_template(source, assigns)
|
154
|
-
#ice = Ice::Template.parse(source)
|
155
|
-
#ice.render(assigns, :filters => [@view.controller.master_helper_module], :registers => {:action_view => @view, :controller => @view.controller})
|
156
|
-
|
157
|
-
=end
|
158
|
-
|
159
|
-
|
160
|
-
end
|
161
|
-
|
162
|
-
def compilable?
|
163
|
-
false
|
164
|
-
end
|
165
|
-
|
166
|
-
end
|
data/lib/ice/base.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
require 'v8'
|
2
|
-
|
3
|
-
class Object
|
4
|
-
def to_ice
|
5
|
-
nil
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
[FalseClass, TrueClass, Numeric, String].each do |cls|
|
10
|
-
cls.class_eval do
|
11
|
-
def to_ice
|
12
|
-
self
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
class Array
|
18
|
-
def to_ice
|
19
|
-
map &:to_ice
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
class Hash
|
24
|
-
def to_ice
|
25
|
-
res = {}
|
26
|
-
each_pair do |key,value|
|
27
|
-
res[key] = value.to_ice
|
28
|
-
end
|
29
|
-
res
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
module Ice
|
36
|
-
def self.convert_template(template_text, vars = {})
|
37
|
-
|
38
|
-
V8::Context.new do |cxt|
|
39
|
-
cxt.load "#{File.dirname(__FILE__)}/../parser.js"
|
40
|
-
|
41
|
-
vars.each_pair do |key, value|
|
42
|
-
cxt[key] = value.to_ice
|
43
|
-
end
|
44
|
-
|
45
|
-
jst = cxt['Jst']
|
46
|
-
return @evaled = jst.evaluate(jst.compile(template_text), {})
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
data/lib/parser.js
DELETED
@@ -1,320 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
Copyright 2008, mark turansky (www.markturansky.com)
|
3
|
-
Copyright 2010, Andrew Kelley (superjoesoftware.com)
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
7
|
-
in the Software without restriction, including without limitation the rights
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
copies of the Software, and to permit persons to whom the Software is furnished
|
10
|
-
to do so, subject to the following conditions:
|
11
|
-
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
13
|
-
copies or substantial portions of the Software.
|
14
|
-
|
15
|
-
The Software shall be used for Good, not Evil.
|
16
|
-
|
17
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
|
-
THE SOFTWARE.
|
24
|
-
|
25
|
-
(This is the license from www.json.org and I think it's awesome)
|
26
|
-
*/
|
27
|
-
|
28
|
-
String.prototype.endsWith = function endsWith(c) {
|
29
|
-
if (this.charAt(this.length - 1) == c) {
|
30
|
-
return true;
|
31
|
-
} else {
|
32
|
-
return false;
|
33
|
-
}
|
34
|
-
};
|
35
|
-
|
36
|
-
String.prototype.startsWith = function startsWith(c) {
|
37
|
-
if (this.charAt(0) == c) {
|
38
|
-
return true;
|
39
|
-
} else {
|
40
|
-
return false;
|
41
|
-
}
|
42
|
-
};
|
43
|
-
|
44
|
-
String.prototype.replaceAll = function replaceAll(a, b) {
|
45
|
-
var s = this;
|
46
|
-
while (s.indexOf(a) > -1) {
|
47
|
-
s = s.replace(a, b);
|
48
|
-
}
|
49
|
-
return s;
|
50
|
-
};
|
51
|
-
|
52
|
-
var Jst = function () {
|
53
|
-
// private variables:
|
54
|
-
var that; // reference to the public object
|
55
|
-
|
56
|
-
// all write and writeln functions eval'd by Jst
|
57
|
-
// concatenate to this internal variable
|
58
|
-
var html = "";
|
59
|
-
|
60
|
-
// private functions
|
61
|
-
function CharacterStack(str) {
|
62
|
-
var i;
|
63
|
-
|
64
|
-
this.characters = [];
|
65
|
-
this.peek = function peek() {
|
66
|
-
return this.characters[this.characters.length - 1];
|
67
|
-
};
|
68
|
-
this.pop = function pop() {
|
69
|
-
return this.characters.pop();
|
70
|
-
};
|
71
|
-
this.push = function push(c) {
|
72
|
-
this.characters.push(c);
|
73
|
-
};
|
74
|
-
this.hasMore = function hasMore() {
|
75
|
-
if (this.characters.length > 0) {
|
76
|
-
return true;
|
77
|
-
} else {
|
78
|
-
return false;
|
79
|
-
}
|
80
|
-
};
|
81
|
-
|
82
|
-
for (i = str.length; i >= 0; i -= 1) {
|
83
|
-
this.characters.push(str.charAt(i));
|
84
|
-
}
|
85
|
-
}
|
86
|
-
|
87
|
-
function StringWriter() {
|
88
|
-
this.str = "";
|
89
|
-
this.write = function write(s) {
|
90
|
-
this.str += s;
|
91
|
-
};
|
92
|
-
this.toString = function toString() {
|
93
|
-
return this.str;
|
94
|
-
};
|
95
|
-
}
|
96
|
-
|
97
|
-
function parseScriptlet(stack) {
|
98
|
-
var fragment = new StringWriter();
|
99
|
-
var c; // character
|
100
|
-
|
101
|
-
while (stack.hasMore()) {
|
102
|
-
if (stack.peek() == '%') { //possible end delimiter
|
103
|
-
c = stack.pop();
|
104
|
-
if (stack.peek() == '>') { //end delimiter
|
105
|
-
// pop > so that it is not available to main parse loop
|
106
|
-
stack.pop();
|
107
|
-
if (stack.peek() == '\n') {
|
108
|
-
fragment.write(stack.pop());
|
109
|
-
}
|
110
|
-
break;
|
111
|
-
} else {
|
112
|
-
fragment.write(c);
|
113
|
-
}
|
114
|
-
} else {
|
115
|
-
fragment.write(stack.pop());
|
116
|
-
}
|
117
|
-
}
|
118
|
-
return fragment.toString();
|
119
|
-
}
|
120
|
-
|
121
|
-
function isOpeningDelimiter(c) {
|
122
|
-
if (c == "<" || c == "%lt;") {
|
123
|
-
return true;
|
124
|
-
} else {
|
125
|
-
return false;
|
126
|
-
}
|
127
|
-
}
|
128
|
-
|
129
|
-
function isClosingDelimiter(c) {
|
130
|
-
if (c == ">" || c == "%gt;") {
|
131
|
-
return true;
|
132
|
-
} else {
|
133
|
-
return false;
|
134
|
-
}
|
135
|
-
}
|
136
|
-
|
137
|
-
function appendExpressionFragment(writer, fragment, jstWriter) {
|
138
|
-
var i,j;
|
139
|
-
var c;
|
140
|
-
|
141
|
-
// check to be sure quotes are on both ends of a string literal
|
142
|
-
if (fragment.startsWith("\"") && !fragment.endsWith("\"")) {
|
143
|
-
//some scriptlets end with \n, especially if the script ends the file
|
144
|
-
if (fragment.endsWith("\n") && fragment.charAt(fragment.length - 2) == '"') {
|
145
|
-
//we're ok...
|
146
|
-
} else {
|
147
|
-
throw { "message":"'" + fragment + "' is not properly quoted"};
|
148
|
-
}
|
149
|
-
}
|
150
|
-
|
151
|
-
if (!fragment.startsWith("\"") && fragment.endsWith("\"")) {
|
152
|
-
throw { "message":"'" + fragment + "' is not properly quoted"};
|
153
|
-
}
|
154
|
-
|
155
|
-
// print or println?
|
156
|
-
if (fragment.endsWith("\n")) {
|
157
|
-
writer.write(jstWriter + "ln(");
|
158
|
-
//strip the newline
|
159
|
-
fragment = fragment.substring(0, fragment.length - 1);
|
160
|
-
} else {
|
161
|
-
writer.write(jstWriter + "(");
|
162
|
-
}
|
163
|
-
|
164
|
-
if (fragment.startsWith("\"") && fragment.endsWith("\"")) {
|
165
|
-
//strip the quotes
|
166
|
-
fragment = fragment.substring(1, fragment.length - 1);
|
167
|
-
writer.write("\"");
|
168
|
-
for (i = 0; i < fragment.length; i += 1) {
|
169
|
-
c = fragment.charAt(i);
|
170
|
-
if (c == '"') {
|
171
|
-
writer.write("\\");
|
172
|
-
writer.write(c);
|
173
|
-
}
|
174
|
-
}
|
175
|
-
writer.write("\"");
|
176
|
-
} else {
|
177
|
-
for (j = 0; j < fragment.length; j += 1) {
|
178
|
-
writer.write(fragment.charAt(j));
|
179
|
-
}
|
180
|
-
}
|
181
|
-
|
182
|
-
writer.write(");");
|
183
|
-
}
|
184
|
-
|
185
|
-
function appendTextFragment(writer, fragment) {
|
186
|
-
var i;
|
187
|
-
var c;
|
188
|
-
|
189
|
-
if (fragment.endsWith("\n")) {
|
190
|
-
writer.write("writeln(\"");
|
191
|
-
} else {
|
192
|
-
writer.write("write(\"");
|
193
|
-
}
|
194
|
-
|
195
|
-
for (i = 0; i < fragment.length; i += 1) {
|
196
|
-
c = fragment.charAt(i);
|
197
|
-
if (c == '"') {
|
198
|
-
writer.write("\\");
|
199
|
-
}
|
200
|
-
// we took care of the line break with print vs. println
|
201
|
-
if (c != '\n' && c != '\r') {
|
202
|
-
writer.write(c);
|
203
|
-
}
|
204
|
-
}
|
205
|
-
|
206
|
-
writer.write("\");");
|
207
|
-
}
|
208
|
-
|
209
|
-
function parseExpression(stack) {
|
210
|
-
var fragment = new StringWriter();
|
211
|
-
var c;
|
212
|
-
|
213
|
-
while (stack.hasMore()) {
|
214
|
-
if (stack.peek() == '%') { //possible end delimiter
|
215
|
-
c = stack.pop();
|
216
|
-
if (isClosingDelimiter(stack.peek())) { //end delimiter
|
217
|
-
//pop > so that it is not available to main parse loop
|
218
|
-
stack.pop();
|
219
|
-
if (stack.peek() == '\n') {
|
220
|
-
fragment.write(stack.pop());
|
221
|
-
}
|
222
|
-
break;
|
223
|
-
} else {
|
224
|
-
fragment.write("%");
|
225
|
-
}
|
226
|
-
} else {
|
227
|
-
fragment.write(stack.pop());
|
228
|
-
}
|
229
|
-
}
|
230
|
-
|
231
|
-
return fragment.toString();
|
232
|
-
}
|
233
|
-
|
234
|
-
function parseText(stack) {
|
235
|
-
var fragment = new StringWriter();
|
236
|
-
var c,d;
|
237
|
-
|
238
|
-
while (stack.hasMore()) {
|
239
|
-
if (isOpeningDelimiter(stack.peek())) { //possible delimiter
|
240
|
-
c = stack.pop();
|
241
|
-
if (stack.peek() == '%') { // delimiter!
|
242
|
-
// push c onto the stack to be used in main parse loop
|
243
|
-
stack.push(c);
|
244
|
-
break;
|
245
|
-
} else {
|
246
|
-
fragment.write(c);
|
247
|
-
}
|
248
|
-
} else {
|
249
|
-
d = stack.pop();
|
250
|
-
fragment.write(d);
|
251
|
-
if (d == '\n') { //done with this fragment. println it.
|
252
|
-
break;
|
253
|
-
}
|
254
|
-
}
|
255
|
-
}
|
256
|
-
return fragment.toString();
|
257
|
-
}
|
258
|
-
|
259
|
-
function write(s) {
|
260
|
-
html += s;
|
261
|
-
}
|
262
|
-
|
263
|
-
function writeln(s) {
|
264
|
-
write(s + "\n");
|
265
|
-
}
|
266
|
-
|
267
|
-
that = {
|
268
|
-
// public methods:
|
269
|
-
// pre-compile a template for quicker rendering. save the return value and
|
270
|
-
// pass it to evaluate.
|
271
|
-
compile: function (src) {
|
272
|
-
var stack = new CharacterStack(src);
|
273
|
-
var writer = new StringWriter();
|
274
|
-
|
275
|
-
var c;
|
276
|
-
var fragment;
|
277
|
-
while (stack.hasMore()) {
|
278
|
-
if (isOpeningDelimiter(stack.peek())) { //possible delimiter
|
279
|
-
c = stack.pop();
|
280
|
-
if (stack.peek() == '%') { //delimiter!
|
281
|
-
c = stack.pop();
|
282
|
-
if (stack.peek() == "=" || stack.peek() == "+") {
|
283
|
-
//not escaping html right now
|
284
|
-
stack.pop()
|
285
|
-
fragment = parseExpression(stack);
|
286
|
-
appendExpressionFragment(writer, fragment,
|
287
|
-
"write");
|
288
|
-
} else {
|
289
|
-
fragment = parseScriptlet(stack);
|
290
|
-
writer.write(fragment);
|
291
|
-
}
|
292
|
-
} else { //not a delimiter
|
293
|
-
stack.push(c);
|
294
|
-
fragment = parseText(stack);
|
295
|
-
appendTextFragment(writer, fragment);
|
296
|
-
}
|
297
|
-
} else {
|
298
|
-
fragment = parseText(stack);
|
299
|
-
appendTextFragment(writer, fragment);
|
300
|
-
}
|
301
|
-
}
|
302
|
-
return writer.toString();
|
303
|
-
},
|
304
|
-
|
305
|
-
// evaluate a pre-compiled script. recommended approach
|
306
|
-
evaluate: function (script, args) {
|
307
|
-
with(args) {
|
308
|
-
html = "";
|
309
|
-
eval(script);
|
310
|
-
return html;
|
311
|
-
}
|
312
|
-
},
|
313
|
-
|
314
|
-
// if you're lazy, you can use this
|
315
|
-
evaluateSingleShot: function (src, args) {
|
316
|
-
return this.evaluate(this.compile(src), args);
|
317
|
-
}
|
318
|
-
};
|
319
|
-
return that;
|
320
|
-
}();
|