superchris-rubyjs 0.8.2
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/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
|