js2 0.0.10 → 0.1.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.
- data/Manifest +42 -0
- data/README.md +65 -0
- data/Rakefile +19 -35
- data/bin/js2 +80 -66
- data/config/js2.yml +2 -0
- data/js2.gemspec +33 -0
- data/lib/js2/{haml_parser.rb → parser/haml.rb} +2 -2
- data/lib/js2/{haml_engine.rb → parser/haml_engine.rb} +1 -1
- data/lib/js2/parser/lexer.rb +37 -0
- data/lib/js2/{parser.rb → parser/tokenizer.rb} +157 -143
- data/lib/js2/{replace.rb → ragel/helper.rb} +16 -5
- data/lib/js2/ragel/tokenizer.rl +561 -0
- data/lib/js2/{tokenizer.rl.erb → ragel/tokenizer.rl.erb} +12 -19
- data/lib/js2/standard/factory.rb +289 -0
- data/lib/js2/standard/node.rb +75 -0
- data/lib/js2/util/compilation.rb +77 -0
- data/lib/js2/util/config.rb +84 -0
- data/lib/js2/util/exec.rb +34 -0
- data/lib/js2/util/file_handler.rb +73 -0
- data/lib/js2/{js2bootstrap.js2 → util/js2bootstrap.js2} +12 -68
- data/lib/js2/util/processor.rb +88 -0
- data/lib/js2/util/rdoc.rb +35 -0
- data/lib/js2/{sel_decorator.rb → util/sel_decorator.rb} +11 -1
- data/lib/js2.rb +22 -45
- data/test/compiled/bar.js +3 -0
- data/test/compiled/basic.comp.js +31 -0
- data/test/compiled/basic.js +27 -0
- data/test/compiled/foo.js +3 -0
- data/test/fixtures/bar.js2 +3 -0
- data/test/fixtures/basic.js2 +27 -0
- data/test/fixtures/basic.js2.haml +4 -0
- data/test/fixtures/basic.js2.yml +5 -0
- data/test/fixtures/curry.js2 +5 -0
- data/test/fixtures/foo.js2 +3 -0
- data/test/fixtures/member.js2 +14 -0
- data/test/fixtures/private.js2 +5 -0
- data/test/fixtures/property.js2 +4 -0
- data/test/test_helper.rb +25 -0
- data/test/test_js2.rb +43 -0
- data/wiki/features.md +106 -0
- data/wiki/installation.md +53 -0
- metadata +89 -83
- data/Changelog +0 -33
- data/History.txt +0 -4
- data/Manifest.txt +0 -35
- data/PostInstall.txt +0 -7
- data/README +0 -69
- data/README.rdoc +0 -69
- data/README.txt +0 -69
- data/examples/js2.yml +0 -8
- data/examples/test.yml +0 -5
- data/lib/javascript/sel_marker.js2 +0 -150
- data/lib/javascript/test.js2 +0 -73
- data/lib/js2/config.rb +0 -39
- data/lib/js2/daemon.rb +0 -35
- data/lib/js2/file_handler.rb +0 -91
- data/lib/js2/foo.js2.haml +0 -3
- data/lib/js2/js2.js +0 -110
- data/lib/js2/processor.rb +0 -112
- data/lib/js2/test/selenium.rb +0 -119
- data/lib/js2/test/selenium_element.rb +0 -234
- data/lib/js2/test/selenium_helper.rb +0 -27
- data/lib/js2/tree.rb +0 -351
- data/lib/js2/universe.rb +0 -123
- data/lib/tasks/js2.rake +0 -9
- data/website/index.txt +0 -86
- /data/{LICENSE → lib/js2/standard/class_node.rb} +0 -0
@@ -0,0 +1,289 @@
|
|
1
|
+
# TODO: break this up into multiple files
|
2
|
+
class JS2::Standard::PageNode < JS2::Standard::Node
|
3
|
+
attr_accessor :klasses, :file
|
4
|
+
|
5
|
+
def initialize (idx, string, factory)
|
6
|
+
@klasses = []
|
7
|
+
super(idx, string, factory)
|
8
|
+
end
|
9
|
+
|
10
|
+
def stop (idx)
|
11
|
+
JS2::Standard::ForeachNode.reset!
|
12
|
+
super(idx)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class JS2::Standard::CommentNode < JS2::Standard::Node
|
17
|
+
def clean
|
18
|
+
return to_s.gsub(%r|^\s*\/?\*+\s?\/?|, '')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class JS2::Standard::ClassNode < JS2::Standard::Node
|
23
|
+
REGEX = /^(\s*class|module)\s+([\w\.]+)\s+(extends\s+([\w\.]+))?\s*\{(.*)/m
|
24
|
+
|
25
|
+
def handle_first_string (str)
|
26
|
+
if m = str.match(REGEX)
|
27
|
+
@name = m[2]
|
28
|
+
@extends = m[4]
|
29
|
+
@ending = m[5]
|
30
|
+
|
31
|
+
if @extends
|
32
|
+
@extends = "#{@name}.oo('extends', #{@extends});"
|
33
|
+
end
|
34
|
+
|
35
|
+
return %|JS2.OO.#{create_name}("#{@name}"); #{@extends} (function (K,Package) {var self=K; var _super=JS2.OO['super']; #{@ending}|
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def methods
|
40
|
+
ret = []
|
41
|
+
|
42
|
+
@children.each do |c|
|
43
|
+
if c.is_a?(JS2::Standard::MethodNode)
|
44
|
+
ret << c
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
return ret
|
49
|
+
end
|
50
|
+
|
51
|
+
def name
|
52
|
+
if m = @string[@start_idx .. @stop_idx].match(REGEX)
|
53
|
+
return m[2]
|
54
|
+
else
|
55
|
+
return ''
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def create_name
|
60
|
+
return 'createClass'
|
61
|
+
end
|
62
|
+
|
63
|
+
def handle_ending (str)
|
64
|
+
pkg = @name.split(/\./)
|
65
|
+
pkg.pop()
|
66
|
+
|
67
|
+
if pkg.empty?
|
68
|
+
pkg = 'null'
|
69
|
+
else
|
70
|
+
pkg = pkg.join('.')
|
71
|
+
end
|
72
|
+
|
73
|
+
return str.sub(/\s*\z/, ")(#{@name}, #{pkg});")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class JS2::Standard::ModuleNode < JS2::Standard::ClassNode
|
78
|
+
def createName
|
79
|
+
return 'createModule'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
class JS2::Standard::PrivateNode < JS2::Standard::Node
|
84
|
+
def handle_first_string (str)
|
85
|
+
return str.sub(/private/m, '// private')
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
class JS2::Standard::IncludeNode < JS2::Standard::Node
|
90
|
+
def handle_first_string (s)
|
91
|
+
return s.sub(/include\s*/, "K.oo('include', ").sub(/;$/, ');');
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
class JS2::Standard::MemberNode < JS2::Standard::Node
|
97
|
+
def handle_first_string (s)
|
98
|
+
method = 'member'
|
99
|
+
|
100
|
+
if s.match(/^(\s*)(static)\s*/)
|
101
|
+
method = 'staticMember'
|
102
|
+
s = s.sub(/static\s*/, '')
|
103
|
+
end
|
104
|
+
|
105
|
+
return s.sub(/var\s*([\$\w]+)/) { "K.oo('#{method}', '" + $1 + "'" }.sub(/;(\s*)$/) { ");#{$1}" }.sub(/\s*=/, ', ');
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
class JS2::Standard::CurryNode < JS2::Standard::Node
|
111
|
+
REGEX = %r|^curry\s*([^\{]*)?\{(.*)$|m
|
112
|
+
REGEX_WITH = %r|with\s+\(([^)]*)\)|
|
113
|
+
REGEX_ARGS = %r|^\s*\(([^)]*)\)|
|
114
|
+
REGEX_ENDING = %r|\}([^\}]*)\z|
|
115
|
+
|
116
|
+
def handle_first_string (str)
|
117
|
+
m = str.match(REGEX)
|
118
|
+
@decl = m[1].strip
|
119
|
+
@stop = m[2]
|
120
|
+
|
121
|
+
@args = ''
|
122
|
+
@in_scoped = ''
|
123
|
+
@scoped = ''
|
124
|
+
|
125
|
+
if m = @decl.match(REGEX_WITH)
|
126
|
+
in_scoped = m[1].split(',').collect { |v| v.strip }
|
127
|
+
scoped = in_scoped.collect { |v| v == 'this' ? 'self' : v }
|
128
|
+
if in_scoped.length
|
129
|
+
@scoped = scoped.join(', ')
|
130
|
+
@in_scoped = in_scoped.join(', ')
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
if m = @decl.match(%r|^\s*\(([^)]*)\)|)
|
135
|
+
@args = m[1].strip
|
136
|
+
end
|
137
|
+
|
138
|
+
return %|(function (#{@scoped}) { return function (#{@args}) {#{@stop}|
|
139
|
+
end
|
140
|
+
|
141
|
+
def handle_ending (str)
|
142
|
+
if m = str.match(REGEX_ENDING)
|
143
|
+
return str.sub(REGEX_ENDING) { |str| "}})(#{@in_scoped})#{m[1]}" }
|
144
|
+
end
|
145
|
+
|
146
|
+
return str
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
class JS2::Standard::MethodNode < JS2::Standard::Node
|
152
|
+
attr_accessor :name, :args, :static
|
153
|
+
|
154
|
+
REGEX = /^(\s*)(static\s+)?function\s+([\$\w\.]+)\s*\(([^)]*)\)\s*\{(.*)/m
|
155
|
+
|
156
|
+
def handle_first_string (s)
|
157
|
+
m = s.match(REGEX)
|
158
|
+
space = m[1]
|
159
|
+
@static = m[2]
|
160
|
+
@name = m[3]
|
161
|
+
@args = m[4]
|
162
|
+
@start = m[5]
|
163
|
+
|
164
|
+
m = static ? 'staticMember' : 'method'
|
165
|
+
return %|#{space}K.oo('#{m}', "#{@name}", function (#{@args}) {#{@start}|
|
166
|
+
end
|
167
|
+
|
168
|
+
def handle_ending (str)
|
169
|
+
return str.sub!(/(\s*)\z/) { |m| ");#{m}" }
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
|
174
|
+
class JS2::Standard::AccessorNode < JS2::Standard::Node
|
175
|
+
REGEX = /(\s*)accessor(\s+)([\w+,\s]+\w)(\s*);(\s*)/
|
176
|
+
|
177
|
+
def handle_first_string (str)
|
178
|
+
m = str.match(REGEX)
|
179
|
+
space = m[1]
|
180
|
+
mid_space = m[2]
|
181
|
+
list = m[3].split(/,/).collect { |i| i.strip }
|
182
|
+
end_space = m[4]
|
183
|
+
trailing = m[5]
|
184
|
+
|
185
|
+
return %|#{space}K.oo('accessor',#{mid_space}[ #{list.collect { |i| "'#{i}'" }.join(',')} ])#{end_space};#{trailing}|
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
class JS2::Standard::ForeachNode < JS2::Standard::Node
|
190
|
+
# start var iterator array
|
191
|
+
REGEX = /(\s*)foreach\s*\(\s*var\s*([\$\w]+)(\s*:\s*([\$\w]))?\s*in\s*([^\s]+)\s*\)/
|
192
|
+
attr_accessor :iterator, :item, :array
|
193
|
+
@@inc = 0
|
194
|
+
|
195
|
+
def handle_first_string (s)
|
196
|
+
m = s.match(REGEX)
|
197
|
+
start = m[1]
|
198
|
+
item = m[2]
|
199
|
+
iterator = m[4]
|
200
|
+
array = m[5]
|
201
|
+
|
202
|
+
it = iterator
|
203
|
+
|
204
|
+
unless iterator
|
205
|
+
it = 'it' + @@inc.to_s
|
206
|
+
@@inc += 1
|
207
|
+
end
|
208
|
+
|
209
|
+
len = it + '__len'
|
210
|
+
arr = it + '__arr'
|
211
|
+
|
212
|
+
return %(#{start}for (var #{it}=0,#{item},#{arr}=#{array},#{len}=#{arr}.length; (#{item}=#{arr}[#{it}]) || #{it}<#{len}; #{it}++))
|
213
|
+
end
|
214
|
+
|
215
|
+
def self.reset!
|
216
|
+
@@inc = 0
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
class JS2::Standard::PropertyNode < JS2::Standard::Node
|
221
|
+
REGEX = /(\s*)property(\s+)([\w+,\s]+\w)(\s*);(\s*)/
|
222
|
+
def handle_first_string (s)
|
223
|
+
m = s.match(REGEX)
|
224
|
+
space = m[1]
|
225
|
+
mid_space = m[2]
|
226
|
+
list = m[3].split(/,/).collect { |i| i.strip }
|
227
|
+
end_space = m[4]
|
228
|
+
trailing = m[5]
|
229
|
+
|
230
|
+
return %|#{space}K.oo('property',#{mid_space}[ #{list.collect { |i| "'#{i}'" }.join(',')} ])#{end_space};#{trailing}|
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
|
235
|
+
class JS2::Standard::StuffNode < JS2::Standard::Node
|
236
|
+
end
|
237
|
+
|
238
|
+
|
239
|
+
class JS2::Standard::Factory
|
240
|
+
attr_accessor :decorators
|
241
|
+
|
242
|
+
@@supports = [ :CLASS, :MEMBER, :METHOD, :ACCESSOR, :FOREACH, :PROPERTY, :INCLUDE, :CURRY, :PAGE, :COMMENT, :STUFF, :MODULE, :PRIVATE ]
|
243
|
+
@@lookup = Hash.new
|
244
|
+
|
245
|
+
@@supports.each do |v|
|
246
|
+
name = v.to_s.downcase.sub(/(\w)/) { |m| m.upcase }
|
247
|
+
@@lookup[v] = eval "JS2::Standard::#{name}Node"
|
248
|
+
end
|
249
|
+
|
250
|
+
def initialize
|
251
|
+
@decorators = []
|
252
|
+
end
|
253
|
+
|
254
|
+
def get_class (type)
|
255
|
+
klass = @@lookup[type] || JS2::Standard::Node
|
256
|
+
end
|
257
|
+
|
258
|
+
def page_node (string, file = nil)
|
259
|
+
@page = new_node(:PAGE, 0, string)
|
260
|
+
@page.file = file
|
261
|
+
@comment = nil
|
262
|
+
return @page
|
263
|
+
end
|
264
|
+
|
265
|
+
def new_node (type, idx, string)
|
266
|
+
klass = get_class(type)
|
267
|
+
node = klass.new(idx, string, self)
|
268
|
+
|
269
|
+
if type == :CLASS || type == :MODULE
|
270
|
+
@page.klasses << node
|
271
|
+
end
|
272
|
+
|
273
|
+
if type == :COMMENT
|
274
|
+
@comment = node
|
275
|
+
elsif @comment
|
276
|
+
node.comment = @comment
|
277
|
+
@comment = nil
|
278
|
+
end
|
279
|
+
|
280
|
+
setup_node(node)
|
281
|
+
|
282
|
+
return node
|
283
|
+
end
|
284
|
+
|
285
|
+
def setup_node (node)
|
286
|
+
# virtual
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
@@ -0,0 +1,75 @@
|
|
1
|
+
class JS2::Standard::Node
|
2
|
+
attr_accessor :type, :start_idx, :stop_idx, :children, :starting, :factory, :comment
|
3
|
+
|
4
|
+
def initialize (start_idx, str, factory)
|
5
|
+
@start_idx = start_idx
|
6
|
+
@string = str
|
7
|
+
@children = []
|
8
|
+
@factory = factory
|
9
|
+
@output = ''
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_child (type, start_idx)
|
13
|
+
child = factory.new_node(type, start_idx, @string)
|
14
|
+
@children.push(child)
|
15
|
+
return child
|
16
|
+
end
|
17
|
+
|
18
|
+
def stop (idx)
|
19
|
+
@stop_idx = idx
|
20
|
+
process!
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_s
|
24
|
+
return @output
|
25
|
+
end
|
26
|
+
|
27
|
+
def process! ()
|
28
|
+
last_idx = @start_idx
|
29
|
+
str = ''
|
30
|
+
|
31
|
+
first = true
|
32
|
+
@children.each do |c|
|
33
|
+
if c.start_idx > last_idx
|
34
|
+
str << handle_string(@string[last_idx .. c.start_idx-1], first)
|
35
|
+
first = false
|
36
|
+
end
|
37
|
+
|
38
|
+
result = c.to_s()
|
39
|
+
|
40
|
+
@factory.decorators.each do |d|
|
41
|
+
d.decorate(result, c)
|
42
|
+
end
|
43
|
+
|
44
|
+
str << result
|
45
|
+
last_idx = c.stop_idx + 1
|
46
|
+
end
|
47
|
+
|
48
|
+
if last_idx < @stop_idx
|
49
|
+
str << handle_string(@string[last_idx .. @stop_idx], first)
|
50
|
+
end
|
51
|
+
|
52
|
+
str = handle_ending(str)
|
53
|
+
|
54
|
+
@output = str
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def handle_string (str, first)
|
60
|
+
if first
|
61
|
+
return handle_first_string(str)
|
62
|
+
else
|
63
|
+
return str
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def handle_ending (str)
|
68
|
+
return str
|
69
|
+
end
|
70
|
+
|
71
|
+
def handle_first_string (str)
|
72
|
+
return str
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
class JS2::Util::Compilation
|
2
|
+
attr_accessor :klass_name, :require, :include, :template, :file
|
3
|
+
@@already = Hash.new
|
4
|
+
|
5
|
+
def initialize (klass_name, config, yml_file, file_handler)
|
6
|
+
@require = config['require'] || []
|
7
|
+
@include = config['include'] || []
|
8
|
+
@template = config['template'] || []
|
9
|
+
@klass_name = klass_name
|
10
|
+
@file = yml_file
|
11
|
+
@file_handler = file_handler
|
12
|
+
|
13
|
+
@make_compilation = config['make_compilation']
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.parse (yml_file, file_handler)
|
17
|
+
klasses = YAML.load_file(yml_file)
|
18
|
+
|
19
|
+
comps = []
|
20
|
+
klasses.each_pair do |k, config|
|
21
|
+
comps << self.new(k, config, yml_file, file_handler)
|
22
|
+
end
|
23
|
+
|
24
|
+
return comps
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.reset!
|
28
|
+
@@already = Hash.new
|
29
|
+
end
|
30
|
+
|
31
|
+
def compile (klasses, errors = [])
|
32
|
+
return unless @make_compilation
|
33
|
+
|
34
|
+
main_file = nil
|
35
|
+
if files = klasses[@klass_name]
|
36
|
+
main_file = @file_handler.outfile(files.first)
|
37
|
+
else
|
38
|
+
return
|
39
|
+
end
|
40
|
+
|
41
|
+
before = []
|
42
|
+
@require.each do |file|
|
43
|
+
before += get_files(file, klasses)
|
44
|
+
end
|
45
|
+
|
46
|
+
after = []
|
47
|
+
@include.each do |file|
|
48
|
+
after += get_files(file, klasses)
|
49
|
+
end
|
50
|
+
|
51
|
+
@template.each do |item|
|
52
|
+
after += get_files(item['class'], klasses)
|
53
|
+
end
|
54
|
+
|
55
|
+
file = main_file.sub(/\.js$/, '.comp.js')
|
56
|
+
str = ''
|
57
|
+
(before + [ main_file ] + after).uniq.each do |f|
|
58
|
+
if File.exist?(f)
|
59
|
+
str << File.read(f)
|
60
|
+
else
|
61
|
+
errors << [ "#{file} references #{f}, but js2 can't find it" ]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
str << "#{@klass_name}.oo('method', 'getTemplate', function () { return #{@template.to_json}; });"
|
66
|
+
File.open(file, 'w') { |f| f << str }
|
67
|
+
end
|
68
|
+
|
69
|
+
def get_files (klass_name_or_file, klasses)
|
70
|
+
ret = nil
|
71
|
+
if files = klasses[klass_name_or_file]
|
72
|
+
ret = files.collect { |f| @file_handler.outfile(f) }
|
73
|
+
else
|
74
|
+
ret = @file_handler.outfile(klass_name_or_file)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
class JS2::Util::Config
|
2
|
+
attr_accessor :node_factory, :lexer, :file_handler, :lexer, :haml_engine, :haml_vars, :asset_dir, :decorators
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@lexer = JS2::Parser::Lexer.new
|
6
|
+
@node_factory = JS2::Standard::Factory.new
|
7
|
+
@file_handler = JS2::Util::FileHandler.new
|
8
|
+
@haml_engine = JS2::Parser::HamlEngine.new
|
9
|
+
@haml_vars = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_decorator (decorator)
|
13
|
+
@node_factory.decorators << decorator
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.from_yml(yml, env = nil)
|
17
|
+
hash = YAML.load(yml)
|
18
|
+
hash = hash[env] if env
|
19
|
+
return self.from_hash(hash)
|
20
|
+
end
|
21
|
+
|
22
|
+
def load_hash (hash)
|
23
|
+
self.file_handler.js2_dir = hash['js2_dir'] if hash['js2_dir']
|
24
|
+
self.haml_engine = eval('::' + hash['haml_engine_class'] + '.new') if hash['haml_engine_class']
|
25
|
+
|
26
|
+
write_dir = hash['write_dir'] || hash['out_dir']
|
27
|
+
self.file_handler.out_dir = write_dir if write_dir
|
28
|
+
self.file_handler.haml_dir = hash['haml_dir'] || self.file_handler.js2_dir
|
29
|
+
end
|
30
|
+
|
31
|
+
def load_yml (yml, env = nil)
|
32
|
+
hash = YAML.load_file(yml)
|
33
|
+
hash = hash[env] if env
|
34
|
+
self.load_hash(hash)
|
35
|
+
end
|
36
|
+
|
37
|
+
def rails! (env = nil)
|
38
|
+
self.out_dir = './public/javascripts'
|
39
|
+
self.js2_dir = './app/js2'
|
40
|
+
self.haml_dir = './app/js2'
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def out_dir= (dir)
|
45
|
+
@file_handler.out_dir = dir
|
46
|
+
end
|
47
|
+
|
48
|
+
def js2_dir= (dir)
|
49
|
+
@file_handler.js2_dir = dir
|
50
|
+
end
|
51
|
+
|
52
|
+
def haml_dir= (dir)
|
53
|
+
@file_handler.haml_dir = dir
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_s
|
57
|
+
return <<-END
|
58
|
+
js2_dir: #{@file_handler.js2_dir}
|
59
|
+
out_dir: #{@file_handler.out_dir}
|
60
|
+
haml_dir: #{@file_handler.haml_dir}
|
61
|
+
END
|
62
|
+
end
|
63
|
+
|
64
|
+
def from_yml (yml, env = nil)
|
65
|
+
hash = YAML.load(yml)
|
66
|
+
hash = hash[env] if env
|
67
|
+
return self.from_hash(hash)
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.from_hash(hash)
|
71
|
+
config = self.new
|
72
|
+
config.load_hash(hash)
|
73
|
+
|
74
|
+
return config
|
75
|
+
end
|
76
|
+
|
77
|
+
def example_yml
|
78
|
+
return <<-END
|
79
|
+
js2_dir: './app/js2'
|
80
|
+
haml_dir: './app/js2'
|
81
|
+
out_dir: './public/javascripts'
|
82
|
+
END
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class JS2::Util::Exec
|
2
|
+
def initialize (config, options)
|
3
|
+
@config = config
|
4
|
+
end
|
5
|
+
|
6
|
+
def rails!
|
7
|
+
@config.out_dir = './public/javascripts'
|
8
|
+
@config.js2_dir = './app/js2'
|
9
|
+
@config.asset_dir = './app/js2'
|
10
|
+
end
|
11
|
+
|
12
|
+
def normal!
|
13
|
+
@config.out_dir = '.'
|
14
|
+
@config.js2_dir = '.'
|
15
|
+
end
|
16
|
+
|
17
|
+
def daemonize (timeout = 1)
|
18
|
+
get_processor!
|
19
|
+
while 1
|
20
|
+
@processor.process!
|
21
|
+
sleep timeout
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def process
|
26
|
+
get_processor!
|
27
|
+
@processor.process!
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_processor!
|
31
|
+
@processor = JS2::Util::Processor.new(@config)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
class JS2::Util::FileHandler
|
2
|
+
attr_accessor :js2_dir, :out_dir, :haml_dir, :doc_dir
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@js2_dir = '.'
|
6
|
+
@out_dir = '.'
|
7
|
+
@haml_dir = '.'
|
8
|
+
@doc_dir = '.'
|
9
|
+
|
10
|
+
@lookup = {
|
11
|
+
:js2 => :js2_dir,
|
12
|
+
:haml => :haml_dir,
|
13
|
+
:yml => :js2_dir
|
14
|
+
}
|
15
|
+
|
16
|
+
@mtimes = Hash.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def docfile (file)
|
20
|
+
return file.sub(/^#{@js2_dir}/, @doc_dir).sub(/\.js2$/, '.js')
|
21
|
+
end
|
22
|
+
|
23
|
+
def needs_update
|
24
|
+
@found = Hash.new
|
25
|
+
|
26
|
+
files = []
|
27
|
+
files += get_changed_files(:js2)
|
28
|
+
files += get_changed_files(:haml)
|
29
|
+
files += get_changed_files(:yml)
|
30
|
+
|
31
|
+
missing = false
|
32
|
+
@mtimes.keys.each do |f|
|
33
|
+
unless @found[f]
|
34
|
+
@mtimes.delete(f)
|
35
|
+
missing = true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
return files
|
40
|
+
end
|
41
|
+
|
42
|
+
def outfile (file)
|
43
|
+
return file.sub(/^#{@js2_dir}/, @out_dir).sub(/\.js2$/, '.js')
|
44
|
+
end
|
45
|
+
|
46
|
+
def get_files (ext)
|
47
|
+
ext = ext.to_sym
|
48
|
+
|
49
|
+
my_ext = :js2 == ext ? 'js2' : "js2.#{ext}"
|
50
|
+
my_dir = self.send(@lookup[ext])
|
51
|
+
return Dir.glob(my_dir + "/**/*/*.#{my_ext}") + Dir.glob(my_dir + "/*.#{my_ext}")
|
52
|
+
end
|
53
|
+
|
54
|
+
def reset!
|
55
|
+
@mtimes = Hash.new
|
56
|
+
end
|
57
|
+
|
58
|
+
def get_changed_files (ext)
|
59
|
+
ret = []
|
60
|
+
get_files(ext).each do |f|
|
61
|
+
@found[f] = true
|
62
|
+
mtime = File.mtime(f)
|
63
|
+
if ! @mtimes[f] || @mtimes[f] < mtime
|
64
|
+
@mtimes[f] = mtime
|
65
|
+
ret << f
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
return ret
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
end
|