js2 0.1.7 → 0.1.8
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +4 -0
- data/README.md +61 -51
- data/Rakefile +4 -3
- data/js2.gemspec +4 -4
- data/lib/js2/parser/tokenizer.rb +5 -5
- data/lib/js2/ragel/tokenizer.rl +2 -2
- data/lib/js2/ragel/tokenizer.rl.erb +1 -1
- data/lib/js2/util/js2bootstrap.js2 +47 -0
- data/wiki/features.md +73 -106
- data/wiki/installation.md +8 -48
- metadata +5 -5
data/CHANGELOG
CHANGED
data/README.md
CHANGED
@@ -1,65 +1,75 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
* [Source Code](http://github.com/jeffsu/js2)
|
4
|
-
|
5
|
-
## OO Javascript
|
6
|
-
|
7
|
-
For every Javascript developer that has ever wanted to create a library for his/her project, there comes a time when an Object Oriented approach is necessary (or extremely desired). Fortunately, there are a plethora of options to choose from:
|
1
|
+
[JS2](http://github.com/jeffsu/js2) - Friendly Cross Browser Object Oriented Javascript
|
2
|
+
=======================================================================================
|
8
3
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
> MyClass.prototype = {
|
14
|
-
> method1: function () { alert('method1 called'); }
|
15
|
-
> }
|
16
|
-
> embedding functions right in the instantiator:
|
17
|
-
> function MyClass () {
|
18
|
-
> this.member1 = "member1";
|
19
|
-
> function method1 () {
|
20
|
-
> alert("method1 called");
|
21
|
-
> }
|
22
|
-
> }
|
23
|
-
> using jQuery (or any of the js OO frameworks) by passing in hashes:
|
24
|
-
> var MyClass = Class.create({
|
25
|
-
> member1: "member1",
|
26
|
-
> method1: function(){ alert("method1 called") },
|
27
|
-
> });
|
28
|
-
Unfortunately, these solutions are dissimilar to Java, Ruby, and C-based languages.
|
4
|
+
JS2 is a way to write classes in a more familiar way for programmers who are used to syntax in languages such as: Java, Ruby, C++, etc...
|
5
|
+
The main motivation is to provide a clean and a less verbose syntax for creating classes, inheritance and modules in Javascript. JS2 plays
|
6
|
+
nicely with most of the popular frameworks including: jQuery and prototype. It also provides some syntactic sugar on the repetative aspects
|
7
|
+
of Javascript.
|
29
8
|
|
30
|
-
|
9
|
+
Sample Syntax:
|
10
|
+
class Rectangle {
|
11
|
+
property height;
|
12
|
+
property width;
|
13
|
+
|
14
|
+
function area () {
|
15
|
+
return this.height * this.width;
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
class Square extends Rectangle {
|
20
|
+
function area () {
|
21
|
+
return this.width * this.width;
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
var s = new Square();
|
31
26
|
|
32
|
-
|
27
|
+
* [Installation](http://github.com/jeffsu/js2/blob/master/wiki/installation.md)
|
28
|
+
* [Language Features and Examples](http://github.com/jeffsu/js2/blob/master/wiki/features.md)
|
29
|
+
* [Compiler Features](http://github.com/jeffsu/js2/blob/master/wiki/compiler.md)
|
30
|
+
* [Source](http://github.com/jeffsu/js2)
|
33
31
|
|
34
|
-
|
32
|
+
Things You need to run JS2
|
33
|
+
--------------------------
|
34
|
+
* Ruby - language used to parse js2 and generate javascript
|
35
|
+
* Ruby Gems - ruby package manager
|
36
|
+
* js2
|
37
|
+
* RubyInline
|
38
|
+
* haml (optional)
|
35
39
|
|
36
|
-
|
37
|
-
|
40
|
+
Quick Start Guide
|
41
|
+
-----------------
|
42
|
+
Create a js2 file (foo.js2):
|
43
|
+
class Person {
|
44
|
+
function speak() {
|
45
|
+
alert("Hello! I'm a person!");
|
46
|
+
}
|
38
47
|
|
39
|
-
function
|
40
|
-
|
48
|
+
function walk() {
|
49
|
+
alert("Walking!");
|
41
50
|
}
|
42
51
|
}
|
43
52
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
member1: "member1",
|
49
|
-
method1: function () { alert("method1 called"); }
|
53
|
+
class Student extends Person {
|
54
|
+
function speak() {
|
55
|
+
alert("Hello, I'm a student!");
|
56
|
+
}
|
50
57
|
}
|
51
58
|
|
52
|
-
|
59
|
+
var person = new Person();
|
60
|
+
var student = new Student();
|
61
|
+
|
62
|
+
person.speak();
|
63
|
+
student.speak();
|
64
|
+
person.walk();
|
65
|
+
student.walk();
|
53
66
|
|
54
|
-
|
55
|
-
|
56
|
-
* getters and setters
|
57
|
-
* IoC (Dependency Injection)
|
58
|
-
* AOP (Aspect Oriented Programming)
|
59
|
-
* foreach
|
60
|
-
* currying
|
61
|
-
* More Features
|
67
|
+
Run js2 in the same directory
|
68
|
+
js2 compile
|
62
69
|
|
63
|
-
|
70
|
+
You should now see these files in that directory:
|
71
|
+
* foo.js2
|
72
|
+
* foo.js
|
73
|
+
* js2bootstrap.js
|
64
74
|
|
65
|
-
|
75
|
+
Include these js2bootstrap.js and foo.js (make sure js2bootstrap.js is included first) in your html page.
|
data/Rakefile
CHANGED
@@ -2,9 +2,10 @@ require 'rubygems'
|
|
2
2
|
require 'rake'
|
3
3
|
require 'echoe'
|
4
4
|
|
5
|
-
JS2_VERSION = '0.1.
|
5
|
+
JS2_VERSION = '0.1.8'
|
6
6
|
Echoe.new('js2', JS2_VERSION) do |p|
|
7
|
-
p.
|
7
|
+
p.summary = "Cross-Browser Object Oriented Javascript Compiler"
|
8
|
+
p.description = "Cross-Browser Object Oriented Javascript Compiler"
|
8
9
|
p.url = "http://github.com/jeffsu/js2"
|
9
10
|
p.author = "Jeff Su"
|
10
11
|
p.email = "me@jeffsu.com"
|
@@ -16,7 +17,7 @@ end
|
|
16
17
|
|
17
18
|
namespace :js2 do
|
18
19
|
task :compile do
|
19
|
-
system("
|
20
|
+
system("cd ./lib/js2/ragel/; ruby helper.rb; ragel -C tokenizer.rl; mv tokenizer.c ../parser/tokenizer.rb")
|
20
21
|
end
|
21
22
|
|
22
23
|
task :install do
|
data/js2.gemspec
CHANGED
@@ -2,13 +2,13 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{js2}
|
5
|
-
s.version = "0.1.
|
5
|
+
s.version = "0.1.8"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Jeff Su"]
|
9
|
-
s.date = %q{2010-10-
|
9
|
+
s.date = %q{2010-10-21}
|
10
10
|
s.default_executable = %q{js2}
|
11
|
-
s.description = %q{}
|
11
|
+
s.description = %q{Cross-Browser Object Oriented Javascript Compiler}
|
12
12
|
s.email = %q{me@jeffsu.com}
|
13
13
|
s.executables = ["js2"]
|
14
14
|
s.extra_rdoc_files = ["README.md", "CHANGELOG", "bin/js2", "lib/js2.rb", "lib/js2/parser/haml.rb", "lib/js2/parser/haml_engine.rb", "lib/js2/parser/lexer.rb", "lib/js2/parser/tokenizer.rb", "lib/js2/ragel/helper.rb", "lib/js2/ragel/tokenizer.rl", "lib/js2/ragel/tokenizer.rl.erb", "lib/js2/standard/class_node.rb", "lib/js2/standard/factory.rb", "lib/js2/standard/node.rb", "lib/js2/util/compilation.rb", "lib/js2/util/config.rb", "lib/js2/util/exec.rb", "lib/js2/util/file_handler.rb", "lib/js2/util/js2bootstrap.js2", "lib/js2/util/processor.rb", "lib/js2/util/rdoc.rb", "lib/js2/util/sel_decorator.rb", "lib/js2/util/haml_filter.rb", "lib/js2/util/jamis.rb"]
|
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.require_paths = ["lib"]
|
19
19
|
s.rubyforge_project = %q{js2}
|
20
20
|
s.rubygems_version = %q{1.3.7}
|
21
|
-
s.summary = %q{}
|
21
|
+
s.summary = %q{Cross-Browser Object Oriented Javascript Compiler}
|
22
22
|
s.test_files = ["test/test_js2.rb", "test/test_helper.rb"]
|
23
23
|
|
24
24
|
if s.respond_to? :specification_version then
|
data/lib/js2/parser/tokenizer.rb
CHANGED
@@ -21,7 +21,7 @@ class JS2::Parser::Tokenizer
|
|
21
21
|
// convert ruby string to char*
|
22
22
|
VALUE r_str = argv[0];
|
23
23
|
int data_length = #{RUBY_VERSION.match(/^1\.8/) ? "RSTRING(r_str)->len" : "RSTRING_LEN(r_str)"};
|
24
|
-
char* data =
|
24
|
+
char* data = StringValuePtr(r_str);
|
25
25
|
|
26
26
|
int in_class = 0;
|
27
27
|
int in_module = 0;
|
@@ -2498,7 +2498,7 @@ _resume:
|
|
2498
2498
|
while ( _nacts-- > 0 ) {
|
2499
2499
|
switch ( *_acts++ ) {
|
2500
2500
|
case 6:
|
2501
|
-
#line 1 "
|
2501
|
+
#line 1 "NONE"
|
2502
2502
|
{ts = p;}
|
2503
2503
|
break;
|
2504
2504
|
#line 2505 "tokenizer.c"
|
@@ -2592,7 +2592,7 @@ _eof_trans:
|
|
2592
2592
|
{regexp_start = p;}
|
2593
2593
|
break;
|
2594
2594
|
case 7:
|
2595
|
-
#line 1 "
|
2595
|
+
#line 1 "NONE"
|
2596
2596
|
{te = p+1;}
|
2597
2597
|
break;
|
2598
2598
|
case 8:
|
@@ -3392,7 +3392,7 @@ _eof_trans:
|
|
3392
3392
|
}}
|
3393
3393
|
break;
|
3394
3394
|
case 139:
|
3395
|
-
#line 1 "
|
3395
|
+
#line 1 "NONE"
|
3396
3396
|
{ switch( act ) {
|
3397
3397
|
case 1:
|
3398
3398
|
{{p = ((te))-1;}
|
@@ -3495,7 +3495,7 @@ _again:
|
|
3495
3495
|
while ( _nacts-- > 0 ) {
|
3496
3496
|
switch ( *_acts++ ) {
|
3497
3497
|
case 5:
|
3498
|
-
#line 1 "
|
3498
|
+
#line 1 "NONE"
|
3499
3499
|
{ts = 0;}
|
3500
3500
|
break;
|
3501
3501
|
#line 3502 "tokenizer.c"
|
data/lib/js2/ragel/tokenizer.rl
CHANGED
@@ -434,8 +434,8 @@ class JS2::Parser::Tokenizer
|
|
434
434
|
int tokenize (int argc, VALUE *argv, VALUE self) {
|
435
435
|
// convert ruby string to char*
|
436
436
|
VALUE r_str = argv[0];
|
437
|
-
int data_length = RSTRING(r_str)->len;
|
438
|
-
char* data =
|
437
|
+
int data_length = #{RUBY_VERSION.match(/^1\.8/) ? "RSTRING(r_str)->len" : "RSTRING_LEN(r_str)"};
|
438
|
+
char* data = StringValuePtr(r_str);
|
439
439
|
|
440
440
|
int in_class = 0;
|
441
441
|
int in_module = 0;
|
@@ -257,7 +257,7 @@ class JS2::Parser::Tokenizer
|
|
257
257
|
// convert ruby string to char*
|
258
258
|
VALUE r_str = argv[0];
|
259
259
|
int data_length = #{RUBY_VERSION.match(/^1\.8/) ? "RSTRING(r_str)->len" : "RSTRING_LEN(r_str)"};
|
260
|
-
char* data =
|
260
|
+
char* data = StringValuePtr(r_str);
|
261
261
|
|
262
262
|
int in_class = 0;
|
263
263
|
int in_module = 0;
|
@@ -399,3 +399,50 @@ class JS2.App.JQuery extends JS2.App {
|
|
399
399
|
}
|
400
400
|
}
|
401
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
|
+
|
data/wiki/features.md
CHANGED
@@ -1,106 +1,73 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
> foreach (var item:i in array) alert(i + ' is ' + item);
|
75
|
-
> curry (arg1, arg2) with (scopeVar1, scopeVar2) { };
|
76
|
-
|
77
|
-
##Other Features
|
78
|
-
|
79
|
-
### Templating in HAML/SASS (useful for ajax applications)
|
80
|
-
|
81
|
-
> //--- in uiBuilder.js2.haml
|
82
|
-
> UIBuilder
|
83
|
-
> button(name)
|
84
|
-
> %div.button= "#name#"
|
85
|
-
>
|
86
|
-
> //--- in uiBuilder.js2
|
87
|
-
> class UIBuilder {
|
88
|
-
> function getButton (name) {
|
89
|
-
> this.htmlCache.button(name);
|
90
|
-
> }
|
91
|
-
> }
|
92
|
-
>
|
93
|
-
> //--- in page.html
|
94
|
-
> var ui = new UIBuilder();
|
95
|
-
> var ele = document.getElementById('buttonContainer');
|
96
|
-
> ele.innerHTML = ui.button('my button');
|
97
|
-
|
98
|
-
### Selenium Testing Integration
|
99
|
-
|
100
|
-
... Coming soon ...
|
101
|
-
|
102
|
-
This is a little bit harder to explain, and is only for Ruby Selenium RC developers. The idea is that complex javascript applications usually reference most important DOM elements in javascript for things such as altering html or adding event handlers. What selenium integration in js2 means is that one can use annotations in his/her code to "mark" DOM elements instead of using xpaths.
|
103
|
-
|
104
|
-
One of the pain points in Selenium testing is that the xpaths are always changing with each iteration of the view layer. In a complex javascript application, one has to maintain the references to DOM objects in javascript anyway, so this would be an easier way to maintain the Selenium references to the DOM.
|
105
|
-
|
106
|
-
While this is available, its not quite ready for public consumption.
|
1
|
+
[JS2](http://github.com/jeffsu/js2) - Friendly Cross Browser Object Oriented Javascript
|
2
|
+
=======================================================================================
|
3
|
+
|
4
|
+
Classes and Methods
|
5
|
+
--------------------
|
6
|
+
To create a class, use the "class" keyword followed by matching curly braces. If the class
|
7
|
+
has an "initialize" method defined, it will run that right after an instance is created.
|
8
|
+
Getters and setters can be created by using the "property" keyword.
|
9
|
+
|
10
|
+
|
11
|
+
Here is an example of a class:
|
12
|
+
|
13
|
+
class Person {
|
14
|
+
// creates getName() and setName(name) methods
|
15
|
+
property name;
|
16
|
+
|
17
|
+
// creates getAge() and setAge(age) methods
|
18
|
+
property age;
|
19
|
+
|
20
|
+
// called after new Person(age) is called
|
21
|
+
function initialize(age) {
|
22
|
+
this.age = age;
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
var p = new Person(14);
|
27
|
+
p.setName("Jeff");
|
28
|
+
var age = p.getAge(); // 14
|
29
|
+
|
30
|
+
Modules/Mixins/Multiple Inheritance
|
31
|
+
-----------------------------------
|
32
|
+
JS2 uses a Ruby-inspired methodology for multiple inheritance. Here is an example
|
33
|
+
of how it works:
|
34
|
+
|
35
|
+
module Flyable {
|
36
|
+
function fly() {
|
37
|
+
alert("I believe I can fly!");
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
class Duck {
|
42
|
+
include Flyable;
|
43
|
+
}
|
44
|
+
|
45
|
+
var duck = new Duck();
|
46
|
+
duck.fly();
|
47
|
+
|
48
|
+
Syntactic Sugar
|
49
|
+
---------------
|
50
|
+
|
51
|
+
*Foreach*: iterating through an array without having to manually create temp variables:
|
52
|
+
|
53
|
+
var items = [ 'foo', 'bar', 'baz' ]
|
54
|
+
foreach (var item in items) {
|
55
|
+
alert(item);
|
56
|
+
}
|
57
|
+
|
58
|
+
// with index
|
59
|
+
foreach (var item:i in items) {
|
60
|
+
alert(i + ':' + item);
|
61
|
+
}
|
62
|
+
|
63
|
+
*Currying*: tightly scoped anonymous functions to prevent memory leaks
|
64
|
+
|
65
|
+
var bigData = getBigData();
|
66
|
+
var inScope = getSmallData();
|
67
|
+
|
68
|
+
element.onClick = curry (evt) with (inScope, this) {
|
69
|
+
alert("curry" + inScope);
|
70
|
+
// variable "self" is available as the "this" in the outer scope
|
71
|
+
}
|
72
|
+
|
73
|
+
|
data/wiki/installation.md
CHANGED
@@ -1,53 +1,13 @@
|
|
1
|
-
|
1
|
+
[JS2](http://github.com/jeffsu/js2) - Installation
|
2
|
+
=======================================================================================
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
> js2 --out-dir=/dir/to/write/js /dir/with/js2
|
4
|
+
1. Install Ruby Gems
|
5
|
+
2. Install js2
|
6
|
+
gem install js2
|
7
7
|
|
8
|
-
|
8
|
+
You should now have the js2 executable in your path. Running this command should bring up the
|
9
|
+
help page.
|
9
10
|
|
10
|
-
|
11
|
+
js2
|
11
12
|
|
12
|
-
From the rails root directory
|
13
13
|
|
14
|
-
> js2 --out-dir=./public/javascripts ./app/js2
|
15
|
-
|
16
|
-
To daemonize it and have it routinely check for changes (every 0.5 secs):
|
17
|
-
|
18
|
-
> js2 -d --out-dir=./public/javascripts ./app/js2
|
19
|
-
|
20
|
-
## Quick Tutorial
|
21
|
-
|
22
|
-
In a new directory, do this:
|
23
|
-
|
24
|
-
> mkdir js2
|
25
|
-
> mkdir js
|
26
|
-
|
27
|
-
Now create some js2 classes: vi js2/base.js2
|
28
|
-
|
29
|
-
> class My.Base {
|
30
|
-
> function sayHi () {
|
31
|
-
> alert("hi");
|
32
|
-
> }
|
33
|
-
> }
|
34
|
-
|
35
|
-
vi js2/concrete.js2
|
36
|
-
|
37
|
-
> class My.Concrete {
|
38
|
-
> function sayHello () {
|
39
|
-
> alert("hello");
|
40
|
-
> }
|
41
|
-
> }
|
42
|
-
|
43
|
-
compile:
|
44
|
-
|
45
|
-
> js2 --out-dir=./js ./js2
|
46
|
-
|
47
|
-
Be sure to include js/classes.js, js/base.js, and concrete.js (order matters as far as classes is concerned) in your browser.
|
48
|
-
|
49
|
-
Now you can run this in javascript:
|
50
|
-
|
51
|
-
> var obj = new My.Concrete();
|
52
|
-
> obj.sayHi();
|
53
|
-
> obj.sayHello();
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
8
|
+
- 8
|
9
|
+
version: 0.1.8
|
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: 2010-10-
|
17
|
+
date: 2010-10-21 00:00:00 -07:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -30,7 +30,7 @@ dependencies:
|
|
30
30
|
version: "0"
|
31
31
|
type: :runtime
|
32
32
|
version_requirements: *id001
|
33
|
-
description:
|
33
|
+
description: Cross-Browser Object Oriented Javascript Compiler
|
34
34
|
email: me@jeffsu.com
|
35
35
|
executables:
|
36
36
|
- js2
|
@@ -144,7 +144,7 @@ rubyforge_project: js2
|
|
144
144
|
rubygems_version: 1.3.7
|
145
145
|
signing_key:
|
146
146
|
specification_version: 3
|
147
|
-
summary:
|
147
|
+
summary: Cross-Browser Object Oriented Javascript Compiler
|
148
148
|
test_files:
|
149
149
|
- test/test_js2.rb
|
150
150
|
- test/test_helper.rb
|