js2 0.3.5 → 0.3.6
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5 -0
- data/lib/js2/browser.js +278 -0
- data/lib/js2/fs.rb +1 -1
- data/lib/js2/js2.js +23 -15
- data/lib/js2/rack.rb +19 -9
- data/lib/js2.rb +2 -0
- metadata +4 -3
data/CHANGELOG
CHANGED
data/lib/js2/browser.js
ADDED
@@ -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
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.
|
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: " +
|
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
|
-
|
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.
|
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
|
-
|
1379
|
-
if (updater.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
|
-
|
1383
|
-
|
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
|
-
'
|
10
|
-
'out_dir'
|
11
|
-
'bin'
|
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
|
-
|
18
|
+
config = YAML.load_file(ROOT + '/config/js2.yml') rescue DEFAULT_CONFIG
|
18
19
|
|
19
|
-
@
|
20
|
-
@out_dir
|
21
|
-
@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 = @
|
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
|
-
|
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
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 3
|
8
|
-
-
|
9
|
-
version: 0.3.
|
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-
|
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
|