js2 0.1.8 → 0.3.0.pre5

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.
Files changed (52) hide show
  1. data/bin/js2 +9 -126
  2. data/bin/js2-ruby +13 -0
  3. data/lib/js2/command.rb +16 -0
  4. data/lib/js2/context.rb +35 -0
  5. data/lib/js2/fs.rb +56 -0
  6. data/lib/js2/js2.js +1265 -0
  7. data/lib/js2/rack.rb +35 -0
  8. data/lib/js2.rb +19 -30
  9. metadata +28 -91
  10. data/CHANGELOG +0 -17
  11. data/Manifest +0 -45
  12. data/README.md +0 -75
  13. data/Rakefile +0 -28
  14. data/config/js2.yml +0 -2
  15. data/js2.gemspec +0 -36
  16. data/lib/js2/parser/haml.rb +0 -145
  17. data/lib/js2/parser/haml_engine.rb +0 -19
  18. data/lib/js2/parser/lexer.rb +0 -37
  19. data/lib/js2/parser/tokenizer.rb +0 -3551
  20. data/lib/js2/ragel/helper.rb +0 -117
  21. data/lib/js2/ragel/tokenizer.rl +0 -561
  22. data/lib/js2/ragel/tokenizer.rl.erb +0 -347
  23. data/lib/js2/standard/class_node.rb +0 -0
  24. data/lib/js2/standard/factory.rb +0 -289
  25. data/lib/js2/standard/node.rb +0 -75
  26. data/lib/js2/util/compilation.rb +0 -77
  27. data/lib/js2/util/config.rb +0 -84
  28. data/lib/js2/util/exec.rb +0 -34
  29. data/lib/js2/util/file_handler.rb +0 -73
  30. data/lib/js2/util/haml_filter.rb +0 -13
  31. data/lib/js2/util/jamis.rb +0 -600
  32. data/lib/js2/util/js2bootstrap.js2 +0 -448
  33. data/lib/js2/util/processor.rb +0 -88
  34. data/lib/js2/util/rdoc.rb +0 -37
  35. data/lib/js2/util/sel_decorator.rb +0 -155
  36. data/test/compiled/bar.js +0 -3
  37. data/test/compiled/basic.comp.js +0 -31
  38. data/test/compiled/basic.js +0 -27
  39. data/test/compiled/foo.js +0 -3
  40. data/test/fixtures/bar.js2 +0 -3
  41. data/test/fixtures/basic.js2 +0 -27
  42. data/test/fixtures/basic.js2.haml +0 -4
  43. data/test/fixtures/basic.js2.yml +0 -5
  44. data/test/fixtures/curry.js2 +0 -5
  45. data/test/fixtures/foo.js2 +0 -3
  46. data/test/fixtures/member.js2 +0 -14
  47. data/test/fixtures/private.js2 +0 -5
  48. data/test/fixtures/property.js2 +0 -4
  49. data/test/test_helper.rb +0 -25
  50. data/test/test_js2.rb +0 -43
  51. data/wiki/features.md +0 -73
  52. data/wiki/installation.md +0 -13
@@ -1,448 +0,0 @@
1
- (function (scope) {
2
- if (scope.JS2) return;
3
-
4
- var JS2 = {};
5
- scope.JS2 = JS2;
6
-
7
- function noInit () { };
8
-
9
- var ooUtils = {
10
- 'extends': function (par) {
11
- this.parent = par;
12
- var newProto = par.oo('instance');
13
- var proto = this.prototype;
14
-
15
- var members = this.oo.members;
16
- for (var k in proto) {
17
- if (proto.hasOwnProperty(k)) newProto[k] = proto[k];
18
- }
19
-
20
- this.prototype = newProto;
21
- this.prototype['class'] = this;
22
- },
23
-
24
- 'instance': function () {
25
- var proto = this.prototype;
26
-
27
- var init = null;
28
- if (this.oo.members.initialize) {
29
- init = proto.initialize;
30
- }
31
-
32
- this.prototype.initialize = noInit;
33
- var ret = new this();
34
-
35
- if (init) {
36
- this.prototype.initialize = init;
37
- ret.initialize = init;
38
- } else {
39
- delete this.prototype['initialize'];
40
- }
41
-
42
- return ret;
43
- },
44
-
45
- 'include': function (mod) {
46
- var hash = mod.prototype;
47
- var members = this.oo.members;
48
- var modMembers = mod.oo.members;
49
-
50
- for (var k in modMembers) {
51
- if (!(k in members)) {
52
- this.prototype[k] = hash[k];
53
- }
54
- }
55
- },
56
-
57
- 'member': function (name, member) {
58
- this.oo.members[name] = true;
59
- this.prototype[name] = member;
60
- },
61
-
62
- 'method': function (name, method) {
63
- this.oo.members[name] = true;
64
- this.prototype[name] = method;
65
- method._name = name;
66
- method._class = this;
67
- },
68
-
69
- 'modularize': function () {
70
- this.isModule = true;
71
- },
72
-
73
- 'staticMember': function (name, member) {
74
- this[name] = member;
75
- },
76
-
77
- 'setHTMLAssets': function (hash) {
78
- // create temp class
79
- var tempClass = function () {};
80
-
81
- // look for super htmlAssets
82
- var par = this.parent;
83
- if (par) {
84
- var parCache = par.prototype.htmlAssets;
85
- if (parCache) tempClass.prototype = parCache;
86
- }
87
-
88
- var htmlAssets = new tempClass();
89
- for (var k in hash) htmlAssets[k] = hash[k];
90
- this.oo('member', 'htmlCache', htmlAssets);
91
- this.oo('member', 'htmlAssets', htmlAssets);
92
- },
93
-
94
- 'super': function (member) {
95
- return this.parent.prototype[member];
96
- },
97
-
98
- 'property': function (names) {
99
- for (var i=0; i<names.length; i++) {
100
- var name = names[i];
101
- var getter = 'get' + name.charAt(0).toUpperCase() + name.substr(1);
102
- var setter = 'set' + name.charAt(0).toUpperCase() + name.substr(1);
103
-
104
- var members = this.oo.members;
105
- if (! (getter in members))
106
- this.oo('method', getter, (function (n) { return function () { return this[n] }})(name));
107
- if (! (setter in members))
108
- this.oo('method', setter, (function (n) { return function (val) { return this[n] = val }})(name));
109
- }
110
- },
111
-
112
- 'accessor': function (names) {
113
- for (var i=0; i<names.length; i++) {
114
- var name = names[i];
115
- if (! (name in this.oo.members))
116
- this.oo('method', name,
117
- function () {
118
- if (arguments.length) { return this['_' + name] = arguments[0]; }
119
- else { return this['_' + name]; }
120
- });
121
- }
122
- },
123
-
124
- 'ancestors': function (names) {
125
- var ret = [];
126
- var k = this.parent;
127
- while (k) {
128
- ret.push(k);
129
- k = k.parent;
130
- }
131
- return ret;
132
- }
133
- };
134
-
135
-
136
- function createClass (name, par) {
137
- var K = function () { if (this.initialize) this.initialize.apply(this, arguments); };
138
-
139
- K.prototype['class'] = K;
140
- K.prototype['klass'] = K;
141
-
142
- K.oo = function (method, param1, param2) {
143
- return ooUtils[method].apply(K, [ param1, param2 ]);
144
- };
145
-
146
- K.oo.includes = [];
147
- K.oo.members = {};
148
-
149
- return K;
150
- }
151
-
152
- function createNamespace (space, currentScope) {
153
- var currentScope = currentScope || scope;
154
-
155
- var splitted = space.split('.');
156
- var name = [];
157
- while (splitted.length) {
158
- var part = splitted.shift();
159
- name.push(part);
160
-
161
- if (! currentScope[part]) {
162
- var K = createClass();
163
- K.package = currentScope;
164
- currentScope[part] = K;
165
- }
166
-
167
- currentScope = currentScope[part];
168
- currentScope.className = name.join('.');
169
- }
170
-
171
- return currentScope;
172
- }
173
-
174
- JS2.OO = {};
175
- JS2.OO.createClass = createNamespace;
176
- JS2.OO.createModule = function (name) { createNamespace(name).oo('modularize') };
177
- JS2.OO.get = function (name, scope) {
178
- scope = scope || window;
179
- var cur = scope;
180
- var names = name.split(/\./);
181
- while (names.length) cur = cur[names.shift()];
182
- return cur;
183
- };
184
-
185
- JS2.OO['super'] = function () {
186
- var method = arguments.callee.caller;
187
- var name = method._name;
188
- var klass = method._class;
189
- var self = arguments[0];
190
-
191
- var method = klass.parent.prototype[name];
192
- if (! method) return;
193
-
194
- var args = [];
195
- for (var i=1,len=arguments.length;i<len;i++) {
196
- args.push(arguments[i]);
197
- }
198
- return method.apply(self, args);
199
- }
200
-
201
- })(window);
202
-
203
-
204
- class JS2.App.Notifier {
205
- var autoInc = 1;
206
-
207
- function initialize () {
208
- this.chains = {};
209
- this.autoInc = 1;
210
- this.id = this['class'].prototype.autoInc;
211
- this['class'].prototype.autoInc++;
212
- }
213
-
214
- function register (comp) {
215
- if (! comp.__notifier_ids) {
216
- comp.__notifier_ids = {};
217
- }
218
-
219
- if (! comp.__notifier_ids[this.id]) {
220
- comp.__notifier_ids[this.id] = this.autoInc;
221
- this.autoInc++;
222
- }
223
-
224
- for (var key in comp) {
225
- if (key.indexOf('e_') == 0) {
226
- var eventType = key.substr(2);
227
- if (! this.chains[eventType]) this.chains[eventType] = [];
228
- this.chains[eventType].push([ comp, comp[key] ]);
229
- }
230
- }
231
-
232
- comp.notify = curry with (this) {
233
- self.notify.apply(self, arguments);
234
- };
235
- }
236
-
237
- function remove (comp) {
238
- var id = comp.__notifier_id;
239
- for (var key in this.chains) {
240
- var newChain = [];
241
- foreach (var ele:j in chain) {
242
- if (ele[0].__notifier_id[this.id] != id) {
243
- newChain.push(ele);
244
- }
245
- }
246
-
247
- this.chains[key] = newChain;
248
- }
249
- }
250
-
251
- function registerListener (listener) {
252
- for (var key in listener) {
253
- var funct = listener[key];
254
- if (typeof funct != 'function') continue;
255
- if (! this.chains[key]) this.chains[key] = [];
256
- this.chains[key].push([ listener, funct ]);
257
- }
258
- }
259
-
260
- function notify () {
261
- var eventType = arguments[0];
262
- var args;
263
-
264
- // optimize for 1 argument
265
- if (arguments.length == 2) {
266
- args = [ arguments[1] ];
267
- } else {
268
- args = [];
269
- for (var i=1; i<=arguments.length; i++) args.push(arguments[i]);
270
- }
271
-
272
- var chain = this.chains[eventType];
273
- if (chain) {
274
- for (var i=0,pair; pair=chain[i++];) {
275
- pair[1].apply(pair[0], args);
276
- }
277
- }
278
- }
279
- }
280
-
281
-
282
-
283
- class JS2.App {
284
-
285
- function start (options) {
286
- // hack to get notifier
287
- this.getNotifier();
288
-
289
- this.build();
290
- this.notify('setOptions', options || {});
291
- this.notify('initHTML');
292
- this.notify('registerEvents');
293
- this.notify('finalize');
294
- }
295
-
296
-
297
- function register (comp) {
298
- this.getNotifier().register(comp);
299
- }
300
-
301
- function getNotifier () {
302
- if (! this._notifier) {
303
- this._notifier = new JS2.App.Notifier();
304
- this._notifier.register(this);
305
- }
306
-
307
- return this._notifier;
308
- }
309
-
310
- function build () {
311
- var components = { main: this };
312
-
313
- var classes = [];
314
- var klass = this['class'];
315
-
316
- while (klass) {
317
- classes.unshift(klass);
318
- klass = klass.parent;
319
- }
320
-
321
- var template = [];
322
- var already = {};
323
- var runningIdx = 0;
324
-
325
- foreach (var c:i in classes) {
326
- var toAdd = c.prototype.getTemplate();
327
- foreach (var t:j in toAdd) {
328
- if (already[t.name] != undefined) {
329
- template[already[t.name]] = t;
330
- } else {
331
- already[t.name] = runningIdx;
332
- runningIdx += 1;
333
- template.push(t);
334
- }
335
- }
336
- }
337
-
338
- // instantiate all components
339
- components['main'] = this;
340
- foreach (var config:i in template) {
341
- if (!config['class']) alert("Invalid class defined for " + name + ':' + config['class']);
342
- var klass = JS2.OO.get(config['class']);
343
-
344
- if (klass) {
345
- components[config.name] = new klass();
346
- } else if (console) {
347
- console.log('class "' + config.name + '" was not found."');
348
- }
349
- this.register(components[config.name]);
350
- }
351
-
352
- foreach (var config:i in template) {
353
- var name = config.name;
354
- var comp = components[name];
355
-
356
- // inject set dependencies as an array
357
- if (config.dependencies instanceof Array) {
358
- foreach (var dep:j in config.dependencies) {
359
- comp[dep] = components[dep];
360
- }
361
- }
362
-
363
- // as a hash... for use when nickname is not the dependency name
364
- else if (config.dependencies instanceof Object) {
365
- for (var key in config.dependencies) {
366
- comp[key] = components[config.dependencies[key]];
367
- }
368
- }
369
- }
370
-
371
- this.notify('initBaseHTML');
372
-
373
- // handle selectors as root elements
374
- foreach (var config:i in template) {
375
- var name = config.name;
376
- var comp = components[name];
377
-
378
- if (config.selector) comp.$root = this.htmlSelect(this.$root, config.selector);
379
- if (config.globalSelector) comp.$root = this.htmlSelect(config.globalSelector);
380
- }
381
- }
382
-
383
- function htmlSelect (root, text) {
384
- alert('html selector not implemented');
385
- }
386
-
387
- function getTemplate () {
388
- return [];
389
- }
390
- }
391
-
392
- class JS2.App.JQuery extends JS2.App {
393
- function htmlSelect ($root, text) {
394
- if (text) {
395
- return $root.find(text);
396
- } else {
397
- return $(root);
398
- }
399
- }
400
- }
401
-
402
- module JS2.Observable {
403
- function addListener (namespace, funct) {
404
- this._initializeObservable(namespace);
405
-
406
- var id = this._listenerCount++;
407
- var chain = this._listeners[namespace];
408
- var index = chain.length;
409
- var info = [ funct, id, namespace ];
410
-
411
- this._listenerLookup[id.toString()] = info;
412
- chain.push(info);
413
- }
414
-
415
- function trigger () {
416
- if (! this._listeners) return;
417
-
418
- var namespace = arguments[0];
419
- var chain = this._listeners[namespace];
420
- if (! chain) return;
421
-
422
- var args = [];
423
- for (var i=1; i<arguments.length; i++) {
424
- args.push(arguments[i]);
425
- }
426
-
427
- if (chain) {
428
- foreach (var ele in chain) {
429
- ele[0].apply(this, args);
430
- }
431
- }
432
- }
433
-
434
- private
435
-
436
- function _initializeObservable (namespace) {
437
- if (! this._listeners) {
438
- this._listeners = {};
439
- this._listenerLookup = {};
440
- this._listenerCount = 1;
441
- }
442
-
443
- if (! this._listeners[namespace]) {
444
- this._listeners[namespace] = [];
445
- }
446
- }
447
- }
448
-
@@ -1,88 +0,0 @@
1
- class JS2::Util::Processor
2
- attr_accessor :errors
3
-
4
- def initialize (config)
5
- @file_handler = config.file_handler
6
- @lexer = config.lexer
7
- @factory = config.node_factory
8
- @haml_engine = config.haml_engine
9
- @haml_parser = JS2::Parser::Haml.new(config.haml_engine, config.haml_vars)
10
-
11
- @lookup = Hash.new
12
-
13
- @config = config
14
- end
15
-
16
- def process!
17
- @errors = []
18
-
19
- ret = { :processed => [], :changed => [], :errors => @errors, :klasses => [], :pages => [] }
20
- ret[:changed] = @file_handler.needs_update
21
- return ret unless ret[:changed].any?
22
-
23
- pages = ret[:pages]
24
- klasses = Hash.new
25
-
26
- @file_handler.get_files(:js2).each do |file|
27
- begin
28
- page = @lexer.parse_file(file, @factory)
29
- page.klasses.each do |k|
30
- (klasses[k.name] ||= []) << page.file
31
- end
32
-
33
- ret[:klasses] += page.klasses
34
-
35
- pages << page
36
-
37
- outfile = @file_handler.outfile(page.file)
38
- outdir = File.dirname(outfile)
39
-
40
- FileUtils.mkdir_p(outdir)
41
- File.open(@file_handler.outfile(page.file), 'w') { |f| f << page.to_s() }
42
- rescue Exception => e
43
- @errors << [ "Can't compile #{file}", e ]
44
- end
45
- end
46
-
47
- js2_file = File.dirname(__FILE__) + '/js2bootstrap.js2'
48
- js2_page = @lexer.parse_file(js2_file, @factory)
49
- out_file = @file_handler.out_dir + '/js2bootstrap.js'
50
- FileUtils.mkdir_p(@file_handler.out_dir)
51
- File.open(out_file, 'w') { |f| f << js2_page.to_s() }
52
-
53
- @file_handler.get_files(:haml).each do |file|
54
- begin
55
- result = @haml_parser.parse(file)
56
- result.keys.each do |klass_name|
57
- hash = result[klass_name]
58
-
59
- out = []
60
- hash.keys.sort.each do |key|
61
- out << %{"#{key}":#{hash[key]}}
62
- end
63
-
64
- if files = klasses[klass_name]
65
- outfile = @file_handler.outfile(files.first)
66
- File.open(outfile, 'a') { |f| f << "#{klass_name}.oo('setHTMLAssets', {#{out.join(',')}});" }
67
- end
68
- end
69
- rescue Exception => e
70
- @errors << [ "Can't compile #{file}", e ]
71
- end
72
- end
73
-
74
- @file_handler.get_files(:yml).each do |file|
75
- begin
76
- comps = JS2::Util::Compilation.parse(file, @file_handler)
77
- comps.each do |c|
78
- c.compile(klasses, errors)
79
- end
80
- rescue Exception => e
81
- @errors << [ "Can't compile #{file}", e ]
82
- end
83
- end
84
-
85
- return ret
86
- end
87
-
88
- end
data/lib/js2/util/rdoc.rb DELETED
@@ -1,37 +0,0 @@
1
- class JS2::Util::Rdoc
2
-
3
- def self.build (pages, file_handler, rdoc_bin = 'rdoc')
4
- file_handler.doc_dir = "./.#{Time.now.to_i.to_s}-doc-code"
5
-
6
- pages.each do |p|
7
- str = ''
8
- p.klasses.each do |k|
9
- if k.comment
10
- str << k.comment.clean.gsub(/^/, "# ") if k.comment
11
- end
12
- str << "class #{k.name.gsub(/\./, '::')}\n"
13
- puts k.name
14
-
15
- k.methods.each_with_index do |m,i|
16
- puts ' - ' + m.name
17
- str << m.comment.clean.gsub(/^/, " # ") if m.comment
18
- str << " def #{m.name} (#{m.args})\n#{m.to_s.gsub(/^/, ' #')} end\n"
19
- end
20
-
21
- str << "end\n"
22
- end
23
-
24
- outfile = file_handler.docfile(p.file)
25
- outdir = File.dirname(outfile)
26
- FileUtils.mkdir_p(outdir)
27
- File.open(outfile, 'w') { |f| f << str }
28
- end
29
-
30
- # TODO make this portable
31
- jamis = File.dirname(__FILE__) + '/jamis.rb'
32
- puts `#{rdoc_bin} --template #{jamis} --extension js=rb #{file_handler.doc_dir}`
33
- puts `rm -rf #{file_handler.doc_dir}`
34
- end
35
-
36
-
37
- end
@@ -1,155 +0,0 @@
1
- require 'json'
2
-
3
- class JS2::Util::SelDecorator
4
-
5
- def initialize ()
6
- @references = Hash.new
7
- @in_class = false
8
- end
9
-
10
- def reset!
11
- @references = Hash.new
12
- @in_class = false
13
- end
14
-
15
- def decorate (str, node)
16
- if node.is_a?(JS2::Standard::ClassNode)
17
- return translate(str, nil, true)
18
- elsif node.is_a?(JS2::Standard::StuffNode)
19
- return translate(str, nil, false)
20
- else
21
- return str
22
- end
23
- end
24
-
25
- def translate (str, scope = nil, in_class = false)
26
- @scope = scope
27
- @in_class = in_class
28
- ret = process_str(str)
29
- @in_class = false
30
- @scope = nil
31
- return ret
32
- end
33
-
34
- def write_references (dir)
35
- @references.each_pair do |klass, val|
36
- File.open(dir + '/' + klass + '.yml', 'w') do |out|
37
- YAML.dump(val, out)
38
- end
39
- end
40
- end
41
-
42
- private
43
-
44
- def process_str (str)
45
- lines = str.split(/\r?\n/)
46
- processed = []
47
-
48
- lines.each do |line|
49
- # release comment and put it back in the queue
50
- line.sub!(%r|\s*//@=\s*.*|) do |str|
51
- if m = str.match(%r|(\s*)//@=\s*(.*)|)
52
- m[1] + m[2]
53
- else
54
- str
55
- end
56
- end
57
- end
58
-
59
- while line = lines.shift
60
-
61
- # scope is defined
62
- if m = line.match(%r|^\s*//@\s*Scope\(([\w\.]+)\)|)
63
- @scope = "Page.#{m[1]}"
64
- processed.push(line)
65
-
66
- elsif @scope
67
- # if its a marker, reverse the next 2 lines
68
- if new_line = process_marker(line, lines.first)
69
- processed.push(lines.shift)
70
- processed.push(new_line)
71
-
72
- # var button = $('.button'); //@ Button
73
- elsif new_lines = process_tailing_marker(line)
74
-
75
- # reorder this and send it back through the loop
76
- # but with the marker on top
77
- lines.unshift(new_lines[1])
78
- lines.unshift(new_lines[0])
79
- next
80
-
81
- # proceed as normal
82
- else
83
- processed.push(line)
84
- end
85
- else
86
- processed.push(line)
87
- end
88
- end
89
-
90
- return processed.join("\n")
91
- end
92
-
93
- def process_marker (line, next_line)
94
- return false unless @scope && next_line
95
-
96
- # //@ Foo // Bar
97
- # //@+ Foo // Bar
98
- # pad type marker comment
99
- if m = line.match(%r|^(\s*)//@(\+)?\s+([^/]+)\s*(//(.*))?$|)
100
-
101
- padding = m[1]
102
- type = m[2]
103
- marker = m[3].strip
104
-
105
- whole_comment = m[4]
106
- comment = (m[5] || '').strip
107
-
108
- # get lval
109
- lval_match = next_line.match(/^\s*(var)?\s*([^\s=;]+)\s*/)
110
-
111
- return false unless lval_match
112
- lval = lval_match[2]
113
-
114
- # figure out what the lval should be
115
- # Button(<jquery selector>)
116
- key, find = parse_marker(marker)
117
- finder = find ? find.to_json : "null"
118
-
119
- # method to use for JS2.TEST.<addEle>(...)
120
- insert = type == "+" ? 'appendVal' : 'addVal'
121
-
122
- (@references[@scope] ||= {})[key] = comment
123
- scope =
124
- if @in_class
125
- "TMP_SEL_MARKER.getRealClassScope(this)"
126
- else
127
- @scope.to_json
128
- end
129
-
130
- return padding + %{var TMP_SEL_MARKER = this.SEL_MARKER || JS2.SEL_MARKER; TMP_SEL_MARKER.#{insert}(#{scope}, #{key.to_json}, #{lval}, #{finder});}
131
- else
132
- return false
133
- end
134
- end
135
-
136
- # split a trailing marker into 2 lines
137
- def process_tailing_marker (line)
138
- if m = line.match(%r|^(\s*)([^\s]+.*)(//@.*)$|)
139
- new_line = m[1] + m[2]
140
- marker = m[1] + m[3]
141
- return [ marker, new_line ]
142
- else
143
- return false
144
- end
145
- end
146
-
147
- def parse_marker (marker)
148
- # key find
149
- if m = marker.match(/^([^\(]+)\(([^\)]*)\)?/)
150
- return [ m[1], m[2] ]
151
- else
152
- return [ marker, nil ]
153
- end
154
- end
155
- end