js2 0.3.5 → 0.3.6

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/CHANGELOG CHANGED
@@ -1,3 +1,8 @@
1
+ 0.3.6
2
+ * Verbosity mode
3
+ * Fixed ruby file "watch" mode
4
+ * Cleaned up rack hooks
5
+
1
6
  0.3.5
2
7
  * Added scope and binding support to shorthand functions
3
8
  * Added support for modules
@@ -0,0 +1,278 @@
1
+ (function (root) {
2
+ // temporarily set root
3
+ // to JS2 global var for this scope
4
+ function mainFunction (arg) {
5
+ if (typeof arg == 'string') {
6
+ return JS2.Parser.parse(arg).toString();
7
+ } else if (arg instanceof Array) {
8
+ return new JS2.Array(arg);
9
+ } else {
10
+ return new JS2.Array();
11
+ }
12
+ }
13
+
14
+
15
+ if (!root.console) {
16
+ root.console = {};
17
+ console.log = function (m) {};
18
+ }
19
+
20
+ var JS2 = root.JS2 = mainFunction;
21
+ var js2 = root.js2 = JS2;
22
+ js2.VERSION = "0.3.6";
23
+
24
+ JS2.ROOT = JS2;
25
+
26
+
27
+ // CLASS HELPERS
28
+ (function (undefined, JS2) {
29
+
30
+ var OO = function (klass, par) {
31
+ this.klass = klass;
32
+ this.par = par;
33
+
34
+ this.members = {};
35
+ this.staticMembers = {};
36
+ this.children = [];
37
+ this.included = [];
38
+
39
+ if (this.par) this.par.OO.children.push(klass);
40
+ };
41
+
42
+ OO.prototype = {
43
+ forbiddenMembers: {
44
+ 'prototype': undefined,
45
+ 'OO': undefined
46
+ },
47
+
48
+ include: function(module) {
49
+ this.included.push(module);
50
+ var members = module.OO.members;
51
+ for (var name in members) {
52
+ if (members.hasOwnProperty(name)) {
53
+ this.addMember(name, members[name]);
54
+ }
55
+ }
56
+
57
+ var staticMembers = module.OO.staticMembers;
58
+ for (var name in staticMembers) {
59
+ if (staticMembers.hasOwnProperty(name)) {
60
+ this.addStaticMember(name, staticMembers[name]);
61
+ }
62
+ }
63
+
64
+ if (typeof staticMembers['included'] == 'function') {
65
+ staticMembers['included'](this.klass);
66
+ }
67
+ },
68
+
69
+ createNamespace: function(name) {
70
+ var splitted = name.split('.');
71
+ var klassName = splitted.pop();
72
+ var root = JS2.ROOT;
73
+
74
+ while (splitted.length > 0) {
75
+ var name = splitted.shift();
76
+ if (!root[name]) root[name] = JS2.Class.extend({});
77
+ root = root[name];
78
+ }
79
+
80
+ return [ root, klassName ];
81
+ },
82
+
83
+ makeSuper: function(newMethod, oldMethod) {
84
+ if (!oldMethod) return newMethod;
85
+
86
+ return function() {
87
+ this.$super = oldMethod;
88
+ return newMethod.apply(this, arguments);
89
+ };
90
+ },
91
+
92
+ addMember: function(name, member) {
93
+ if (this.forbiddenMembers.hasOwnProperty(name)) return;
94
+
95
+ var proto = this.klass.prototype;
96
+ if (typeof proto[name] == 'function' && !(proto[name] instanceof RegExp)) {
97
+ member = this.makeSuper(member, proto[name]);
98
+ }
99
+
100
+ proto[name] = member;
101
+ this.members[name] = member;
102
+ },
103
+
104
+ addStaticMember: function(name, member) {
105
+ if (this.forbiddenMembers.hasOwnProperty(name)) return;
106
+
107
+ if (typeof this.klass[name] == 'function') {
108
+ if (!this.klass.hasOwnProperty(name)) {
109
+ member = this.makeSuper(member, this.klass[name]);
110
+ }
111
+ }
112
+
113
+ this.klass[name] = member;
114
+ this.staticMembers[name] = member;
115
+ }
116
+ };
117
+
118
+ JS2.Class = function() { this.initialize.apply(this, arguments); };
119
+ JS2.Class.OO = new OO(JS2.Class);
120
+ JS2.Class.prototype = {
121
+ initialize: function () {},
122
+ oo: JS2.Class.OO
123
+ };
124
+
125
+ var namedClasses = {};
126
+ JS2.getClass = function(name) {
127
+ return namedClasses[name];
128
+ };
129
+
130
+ var noInit = false;
131
+ JS2.Class.extend = function(name, klassDef) {
132
+ var klass = function() { if (!noInit) this.initialize.apply(this, arguments); };
133
+ klass.OO = new OO(klass, this);
134
+
135
+ if (typeof name != 'string') {
136
+ klassDef = name;
137
+ } else {
138
+ namedClasses[name] = klass;
139
+ var namespace = this.OO.createNamespace(name);
140
+ namespace[0][namespace[1]] = klass;
141
+ }
142
+
143
+ // create instance of this as prototype for new this
144
+ noInit = true;
145
+ var proto = new this();
146
+ noInit = false;
147
+
148
+ klass.prototype = proto;
149
+ var oo = klass.OO;
150
+ proto.OO = oo;
151
+
152
+ for (var name in this) {
153
+ oo.addStaticMember(name, this[name]);
154
+ }
155
+
156
+ if (typeof klassDef == 'function') {
157
+ klassDef(klass, oo);
158
+ } else {
159
+ for (var name in klassDef) {
160
+ oo.addMember(name, klassDef[name]);
161
+ }
162
+ }
163
+
164
+ return klass;
165
+ };
166
+
167
+ JS2.Module = JS2.Class;
168
+
169
+ var assert = {
170
+ 'eq': function(expected, actual) { if (expected != actual) console.log("Expected "+expected+", but got "+actual+".") },
171
+ 'isFalse': function(val) { if (val) console.log("Expected false, but got "+val+".") },
172
+ 'isTrue': function(val) { if (!val) console.log("Expected true, but got " +val+".") }
173
+ };
174
+
175
+ JS2.test = function(message, callback) {
176
+ if (!callback) callback = message;
177
+ callback(assert);
178
+ };
179
+
180
+
181
+ return JS2;
182
+ })(undefined, JS2);
183
+
184
+ JS2.Array = function (arr) {
185
+ if (arr instanceof Array) {
186
+ this.append(arr);
187
+ }
188
+ };
189
+
190
+ JS2.Array.prototype = new Array();
191
+ JS2.Array.prototype.each = function(f) {
192
+ for (var i=0; i<this.length; i++) {
193
+ f.call(this, this[i], i );
194
+ }
195
+ return this;
196
+ };
197
+
198
+ JS2.Array.prototype.toString = function() {
199
+ return this.join(',');
200
+ };
201
+
202
+
203
+ JS2.Array.prototype.until = function(f) {
204
+ for (var i=0; i<this.length; i++) {
205
+ if (f.call(this, this[i], i )) return true;;
206
+ }
207
+ return false;
208
+ };
209
+
210
+
211
+ JS2.Array.prototype.collect = function(f) {
212
+ var ret = new JS2.Array();
213
+ var self = this;
214
+ this.each(function($1,$2,$3){ ret.push(f.call(self, $1, $2)) });
215
+ return ret;
216
+ };
217
+
218
+ // http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/reduce
219
+ JS2.Array.prototype.reduce = function(f, val) {
220
+ if (this.length == 0) return val;
221
+ if (this.length == 1) return val == null ? f(this[0]) : f(val, this[0]);
222
+
223
+ var i = 0;
224
+ if (val == null) val = this[i++];
225
+
226
+ for (var n=this.length;i<n;i++) {
227
+ val = f(val, this[i]);
228
+ }
229
+
230
+ return val;
231
+ };
232
+
233
+ JS2.Array.prototype.reject = function(f) {
234
+ var ret = new JS2.Array();
235
+ if (f instanceof RegExp) {
236
+ this.each(function($1,$2,$3){ if (!$1.match(f)) ret.push($1) });
237
+ } else if (typeof f == 'string' || typeof f == 'number') {
238
+ this.each(function($1,$2,$3){ if ($1 != f) ret.push($1) });
239
+ } else if (typeof f == 'function') {
240
+ var self = this;
241
+ this.each(function($1,$2,$3){ if (!f.call(self, $1, $2)) ret.push($1) });
242
+ }
243
+ return ret;
244
+ };
245
+
246
+ JS2.Array.prototype.select = function(f) {
247
+ var ret = new JS2.Array();
248
+ if (f instanceof RegExp) {
249
+ this.each(function($1,$2,$3){ if ($1.match(f)) ret.push($1) });
250
+ } else if (typeof f == 'string' || typeof f == 'number') {
251
+ this.each(function($1,$2,$3){ if ($1 == f) ret.push($1) });
252
+ } else if (typeof f == 'function') {
253
+ var self = this;
254
+ this.each(function($1,$2,$3){ if (f.call(self, $1, $2)) ret.push($1) });
255
+ }
256
+ return ret;
257
+ };
258
+
259
+ JS2.Array.prototype.append = function(arr) {
260
+ this.push.apply(this, arr);
261
+ return this;
262
+ };
263
+
264
+ JS2.Array.prototype.empty = function() {
265
+ return this.length == 0;
266
+ };
267
+
268
+ JS2.Array.prototype.any = function() {
269
+ return this.length > 0;
270
+ };
271
+
272
+
273
+
274
+ js2.ROOT = root;
275
+
276
+ return JS2;
277
+
278
+ })(window);
data/lib/js2/fs.rb CHANGED
@@ -47,7 +47,7 @@ class JS2::FS
47
47
 
48
48
  def setInterval(code, time)
49
49
  while true
50
- @ctx.eval(code)
50
+ code.call()
51
51
  sleep(time/1000)
52
52
  end
53
53
  end
data/lib/js2/js2.js CHANGED
@@ -14,7 +14,7 @@ function mainFunction (arg) {
14
14
 
15
15
  var JS2 = root.JS2 = mainFunction;
16
16
  var js2 = root.js2 = JS2;
17
- js2.VERSION = "0.3.5";
17
+ js2.VERSION = "0.3.6";
18
18
 
19
19
  JS2.ROOT = JS2;
20
20
 
@@ -1233,6 +1233,7 @@ JS2.Class.extend('Updater', function(KLASS, OO){
1233
1233
  if (! this.fs.isDirectory(dir)) this.fs.mkpath(dir);
1234
1234
 
1235
1235
  if (force || this.fs.mtime(file) > this.fs.mtime(outFile)) {
1236
+ JS2.LOGGER.info(file + ' -> ' + outFile);
1236
1237
  if (funct) {
1237
1238
  this.fs.write(outFile, funct(JS2(this.fs.read(file))));
1238
1239
  } else {
@@ -1244,11 +1245,13 @@ JS2.Class.extend('Updater', function(KLASS, OO){
1244
1245
 
1245
1246
 
1246
1247
  JS2.Class.extend('Config', function(KLASS, OO){
1247
- OO.addMember("CLI_REGEX",/^-(r|i|f)(=(\w+))$/);
1248
+ OO.addMember("CLI_REGEX",/^-(r|i|f|n|v|m)(=(\w+))?$/);
1248
1249
  OO.addMember("optsLookup",{
1249
1250
  'n': 'non-recursive',
1250
1251
  'i': 'interval',
1251
- 'f': 'format'
1252
+ 'f': 'format',
1253
+ 'v': 'verbose',
1254
+ 'm': 'use_mtime'
1252
1255
  });
1253
1256
 
1254
1257
  OO.addMember("initialize",function (fs, argv) {
@@ -1292,8 +1295,10 @@ JS2.Class.extend('Config', function(KLASS, OO){
1292
1295
  this.interval = config['interval'] ? config['interval'] : this.interval;
1293
1296
  this.sourceDir = config['source-dir'] || this.sourceDir;
1294
1297
  this.outDir = config['out-dir'] || this.outDir;
1298
+ this.verbose = ('verbose' in config) ? config['verbose'] : false;
1295
1299
 
1296
1300
  this['non-recursive'] = config['non-recursive'];
1301
+ this['use-mtime'] = config['use-mtime'];
1297
1302
 
1298
1303
  return true;
1299
1304
  } catch(e) {
@@ -1308,31 +1313,32 @@ JS2.Class.extend('Config', function(KLASS, OO){
1308
1313
 
1309
1314
  JS2.Class.extend('Commander', function(KLASS, OO){
1310
1315
  OO.addMember("BANNER","js2 <command> [options] <arguments>\n" +
1311
- "VERSION: " + js2.VERSION + "\n" +
1316
+ "VERSION: " + JS2.VERSION + "\n" +
1312
1317
  "Commands:\n" +
1313
1318
  " * run <file> -- Executes file\n" +
1314
1319
  " * render <file> -- Shows JS2 compiled output\n" +
1315
1320
  " * compile <inDir> [outDir] -- Compiles a directory and puts js files into outDir. If outDir is not specified, inDir will be used\n" +
1316
1321
  " Options:\n" +
1317
1322
  " -n -- Do NOT traverse directories recursively\n" +
1323
+ " -v -- Verbose \n" +
1318
1324
  " -f=<format> -- Compile for different formats: node, ringo, or browser\n" +
1319
1325
  " * compile <file> -- Compiles a single js2 file into js\n" +
1320
1326
  " * watch <inDir> <outDir> -- Similar to compile, but update will keep looping while watching for modifications\n" +
1321
1327
  " Options:\n" +
1322
1328
  " -n -- Do NOT traverse directories recursively\n" +
1323
1329
  " -f=<format> -- Compile for different formats: node, ringo, or browser\n" +
1330
+ " -v -- Verbose \n" +
1324
1331
  " -i=<seconds> -- Interval time in seconds between loops\n");
1325
1332
 
1326
- OO.addMember("DEFAULT_CONFIG",{
1327
- compile: { inDir: 'src', outDir: 'lib', recursive: true, decorator: 'Node' },
1328
- watch: { inDir: 'src', outDir: 'lib', recursive: true, decorator: 'Node' }
1329
- });
1330
-
1331
1333
  OO.addMember("initialize",function (argv) {
1332
1334
  this.fs = JS2.fs;
1333
1335
  this.config = new JS2.Config(this.fs, argv);
1334
1336
  this.command = this.config.command;
1335
1337
 
1338
+ // HACK for now
1339
+ JS2.VERBOSE = this.config.verbose || false;
1340
+ JS2.LOGGER = { info: function($1,$2,$3){ if (JS2.VERBOSE) console.log($1) } };
1341
+
1336
1342
  switch(this.config.format) {
1337
1343
  case 'ringo': JS2.DECORATOR = new JS2.RingoDecorator(); break;
1338
1344
  case 'node': JS2.DECORATOR = new JS2.NodeDecorator(); break;
@@ -1349,7 +1355,7 @@ JS2.Class.extend('Commander', function(KLASS, OO){
1349
1355
  });
1350
1356
 
1351
1357
  OO.addMember("render",function () {
1352
- console.log(js2.render(this.fs.read(this.config.args[0])));
1358
+ JS2.LOGGER.info(js2.render(this.fs.read(this.config.args[0])));
1353
1359
  });
1354
1360
 
1355
1361
  OO.addMember("run",function () {
@@ -1362,7 +1368,8 @@ JS2.Class.extend('Commander', function(KLASS, OO){
1362
1368
 
1363
1369
  OO.addMember("compile",function () {
1364
1370
  var self = this;
1365
- this.getUpdater().update(true, function($1,$2,$3){ return JS2.DECORATOR.file($1); });
1371
+ var force = this.config['use-mtime'] ? false : true;
1372
+ this.getUpdater().update(force, function($1,$2,$3){ return JS2.DECORATOR.file($1); });
1366
1373
  });
1367
1374
 
1368
1375
  OO.addMember("getUpdater",function () {
@@ -1375,12 +1382,13 @@ JS2.Class.extend('Commander', function(KLASS, OO){
1375
1382
  var updater = this.getUpdater();
1376
1383
  var self = this;
1377
1384
  var interval = this.config.interval || 2;
1378
- console.log('Input Directory:' + updater.inDir + ' -> Output Directory:' + updater.outDir);
1379
- if (updater.recursive) console.log('RECURSIVE');
1385
+ JS2.LOGGER.info('Input Directory:' + updater.inDir + ' -> Output Directory:' + updater.outDir);
1386
+ if (updater.recursive) JS2.LOGGER.info('RECURSIVE');
1380
1387
 
1381
1388
  // HACK to get this integrated with ruby
1382
- updater.update();
1383
- setInterval(function($1,$2,$3){ console.log('updating'); updater.update(true, function($1,$2,$3){ return JS2.DECORATOR.file($1); }); }, interval * 1000);
1389
+ var decor = function($1,$2,$3){ return JS2.DECORATOR.file($1) };
1390
+ updater.update(true, decor);
1391
+ this.fs.setInterval(function($1,$2,$3){ JS2.LOGGER.info('updating'); updater.update(false, decor); }, interval * 1000);
1384
1392
  });
1385
1393
 
1386
1394
  OO.addMember("showBanner",function () {
data/lib/js2/rack.rb CHANGED
@@ -6,21 +6,23 @@ module JS2
6
6
  ROOT = File.expand_path(Dir.getwd)
7
7
 
8
8
  DEFAULT_CONFIG = {
9
- 'in_dir' => "#{ROOT}/app/js2",
10
- 'out_dir' => "#{ROOT}/public/javascripts",
11
- 'bin' => (`which js2`.chomp rescue nil)
9
+ 'source_dir' => "#{ROOT}/app/js2",
10
+ 'out_dir' => "#{ROOT}/public/javascripts",
11
+ 'bin' => (`which js2`.chomp rescue nil),
12
+ 'copy_js2' => true
12
13
  }
13
14
 
14
15
  def initialize(app)
15
16
  @app = app
16
17
 
17
- @config = YAML.read_file(ROOT + '/config/js2.yml') rescue DEFAULT_CONFIG
18
+ config = YAML.load_file(ROOT + '/config/js2.yml') rescue DEFAULT_CONFIG
18
19
 
19
- @in_dir = @config['in_dir']
20
- @out_dir = @config['out_dir']
21
- @bin = @config['bin']
20
+ @source_dir = config['source_dir'] || './app/js2'
21
+ @out_dir = config['out_dir'] || './public/javascripts'
22
+ @bin = config['bin'] || 'js2'
23
+ @copy_js2 = config.has_key?('copy_js2') ? config['copy_js2'] : true
22
24
 
23
- @valid = @in_dir && @out_dir && !@bin.blank?
25
+ @valid = @source_dir && @out_dir && !@bin.blank?
24
26
 
25
27
  unless @valid
26
28
  puts "JS2 is not configured properly"
@@ -28,7 +30,15 @@ module JS2
28
30
  end
29
31
 
30
32
  def call(env)
31
- `#{@bin} compile #{@in_dir} #{@out_dir}` if @valid
33
+ if @copy_js2
34
+ to_file = ROOT + '/public/javascripts/js2.js'
35
+ unless File.exists?(to_file)
36
+ from_file = JS2::ROOT + '/js2/browser.js'
37
+ File.open(to_file, 'w') { |f| f << File.read(from_file) }
38
+ end
39
+ end
40
+
41
+ `#{@bin} compile -f=browser -m #{@source_dir} #{@out_dir}` if @valid
32
42
  @app.call(env)
33
43
  end
34
44
  end
data/lib/js2.rb CHANGED
@@ -20,6 +20,8 @@ module JS2
20
20
  end
21
21
 
22
22
  dirname = File.dirname(File.expand_path('', __FILE__))
23
+ JS2::ROOT = dirname
24
+
23
25
  %W{ context fs command rack }.each do |f|
24
26
  require "#{dirname}/js2/#{f}"
25
27
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 3
8
- - 5
9
- version: 0.3.5
8
+ - 6
9
+ version: 0.3.6
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jeff Su
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-03-14 00:00:00 -07:00
17
+ date: 2011-03-20 00:00:00 -07:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -47,6 +47,7 @@ files:
47
47
  - lib/js2/fs.rb
48
48
  - lib/js2/rack.rb
49
49
  - lib/js2.rb
50
+ - lib/js2/browser.js
50
51
  - lib/js2/js2.js
51
52
  - CHANGELOG
52
53
  has_rdoc: true