superchris-rubyjs 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README +131 -0
- data/Rakefile +65 -0
- data/bin/rubyjs +144 -0
- data/rubyjs.gemspec +112 -0
- data/src/rubyjs.rb +3 -0
- data/src/rubyjs/code_generator.rb +474 -0
- data/src/rubyjs/compiler.rb +2061 -0
- data/src/rubyjs/debug_name_generator.rb +95 -0
- data/src/rubyjs/encoder.rb +171 -0
- data/src/rubyjs/eval_into.rb +59 -0
- data/src/rubyjs/lib/core.rb +1016 -0
- data/src/rubyjs/lib/dom_element.rb +66 -0
- data/src/rubyjs/lib/json.rb +101 -0
- data/src/rubyjs/lib/microunit.rb +188 -0
- data/src/rubyjs/model.rb +293 -0
- data/src/rubyjs/name_generator.rb +71 -0
- data/src/rwt/AbsolutePanel.rb +161 -0
- data/src/rwt/DOM.Konqueror.rb +89 -0
- data/src/rwt/DOM.Opera.rb +65 -0
- data/src/rwt/DOM.rb +1044 -0
- data/src/rwt/Event.Opera.rb +35 -0
- data/src/rwt/Event.rb +429 -0
- data/src/rwt/HTTPRequest.IE6.rb +5 -0
- data/src/rwt/HTTPRequest.rb +74 -0
- data/src/rwt/Label.rb +164 -0
- data/src/rwt/Panel.rb +90 -0
- data/src/rwt/RootPanel.rb +16 -0
- data/src/rwt/UIObject.rb +495 -0
- data/src/rwt/Widget.rb +193 -0
- data/src/rwt/ported-from/AbsolutePanel.java +158 -0
- data/src/rwt/ported-from/DOM.java +571 -0
- data/src/rwt/ported-from/DOMImpl.java +426 -0
- data/src/rwt/ported-from/DOMImplOpera.java +82 -0
- data/src/rwt/ported-from/DOMImplStandard.java +234 -0
- data/src/rwt/ported-from/HTTPRequest.java +81 -0
- data/src/rwt/ported-from/HTTPRequestImpl.java +103 -0
- data/src/rwt/ported-from/Label.java +163 -0
- data/src/rwt/ported-from/Panel.java +99 -0
- data/src/rwt/ported-from/UIObject.java +614 -0
- data/src/rwt/ported-from/Widget.java +221 -0
- data/test/benchmark/bm_vm1_block.rb +15 -0
- data/test/benchmark/bm_vm1_const.rb +13 -0
- data/test/benchmark/bm_vm1_ensure.rb +15 -0
- data/test/benchmark/common.rb +5 -0
- data/test/benchmark/params.yaml +7 -0
- data/test/common.Browser.rb +13 -0
- data/test/common.rb +8 -0
- data/test/gen_browser_test_suite.rb +129 -0
- data/test/gen_test_suite.rb +41 -0
- data/test/run_benchs.rb +58 -0
- data/test/run_tests.rb +22 -0
- data/test/test_args.rb +24 -0
- data/test/test_array.rb +22 -0
- data/test/test_case.rb +35 -0
- data/test/test_class.rb +55 -0
- data/test/test_eql.rb +9 -0
- data/test/test_exception.rb +61 -0
- data/test/test_expr.rb +12 -0
- data/test/test_hash.rb +29 -0
- data/test/test_hot_ruby.rb +146 -0
- data/test/test_if.rb +28 -0
- data/test/test_insertion_sort.rb +25 -0
- data/test/test_inspect.rb +10 -0
- data/test/test_lebewesen.rb +39 -0
- data/test/test_massign.rb +66 -0
- data/test/test_new.rb +12 -0
- data/test/test_range.rb +70 -0
- data/test/test_regexp.rb +22 -0
- data/test/test_send.rb +65 -0
- data/test/test_simple_output.rb +5 -0
- data/test/test_splat.rb +21 -0
- data/test/test_string.rb +51 -0
- data/test/test_test.rb +17 -0
- data/test/test_yield.rb +154 -0
- data/utils/js/Makefile +9 -0
- data/utils/js/RunScript.class +0 -0
- data/utils/js/RunScript.java +73 -0
- data/utils/js/js.jar +0 -0
- data/utils/js/run.sh +3 -0
- data/utils/jsc/Makefile +7 -0
- data/utils/jsc/README +3 -0
- data/utils/jsc/RunScript.c +93 -0
- data/utils/jsc/run.sh +15 -0
- data/utils/yuicompressor/README +1 -0
- data/utils/yuicompressor/yuicompressor-2.2.5.jar +0 -0
- metadata +157 -0
@@ -0,0 +1,221 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright 2007 Google Inc.
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
5
|
+
* use this file except in compliance with the License. You may obtain a copy of
|
6
|
+
* the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
12
|
+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
13
|
+
* License for the specific language governing permissions and limitations under
|
14
|
+
* the License.
|
15
|
+
*/
|
16
|
+
package com.google.gwt.user.client.ui;
|
17
|
+
|
18
|
+
import com.google.gwt.core.client.GWT;
|
19
|
+
import com.google.gwt.user.client.DOM;
|
20
|
+
import com.google.gwt.user.client.Event;
|
21
|
+
import com.google.gwt.user.client.EventListener;
|
22
|
+
import com.google.gwt.user.client.Element;
|
23
|
+
|
24
|
+
/**
|
25
|
+
* The base class for the majority of user-interface objects. Widget adds
|
26
|
+
* support for receiving events from the browser and being added directly to
|
27
|
+
* {@link com.google.gwt.user.client.ui.Panel panels}.
|
28
|
+
*/
|
29
|
+
public class Widget extends UIObject implements EventListener {
|
30
|
+
|
31
|
+
private boolean attached;
|
32
|
+
private Object layoutData;
|
33
|
+
private Widget parent;
|
34
|
+
|
35
|
+
/**
|
36
|
+
* Gets this widget's parent panel.
|
37
|
+
*
|
38
|
+
* @return the widget's parent panel
|
39
|
+
*/
|
40
|
+
public Widget getParent() {
|
41
|
+
return parent;
|
42
|
+
}
|
43
|
+
|
44
|
+
/**
|
45
|
+
* Determines whether this widget is currently attached to the browser's
|
46
|
+
* document (i.e., there is an unbroken chain of widgets between this widget
|
47
|
+
* and the underlying browser document).
|
48
|
+
*
|
49
|
+
* @return <code>true</code> if the widget is attached
|
50
|
+
*/
|
51
|
+
public boolean isAttached() {
|
52
|
+
return attached;
|
53
|
+
}
|
54
|
+
|
55
|
+
public void onBrowserEvent(Event event) {
|
56
|
+
}
|
57
|
+
|
58
|
+
/**
|
59
|
+
* Removes this widget from its parent widget. If it has no parent, this
|
60
|
+
* method does nothing.
|
61
|
+
*
|
62
|
+
* @throws IllegalStateException if this widget's parent does not support
|
63
|
+
* removal (e.g. {@link Composite})
|
64
|
+
*/
|
65
|
+
public void removeFromParent() {
|
66
|
+
if (parent instanceof HasWidgets) {
|
67
|
+
((HasWidgets) parent).remove(this);
|
68
|
+
} else if (parent != null) {
|
69
|
+
throw new IllegalStateException(
|
70
|
+
"This widget's parent does not implement HasWidgets");
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
/**
|
75
|
+
* This method is called when a widget is attached to the browser's document.
|
76
|
+
* To receive notification after a Widget has been added from the
|
77
|
+
* document, override the {@link #onLoad} method.
|
78
|
+
*
|
79
|
+
* <p>
|
80
|
+
* Subclasses that override this method must call
|
81
|
+
* <code>super.onAttach()</code> to ensure that the Widget has been
|
82
|
+
* attached to the underlying Element.
|
83
|
+
* </p>
|
84
|
+
*
|
85
|
+
* @throws IllegalStateException if this widget is already attached
|
86
|
+
*/
|
87
|
+
protected void onAttach() {
|
88
|
+
if (attached) {
|
89
|
+
throw new IllegalStateException(
|
90
|
+
"Should only call onAttach when the widget is detached from the browser's document");
|
91
|
+
}
|
92
|
+
|
93
|
+
attached = true;
|
94
|
+
|
95
|
+
// Set the main element's event listener. This should only be set
|
96
|
+
// while the widget is attached, because it creates a circular
|
97
|
+
// reference between JavaScript and the DOM.
|
98
|
+
DOM.setEventListener(getElement(), this);
|
99
|
+
|
100
|
+
// Now that the widget is attached, call onLoad().
|
101
|
+
onLoad();
|
102
|
+
}
|
103
|
+
|
104
|
+
/**
|
105
|
+
* This method is called when a widget is detached from the browser's
|
106
|
+
* document. To receive notification before a Widget is removed from the
|
107
|
+
* document, override the {@link #onUnload} method.
|
108
|
+
*
|
109
|
+
* <p>
|
110
|
+
* Subclasses that override this method must call
|
111
|
+
* <code>super.onDetach()</code> to ensure that the Widget has been
|
112
|
+
* detached from the underlying Element. Failure to do so will result
|
113
|
+
* in application memeroy leaks due to circular references between DOM
|
114
|
+
* Elements and JavaScript objects.
|
115
|
+
* </p>
|
116
|
+
*
|
117
|
+
* @throws IllegalStateException if this widget is already detached
|
118
|
+
*/
|
119
|
+
protected void onDetach() {
|
120
|
+
if (!attached) {
|
121
|
+
throw new IllegalStateException(
|
122
|
+
"Should only call onDetach when the widget is attached to the browser's document");
|
123
|
+
}
|
124
|
+
|
125
|
+
// Give the user a chance to clean up, but don't trust the code to not throw
|
126
|
+
try {
|
127
|
+
onUnload();
|
128
|
+
} finally {
|
129
|
+
attached = false;
|
130
|
+
|
131
|
+
// Clear out the element's event listener (breaking the circular
|
132
|
+
// reference between it and the widget).
|
133
|
+
DOM.setEventListener(getElement(), null);
|
134
|
+
}
|
135
|
+
}
|
136
|
+
|
137
|
+
/**
|
138
|
+
* This method is called immediately after a widget becomes attached to the
|
139
|
+
* browser's document.
|
140
|
+
*/
|
141
|
+
protected void onLoad() {
|
142
|
+
}
|
143
|
+
|
144
|
+
/**
|
145
|
+
* This method is called immediately before a widget will be detached from the
|
146
|
+
* browser's document.
|
147
|
+
*/
|
148
|
+
protected void onUnload() {
|
149
|
+
}
|
150
|
+
|
151
|
+
/**
|
152
|
+
* Sets this object's browser element. Widget subclasses must call this method
|
153
|
+
* before attempting to call any other methods.
|
154
|
+
*
|
155
|
+
* If a browser element has already been attached, then it is replaced with
|
156
|
+
* the new element. The old event listeners are removed from the old browser
|
157
|
+
* element, and the event listeners are set up on the new browser element.
|
158
|
+
*
|
159
|
+
* @param elem the object's new element
|
160
|
+
*/
|
161
|
+
protected void setElement(Element elem) {
|
162
|
+
if (attached) {
|
163
|
+
// Remove old event listener to avoid leaking. onDetach will not do this
|
164
|
+
// for us, because it is only called when the widget itself is detached from
|
165
|
+
// the document.
|
166
|
+
DOM.setEventListener(getElement(), null);
|
167
|
+
}
|
168
|
+
|
169
|
+
super.setElement(elem);
|
170
|
+
if (attached) {
|
171
|
+
// Hook the event listener back up on the new element. onAttach will not
|
172
|
+
// do this for us, because it is only called when the widget itself is
|
173
|
+
// attached to the document.
|
174
|
+
DOM.setEventListener(elem, this);
|
175
|
+
}
|
176
|
+
}
|
177
|
+
|
178
|
+
/**
|
179
|
+
* Gets the panel-defined layout data associated with this widget.
|
180
|
+
*
|
181
|
+
* @return the widget's layout data
|
182
|
+
* @see #setLayoutData
|
183
|
+
*/
|
184
|
+
Object getLayoutData() {
|
185
|
+
return layoutData;
|
186
|
+
}
|
187
|
+
|
188
|
+
/**
|
189
|
+
* Sets the panel-defined layout data associated with this widget. Only the
|
190
|
+
* panel that currently contains a widget should ever set this value. It
|
191
|
+
* serves as a place to store layout bookkeeping data associated with a
|
192
|
+
* widget.
|
193
|
+
*
|
194
|
+
* @param layoutData the widget's layout data
|
195
|
+
*/
|
196
|
+
void setLayoutData(Object layoutData) {
|
197
|
+
this.layoutData = layoutData;
|
198
|
+
}
|
199
|
+
|
200
|
+
/**
|
201
|
+
* Sets this widget's parent. This method should only be called by
|
202
|
+
* {@link Panel} and {@link Composite}.
|
203
|
+
*
|
204
|
+
* @param parent the widget's new parent
|
205
|
+
*/
|
206
|
+
void setParent(Widget parent) {
|
207
|
+
Widget oldParent = this.parent;
|
208
|
+
this.parent = parent;
|
209
|
+
if (parent == null) {
|
210
|
+
if (oldParent != null && oldParent.isAttached()) {
|
211
|
+
onDetach();
|
212
|
+
assert !isAttached() :
|
213
|
+
"Failure of " + GWT.getTypeName(this) + " to call super.onDetach()";
|
214
|
+
}
|
215
|
+
} else if (parent.isAttached()) {
|
216
|
+
onAttach();
|
217
|
+
assert isAttached() :
|
218
|
+
"Failure of " + GWT.getTypeName(this) + " to call super.onAttach()";
|
219
|
+
}
|
220
|
+
}
|
221
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Kernel
|
2
|
+
=begin
|
3
|
+
def puts(obj="")
|
4
|
+
obj = obj.to_s.gsub("&", "&").gsub("<", "<").gsub(">", ">") + "<br/>"
|
5
|
+
`document.getElementById('out').innerHTML += #<obj>`
|
6
|
+
end
|
7
|
+
=end
|
8
|
+
|
9
|
+
def puts(obj="")
|
10
|
+
obj = obj.to_s
|
11
|
+
`STDOUT_puts(#<obj>)`
|
12
|
+
end
|
13
|
+
end
|
data/test/common.rb
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
require 'test/gen_test_suite'
|
3
|
+
|
4
|
+
if ARGV.empty?
|
5
|
+
tests = Dir['test/test_*.rb']
|
6
|
+
else
|
7
|
+
tests = Dir["test/test_{" + ARGV.join(',') + "}.rb"]
|
8
|
+
end
|
9
|
+
|
10
|
+
rubycode = Tempfile.new('rubyjs')
|
11
|
+
script = gen_test_suite(tests)
|
12
|
+
rubycode.write(script)
|
13
|
+
rubycode.close(false)
|
14
|
+
|
15
|
+
#
|
16
|
+
# Generate Javascript code
|
17
|
+
#
|
18
|
+
|
19
|
+
RED = '#ff8888'
|
20
|
+
GREEN = '#aaffaa'
|
21
|
+
|
22
|
+
expected = `ruby -I./test < #{rubycode.path}`.chomp. # remove last newline
|
23
|
+
gsub("&", "&").
|
24
|
+
gsub("<", "<").
|
25
|
+
gsub(">", ">").split("\n")
|
26
|
+
|
27
|
+
jscode = `./bin/rubyjs -I./test --opt PrettyPrint -P Browser -m TestSuite #{rubycode.path}`
|
28
|
+
jscode << <<END_JS
|
29
|
+
var STDOUT_LINE_NO = 0;
|
30
|
+
var FAILURES = 0;
|
31
|
+
var TOTAL = #{expected.size};
|
32
|
+
|
33
|
+
function STDOUT_puts(str)
|
34
|
+
{
|
35
|
+
var out = document.getElementById('out_' + STDOUT_LINE_NO);
|
36
|
+
var expected = document.getElementById('exp_' + STDOUT_LINE_NO);
|
37
|
+
|
38
|
+
out.innerHTML = str.replace(/[&]/g, "&").replace(/[<]/g, "<").replace(/[>]/g, ">");
|
39
|
+
|
40
|
+
if (out.innerHTML === expected.innerHTML)
|
41
|
+
{
|
42
|
+
document.getElementById('line_' + STDOUT_LINE_NO).style.background = '#{GREEN}';
|
43
|
+
}
|
44
|
+
else
|
45
|
+
{
|
46
|
+
FAILURES += 1;
|
47
|
+
}
|
48
|
+
|
49
|
+
STDOUT_LINE_NO += 1;
|
50
|
+
|
51
|
+
document.getElementById('status').innerHTML =
|
52
|
+
"<b>" + STDOUT_LINE_NO + "</b> / " + TOTAL + " (" + FAILURES + " failures)";
|
53
|
+
}
|
54
|
+
|
55
|
+
function start()
|
56
|
+
{
|
57
|
+
main();
|
58
|
+
}
|
59
|
+
END_JS
|
60
|
+
|
61
|
+
File.open('test/browser.test.js', 'w+') {|f| f << jscode}
|
62
|
+
|
63
|
+
html_script = script.gsub("&", "&").
|
64
|
+
gsub("<", "<").
|
65
|
+
gsub(">", ">").gsub("\n", "<br/>")
|
66
|
+
|
67
|
+
File.open('test/browser.test.html', 'w+') do |f|
|
68
|
+
f.puts %{<html><head><script language="javascript" src="browser.test.js"></script>
|
69
|
+
<style>
|
70
|
+
#expected { background: #ccc; }
|
71
|
+
</style>
|
72
|
+
<body onload="start();">
|
73
|
+
<h1>RubyJS Test Suite Runner</h1>
|
74
|
+
|
75
|
+
<a href="#source">View Ruby source code</a> |
|
76
|
+
<a href="browser.test.js">View Javascript source code</a><br/>
|
77
|
+
|
78
|
+
<p>
|
79
|
+
Test status (tests run / total # of tests): <div id="status"></div>
|
80
|
+
</p>
|
81
|
+
|
82
|
+
<table cellspacing="5" cellpadding="5">
|
83
|
+
<thead>
|
84
|
+
<tr>
|
85
|
+
<td width="50%"><b>Output</b></td>
|
86
|
+
<td width="50%"><b>Expected</b></td>
|
87
|
+
</tr>
|
88
|
+
</thead>
|
89
|
+
<tbody>
|
90
|
+
}
|
91
|
+
|
92
|
+
expected.each_with_index do |line, i|
|
93
|
+
f.puts %{
|
94
|
+
<tr id="line_#{i}" style="background: #{RED}">
|
95
|
+
<td>
|
96
|
+
<pre id="out_#{i}"></pre>
|
97
|
+
</td>
|
98
|
+
<td>
|
99
|
+
<pre id="exp_#{i}">#{line}</pre>
|
100
|
+
</td>
|
101
|
+
</tr>
|
102
|
+
}
|
103
|
+
end
|
104
|
+
|
105
|
+
f.puts %{
|
106
|
+
<tr><td colspan="2" style="background: grey"> </td></tr>
|
107
|
+
}
|
108
|
+
|
109
|
+
# Add some "overflow" rows, in case the RubyJS test output
|
110
|
+
# is longer as expected.
|
111
|
+
10.times do |i|
|
112
|
+
f.puts %{
|
113
|
+
<tr id="line_#{i+expected.size}">
|
114
|
+
<td>
|
115
|
+
<pre id="out_#{i+expected.size}"></pre>
|
116
|
+
</td>
|
117
|
+
<td>
|
118
|
+
<pre id="exp_#{i+expected.size}"></pre>
|
119
|
+
</td>
|
120
|
+
</tr>
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
f.puts %{
|
125
|
+
</tbody>
|
126
|
+
</table>
|
127
|
+
<pre id="source">#{html_script}</pre>
|
128
|
+
</body></html>}
|
129
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
def gen_test_suite(tests)
|
2
|
+
script = ""
|
3
|
+
body = ""
|
4
|
+
|
5
|
+
script << "require 'common'\n\n"
|
6
|
+
tests.each_with_index do |file, i|
|
7
|
+
basename = File.basename(file)[0..-4]
|
8
|
+
klassname = basename.gsub(/(^|_)./) {|m| m[-1,1].upcase}
|
9
|
+
humanname = basename.gsub('_', ' ').capitalize
|
10
|
+
|
11
|
+
script << "#\n"
|
12
|
+
script << "# file: #{file}\n"
|
13
|
+
script << "#\n\n"
|
14
|
+
script << "module T_#{klassname}\n"
|
15
|
+
script << File.read(file)
|
16
|
+
script << "end\n"
|
17
|
+
script << "\n\n"
|
18
|
+
body << %{
|
19
|
+
puts '~~~~~~~~~~~~~~~~~~~~'
|
20
|
+
puts '#{humanname}'
|
21
|
+
puts '~~~~~~~~~~~~~~~~~~~~'
|
22
|
+
T_#{klassname}::#{klassname}.main
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
script << %{
|
27
|
+
class TestSuite
|
28
|
+
def self.main
|
29
|
+
begin
|
30
|
+
#{body}
|
31
|
+
rescue Exception => a
|
32
|
+
p "unhandled exception"
|
33
|
+
p a
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
TestSuite.main unless $RUBYJS
|
38
|
+
}
|
39
|
+
|
40
|
+
return script
|
41
|
+
end
|