js2 0.0.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/Changelog ADDED
File without changes
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ === 0.0.1 2009-11-20
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/LICENSE ADDED
File without changes
data/Manifest.txt ADDED
@@ -0,0 +1,43 @@
1
+ Changelog
2
+ History.txt
3
+ LICENSE
4
+ Manifest.txt
5
+ PostInstall.txt
6
+ README
7
+ README.rdoc
8
+ Rakefile
9
+ examples/js2.yml
10
+ examples/test.yml
11
+ lib/javascript/sel_marker.js2
12
+ lib/javascript/test.js2
13
+ lib/js2.rb
14
+ lib/js2/ast/class_node.rb
15
+ lib/js2/ast/comment_node.rb
16
+ lib/js2/ast/haml_node.rb
17
+ lib/js2/ast/include_node.rb
18
+ lib/js2/ast/inherited_node.rb
19
+ lib/js2/ast/member_node.rb
20
+ lib/js2/ast/method_node.rb
21
+ lib/js2/ast/module_node.rb
22
+ lib/js2/ast/node.rb
23
+ lib/js2/ast/nodes.rb
24
+ lib/js2/ast/stuff_node.rb
25
+ lib/js2/config.rb
26
+ lib/js2/daemon.rb
27
+ lib/js2/decorator/app.rb
28
+ lib/js2/decorator/cleanser.rb
29
+ lib/js2/decorator/standard.rb
30
+ lib/js2/decorator/test.rb
31
+ lib/js2/parser/fast.rb
32
+ lib/js2/parser/haml.rb
33
+ lib/js2/process/file_handler.rb
34
+ lib/js2/process/haml_engine.rb
35
+ lib/js2/process/universe.rb
36
+ lib/js2/processor.rb
37
+ lib/js2/test/selenium.rb
38
+ lib/js2/test/selenium_element.rb
39
+ lib/js2/test/selenium_helper.rb
40
+ lib/tasks/js2.rake
41
+ meta/c_tokenizer.rl.erb
42
+ meta/replace.rb
43
+ bin/js2
data/PostInstall.txt ADDED
@@ -0,0 +1,7 @@
1
+
2
+ For more information on js2, see http://js2.rubyforge.org
3
+
4
+ NOTE: Change this information in PostInstall.txt
5
+ You can also delete it if you don't want it.
6
+
7
+
data/README ADDED
File without changes
data/README.rdoc ADDED
@@ -0,0 +1,48 @@
1
+ = js2
2
+
3
+ * http://github.com/#{github_username}/#{project_name}
4
+
5
+ == DESCRIPTION:
6
+
7
+ FIX (describe your package)
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * FIX (list of features or problems)
12
+
13
+ == SYNOPSIS:
14
+
15
+ FIX (code sample of usage)
16
+
17
+ == REQUIREMENTS:
18
+
19
+ * FIX (list of requirements)
20
+
21
+ == INSTALL:
22
+
23
+ * FIX (sudo gem install, anything else)
24
+
25
+ == LICENSE:
26
+
27
+ (The MIT License)
28
+
29
+ Copyright (c) 2009 FIXME full name
30
+
31
+ Permission is hereby granted, free of charge, to any person obtaining
32
+ a copy of this software and associated documentation files (the
33
+ 'Software'), to deal in the Software without restriction, including
34
+ without limitation the rights to use, copy, modify, merge, publish,
35
+ distribute, sublicense, and/or sell copies of the Software, and to
36
+ permit persons to whom the Software is furnished to do so, subject to
37
+ the following conditions:
38
+
39
+ The above copyright notice and this permission notice shall be
40
+ included in all copies or substantial portions of the Software.
41
+
42
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
43
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
44
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
45
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
46
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
47
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
48
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,42 @@
1
+ require 'rubygems'
2
+ gem 'hoe', '>= 2.1.0'
3
+ require 'hoe'
4
+ require 'fileutils'
5
+ require './lib/js2'
6
+
7
+ Hoe.plugin :newgem
8
+ # Hoe.plugin :website
9
+ # Hoe.plugin :cucumberfeatures
10
+
11
+ # Generate all the Rake tasks
12
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
13
+ $hoe = Hoe.spec 'js2' do
14
+ self.developer 'Jeff Su', 'me@jeffsu.com'
15
+ self.rubyforge_name = self.name
16
+ # self.extra_deps = [['activesupport','>= 2.0.2']]
17
+
18
+ end
19
+
20
+ require 'newgem/tasks'
21
+ Dir['tasks/**/*.rake'].each { |t| load t }
22
+
23
+
24
+ task :default => [ :build_ragel, :test ] do
25
+ end
26
+
27
+ task :build_ragel do
28
+ puts "build_ragel"
29
+ system("cd meta/; ruby replace.rb; cd ../; ragel -C meta/final_tokenizer.rl; mv meta/final_tokenizer.c lib/js2/parser/fast.rb")
30
+ end
31
+
32
+ task :test do
33
+ puts "run test"
34
+ system("ruby test/test.rb")
35
+ end
36
+
37
+ namespace :js2 => :envionment do
38
+ task :build do
39
+ p = JS2::Processor.processor_from_file(RAILS_ROOT + '/config/js2.yml', RAILS_ENV)
40
+ p.write_files
41
+ end
42
+ end
data/bin/js2 ADDED
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+
5
+ require 'rubygems'
6
+ require 'js2'
7
+
8
+ options = Hash.new
9
+
10
+ usage = "Usage: js2 [options] <dir-with-js2>"
11
+ op = OptionParser.new do |opts|
12
+ opts.banner = usage
13
+
14
+ opts.on("--js2-haml-dir DIR", "Directory with js2.haml files") do |haml|
15
+ options[:js2_haml_dir] = haml
16
+ end
17
+
18
+ opts.on("--out-dir DIR", "Directory of js2 -> js output") do |out|
19
+ options[:write_dir] = out
20
+ end
21
+
22
+ opts.on("-d", "--daemonize") do |d|
23
+ options[:daemonize] = true
24
+ end
25
+
26
+ opts.on('-h', "--help", "Help Screen") do
27
+ puts opts
28
+ exit
29
+ end
30
+ end
31
+
32
+ begin
33
+ op.parse!(ARGV)
34
+ rescue OptionParser::ParseError => e
35
+ puts op
36
+ end
37
+
38
+ dir = ARGV.pop
39
+
40
+ unless dir
41
+ puts op
42
+ exit
43
+ end
44
+
45
+
46
+ config = JS2::Config.new
47
+
48
+ config.js2_dir = dir
49
+ config.js2_haml_dir = options[:js2_haml_dir] || dir
50
+ config.write_dir = options[:write_dir] || dir
51
+
52
+ p = JS2::Processor.get(config)
53
+ if options[:daemonize]
54
+ d = JS2::Daemon.new(p)
55
+ d.run do
56
+ "Recompiled at #{Time.now}"
57
+ sleep 0.5
58
+ end
59
+ else
60
+ p.write_files
61
+ end
data/examples/js2.yml ADDED
@@ -0,0 +1,8 @@
1
+ devlopment:
2
+ test_mode: true
3
+ js2_dir: './js2'
4
+ js2_haml_dir: './js2'
5
+ write_dir: './javascripts/public'
6
+ haml_dir: './app/views'
7
+ reference_dir: './spec/js2refs'
8
+ haml_engine_class: 'Sci::Javascript::HamlEngine'
data/examples/test.yml ADDED
@@ -0,0 +1,5 @@
1
+ test_mode: true
2
+ js2_dir: './test/js2'
3
+ js2_haml_dir: './test/js2'
4
+ write_dir: './test/js'
5
+ reference_dir: './test/refs'
@@ -0,0 +1,139 @@
1
+ class JS2.SelMarker {
2
+
3
+ function initialize () {
4
+ this.scopes = {};
5
+ this.children = {};
6
+ this.selectors = {};
7
+ this.normalized = false;
8
+
9
+ // keep track of all the handlers
10
+ JS2.SEL_TRACKER.idCount = JS2.SEL_TRACKER.idCount || 0;
11
+ JS2.SEL_TRACKER.idCount++;
12
+ JS2.SEL_TRACKER[JS2.SEL_TRACKER.idCount] = this;
13
+ }
14
+
15
+ function newChild (namespace) {
16
+ if (! this.children[namespace]) this.children[namespace] = new JS2.SelMarker();
17
+ return this.children[namespace];
18
+ }
19
+
20
+ function addVal (scope, key, val, selector) {
21
+ this.normalized = false;
22
+ if (! this.scopes[scope]) {
23
+ this.scopes[scope] = {};
24
+ this.selectors[scope] = {};
25
+ }
26
+ this.scopes[scope][key] = val;
27
+ this.selectors[scope][key] = selector;
28
+ }
29
+
30
+ function appendVal (scope, key, val, selector) {
31
+ this.normalized = false;
32
+ if (! this.scopes[scope]) {
33
+ this.scopes[scope] = {};
34
+ this.selectors[scope] = {};
35
+ }
36
+ if (! this.scopes[scope][key]) {
37
+ this.scopes[scope][key] = [];
38
+ this.selectors[scope][key] = [];
39
+ }
40
+ this.scopes[scope][key].push(val);
41
+ this.selectors[scope][key].push(selector);
42
+ }
43
+
44
+ function getRawVal (scope, key) {
45
+ this.normalize();
46
+ return this.scopes[scope][key];
47
+ }
48
+
49
+ function getVal (scope, key, idx) {
50
+ this.normalize();
51
+ if (idx === undefined) {
52
+ var val = this.scopes[scope][key];
53
+ var sel = this.selectors[scope][key];
54
+ if (val.find && sel) val = val.find(sel);
55
+ return (val.jquery && val.length == 1) ? val[0] : val;
56
+ } else {
57
+ var val = this.scopes[scope][key];
58
+ var sel = this.selectors[scope][key];
59
+ if (val.find && sel) val = val.find(sel);
60
+ return val[idx];
61
+ }
62
+ }
63
+
64
+ function getJQ (scope, key, idx) {
65
+ idx = idx || 0;
66
+ return $(this.getVal(scope, key, idx));
67
+ }
68
+
69
+ function toJson () {
70
+ return JSON.stringify(this.toHash());
71
+ }
72
+
73
+ function toHash () {
74
+ this.normalize();
75
+ var ret = {
76
+ 'children': {}
77
+ };
78
+
79
+ for (var name in this.scopes) {
80
+ var scope = this.scopes[name];
81
+ ret[name] = {};
82
+ for (var key in scope) {
83
+ var val = scope[key];
84
+ if (val.length == 1) {
85
+ ret[name][key] = 'Scalar';
86
+ } else {
87
+ ret[name][key] = 'Array';
88
+ }
89
+ }
90
+ }
91
+
92
+ for (var namespace in this.children) {
93
+ var childMarker = this.children[namespace];
94
+ ret.children[namespace] = childMarker.toHash();
95
+ }
96
+
97
+ return ret;
98
+ }
99
+
100
+ function normalize () {
101
+ // TODO
102
+ this.normalized = true;
103
+ }
104
+
105
+ private
106
+
107
+ function normalizeVal (val) {
108
+ var ret = [];
109
+ if (typeof val == 'object') {
110
+ if (val.jquery) {
111
+ foreach (var e in val) {
112
+ if (! e) continue;
113
+ ret.push(e);
114
+ }
115
+ } else if (val instanceof Array) {
116
+ foreach (var v in val) {
117
+ if (! v) continue;
118
+ var norms = this.normalizeVal(v);
119
+ foreach (var norm in norms) {
120
+ if (! norm) continue;
121
+ ret.push(norm);
122
+ }
123
+ }
124
+ }
125
+ }
126
+
127
+ return ret;
128
+ }
129
+
130
+ }
131
+
132
+ JS2.SEL_EVENTS = {};
133
+ JS2.SEL_EVENTS.LEFT_BUTTON = $.browser.msie ? 1 : 0;
134
+ JS2.SEL_EVENTS.LEFT_MOUSE_UP = $.Event('mouseup');
135
+ JS2.SEL_EVENTS.LEFT_MOUSE_UP.button = JS2.SEL_EVENTS.LEFT_BUTTON;
136
+ JS2.SEL_EVENTS.LEFT_MOUSE_DOWN = $.Event('mousedown');
137
+ JS2.SEL_EVENTS.LEFT_MOUSE_DOWN.button = JS2.SEL_EVENTS.LEFT_BUTTON;
138
+ JS2.SEL_TRACKER = {};
139
+ JS2.SEL_MARKER = new JS2.SelMarker();
@@ -0,0 +1,73 @@
1
+ class JS2.Test {
2
+ function initialize () {
3
+ this.store = {};
4
+ this.namespaces = {};
5
+ }
6
+
7
+ function setNamespace (name) {
8
+ this.namespaces[name] = this.namespaces[name] || {};
9
+ this.switchNamespace(name);
10
+ }
11
+
12
+ function switchNamespace (name) {
13
+ if (! this.namespaces[name]) this.setNamespace(name);
14
+ this.store = this.namespaces[name];
15
+ }
16
+
17
+ function addEle (klass, key, ele) {
18
+ if (! this.store[klass]) this.store[klass] = {};
19
+
20
+ var klassStore = this.store[klass];
21
+ if (! klassStore[key]) klassStore[key] = {};
22
+
23
+ klassStore[key] = ele;
24
+ }
25
+
26
+ function pushEle (klass, key, ele) {
27
+ if (! this.store[klass]) this.store[klass] = {};
28
+ if (! this.store[klass][key]) this.store[klass][key] = [];
29
+ if (ele.length && ele.length > 1) {
30
+ foreach (var e in ele) {
31
+ this.store[klass][key].push(ele);
32
+ }
33
+ } else {
34
+ this.store[klass][key].push(ele)
35
+ }
36
+ }
37
+
38
+ function getEle (klass, key, n) {
39
+ if (! this.store[klass]) return false;
40
+ var ele = this.store[klass][key];
41
+
42
+ if (! ele) return false;
43
+
44
+ n = n || 0;
45
+
46
+ if (ele.length > 0) {
47
+ return ele[n];
48
+ } else {
49
+ return ele;
50
+ }
51
+ }
52
+
53
+ function setEle (klass, key) {
54
+ var ele = this.currentEle;
55
+ if (ele) {
56
+ ele.setAttribute(this.currentID);
57
+ }
58
+
59
+ var newEle = this.store[klass][key];
60
+ if (! newEle) return false;
61
+
62
+ if (newEle.jquery) {
63
+ newEle = newEle[0];
64
+ }
65
+
66
+ this.currentID = newEle.getAttribute('id');
67
+ newEle.setAttribute('id', 'JS2_TEST_ELEMENT');
68
+
69
+ return newEle.nodeName;
70
+ }
71
+ }
72
+
73
+ JS2.TEST = new JS2.Test();
@@ -0,0 +1,105 @@
1
+ class JS2::AST::ClassNode < JS2::AST::Node
2
+ attr_accessor :name, :members, :extends, :filename, :parent, :mem_hash, :haml, :includes, :included_mods, :statics
3
+
4
+ def initialize (filename, n, text, mems, includes, statics)
5
+ @filename = filename
6
+ @line_number = n
7
+ @members = mems
8
+ @text = text
9
+ @mem_hash = Hash.new
10
+ @child_filenames = Array.new
11
+ @super_hash = Hash.new
12
+ @includes = includes
13
+ @included_mods = []
14
+ @statics = statics
15
+
16
+ self.close!
17
+
18
+ @finalized = false
19
+ end
20
+
21
+ def is_module?
22
+ return false
23
+ end
24
+
25
+ def members
26
+ if self.haml
27
+ return @members + [ self.haml ]
28
+ else
29
+ return @members
30
+ end
31
+ end
32
+
33
+ def close!
34
+ parse_text!()
35
+ @members.each do |m|
36
+ next if m.is_a? JS2::AST::CommentNode
37
+ @mem_hash[m.name] = m
38
+ end
39
+ end
40
+
41
+ def finalize!
42
+ # already done dude
43
+ return if @finalized
44
+ @finalized = true
45
+
46
+ # make the connection
47
+ if parent
48
+ parent.finalize!
49
+ end
50
+
51
+ haml.finalize!(parent) if haml
52
+
53
+
54
+ @super_hash = Hash.new
55
+
56
+ if parent
57
+ # if parent has haml but not child
58
+ if parent.haml && ! haml
59
+ inherited = JS2::AST::InheritedNode.new
60
+ inherited.name = 'htmlCache'
61
+ inherited.extends = self.extends
62
+ @mem_hash['htmlCache'] = inherited
63
+ @members.push(inherited)
64
+ end
65
+
66
+ parent.mem_hash.each_pair do |name, m|
67
+ if @mem_hash[m.name]
68
+ @super_hash[m.name] = parent.name
69
+ end
70
+ end
71
+ end
72
+
73
+ included_mods.reverse.each do |c|
74
+ merge(c)
75
+ end
76
+
77
+ merge(parent) if parent
78
+ end
79
+
80
+ def merge (c)
81
+ c.mem_hash.each_pair do |name, m|
82
+ unless @mem_hash[name]
83
+ inherited = JS2::AST::InheritedNode.new
84
+ inherited.name = m.name
85
+ inherited.extends = c.name
86
+ @mem_hash[m.name] = inherited
87
+ @members.push(inherited)
88
+ end
89
+ end
90
+ end
91
+
92
+ def super_hash
93
+ return @super_hash
94
+ end
95
+
96
+
97
+ def parse_text!
98
+ m = @text.match(/\s+([\w\.]+)\s+(extends ([\w\.]+))?/)
99
+ @name = m[1]
100
+ @extends = m[3]
101
+ end
102
+
103
+ end
104
+
105
+
@@ -0,0 +1,2 @@
1
+ class JS2::AST::CommentNode < JS2::AST::Node
2
+ end
@@ -0,0 +1,22 @@
1
+ class JS2::AST::HamlNode < Hash
2
+ attr_accessor :attrs
3
+
4
+ def initialize
5
+ @attrs = []
6
+ end
7
+
8
+ def finalize! (parent)
9
+ @attrs = []
10
+
11
+ if parent && parent.haml
12
+ parent.haml.keys.each do |k|
13
+ next if self[k]
14
+ @attrs << [ k, "#{parent.name}.prototype.htmlCache.#{k}" ]
15
+ end
16
+ end
17
+
18
+ self.keys.each do |k|
19
+ @attrs << [ k, self[k] ]
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,11 @@
1
+ class JS2::AST::IncludeNode < JS2::AST::Node
2
+ attr_accessor :name
3
+
4
+ def close!
5
+ if m = @text.match(/^(\s*)include\s*([\.\w]+)\s*;/)
6
+ @padding = m[1]
7
+ @name = m[2]
8
+ end
9
+ end
10
+
11
+ end
@@ -0,0 +1,7 @@
1
+ class JS2::AST::InheritedNode
2
+ attr_accessor :name, :extends
3
+
4
+ def to_js
5
+ return " #{name}: #{extends}.prototype.#{name}"
6
+ end
7
+ end
@@ -0,0 +1,18 @@
1
+ class JS2::AST::MemberNode < JS2::AST::Node
2
+ attr_accessor :name, :klass
3
+
4
+ def close!
5
+ if m = @text.match(/^(\s*)var\s*([\w\$]+)\s*=(.*);/)
6
+ @padding = m[1]
7
+ @name = m[2]
8
+ @text = m[3].sub(/;\s*$/m, '')
9
+ elsif m = @text.match(/^(\s*)accessor\s*([\w\$]+)\s*;/)
10
+ @padding = m[1]
11
+ @name = m[2]
12
+ @text = "function (val) { if (arguments.length>0) this._#{@name}=val; return this._#{@name}; }"
13
+ else
14
+ raise 'Invalid member'
15
+ end
16
+ end
17
+
18
+ end
@@ -0,0 +1,29 @@
1
+ class JS2::AST::MethodNode < JS2::AST::Node
2
+ attr_accessor :name
3
+
4
+ def self.properties (filename, line, str)
5
+ ret = []
6
+
7
+ str.sub!(/property/, '')
8
+ str.split(/,/).collect { |s| s.strip.sub(/;$/, '') }.each do |prop|
9
+ name = String.new(prop)
10
+ name[0,1] = name[0,1].upcase
11
+ setter = "function set#{name} (val) { this.#{prop} = val; }"
12
+ getter = "function get#{name} () { return this.#{prop}; }"
13
+
14
+ ret << self.new(filename, line, setter)
15
+ ret << self.new(filename, line, getter)
16
+ end
17
+
18
+ return ret
19
+ end
20
+
21
+
22
+ def close!
23
+ m = @text.match(/^(\s*)function\s*(\w+)\s*(.*)\s*/m)
24
+ @padding = m[1]
25
+ @name = m[2]
26
+ @text = m[3].sub(/\s*$/m, '')
27
+ @annotations = []
28
+ end
29
+ end
@@ -0,0 +1,6 @@
1
+ class JS2::AST::ModuleNode < JS2::AST::ClassNode
2
+
3
+ def is_module?
4
+ return true
5
+ end
6
+ end
@@ -0,0 +1,14 @@
1
+ class JS2::AST::Node
2
+ attr_accessor :text, :filename, :line_number
3
+
4
+ def initialize (filename, n, text)
5
+ @line_number = n
6
+ @filename = filename
7
+ @text = text
8
+
9
+ self.close!
10
+ end
11
+
12
+ def close!
13
+ end
14
+ end