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.
Files changed (86) hide show
  1. data/README +131 -0
  2. data/Rakefile +65 -0
  3. data/bin/rubyjs +144 -0
  4. data/rubyjs.gemspec +112 -0
  5. data/src/rubyjs.rb +3 -0
  6. data/src/rubyjs/code_generator.rb +474 -0
  7. data/src/rubyjs/compiler.rb +2061 -0
  8. data/src/rubyjs/debug_name_generator.rb +95 -0
  9. data/src/rubyjs/encoder.rb +171 -0
  10. data/src/rubyjs/eval_into.rb +59 -0
  11. data/src/rubyjs/lib/core.rb +1016 -0
  12. data/src/rubyjs/lib/dom_element.rb +66 -0
  13. data/src/rubyjs/lib/json.rb +101 -0
  14. data/src/rubyjs/lib/microunit.rb +188 -0
  15. data/src/rubyjs/model.rb +293 -0
  16. data/src/rubyjs/name_generator.rb +71 -0
  17. data/src/rwt/AbsolutePanel.rb +161 -0
  18. data/src/rwt/DOM.Konqueror.rb +89 -0
  19. data/src/rwt/DOM.Opera.rb +65 -0
  20. data/src/rwt/DOM.rb +1044 -0
  21. data/src/rwt/Event.Opera.rb +35 -0
  22. data/src/rwt/Event.rb +429 -0
  23. data/src/rwt/HTTPRequest.IE6.rb +5 -0
  24. data/src/rwt/HTTPRequest.rb +74 -0
  25. data/src/rwt/Label.rb +164 -0
  26. data/src/rwt/Panel.rb +90 -0
  27. data/src/rwt/RootPanel.rb +16 -0
  28. data/src/rwt/UIObject.rb +495 -0
  29. data/src/rwt/Widget.rb +193 -0
  30. data/src/rwt/ported-from/AbsolutePanel.java +158 -0
  31. data/src/rwt/ported-from/DOM.java +571 -0
  32. data/src/rwt/ported-from/DOMImpl.java +426 -0
  33. data/src/rwt/ported-from/DOMImplOpera.java +82 -0
  34. data/src/rwt/ported-from/DOMImplStandard.java +234 -0
  35. data/src/rwt/ported-from/HTTPRequest.java +81 -0
  36. data/src/rwt/ported-from/HTTPRequestImpl.java +103 -0
  37. data/src/rwt/ported-from/Label.java +163 -0
  38. data/src/rwt/ported-from/Panel.java +99 -0
  39. data/src/rwt/ported-from/UIObject.java +614 -0
  40. data/src/rwt/ported-from/Widget.java +221 -0
  41. data/test/benchmark/bm_vm1_block.rb +15 -0
  42. data/test/benchmark/bm_vm1_const.rb +13 -0
  43. data/test/benchmark/bm_vm1_ensure.rb +15 -0
  44. data/test/benchmark/common.rb +5 -0
  45. data/test/benchmark/params.yaml +7 -0
  46. data/test/common.Browser.rb +13 -0
  47. data/test/common.rb +8 -0
  48. data/test/gen_browser_test_suite.rb +129 -0
  49. data/test/gen_test_suite.rb +41 -0
  50. data/test/run_benchs.rb +58 -0
  51. data/test/run_tests.rb +22 -0
  52. data/test/test_args.rb +24 -0
  53. data/test/test_array.rb +22 -0
  54. data/test/test_case.rb +35 -0
  55. data/test/test_class.rb +55 -0
  56. data/test/test_eql.rb +9 -0
  57. data/test/test_exception.rb +61 -0
  58. data/test/test_expr.rb +12 -0
  59. data/test/test_hash.rb +29 -0
  60. data/test/test_hot_ruby.rb +146 -0
  61. data/test/test_if.rb +28 -0
  62. data/test/test_insertion_sort.rb +25 -0
  63. data/test/test_inspect.rb +10 -0
  64. data/test/test_lebewesen.rb +39 -0
  65. data/test/test_massign.rb +66 -0
  66. data/test/test_new.rb +12 -0
  67. data/test/test_range.rb +70 -0
  68. data/test/test_regexp.rb +22 -0
  69. data/test/test_send.rb +65 -0
  70. data/test/test_simple_output.rb +5 -0
  71. data/test/test_splat.rb +21 -0
  72. data/test/test_string.rb +51 -0
  73. data/test/test_test.rb +17 -0
  74. data/test/test_yield.rb +154 -0
  75. data/utils/js/Makefile +9 -0
  76. data/utils/js/RunScript.class +0 -0
  77. data/utils/js/RunScript.java +73 -0
  78. data/utils/js/js.jar +0 -0
  79. data/utils/js/run.sh +3 -0
  80. data/utils/jsc/Makefile +7 -0
  81. data/utils/jsc/README +3 -0
  82. data/utils/jsc/RunScript.c +93 -0
  83. data/utils/jsc/run.sh +15 -0
  84. data/utils/yuicompressor/README +1 -0
  85. data/utils/yuicompressor/yuicompressor-2.2.5.jar +0 -0
  86. metadata +157 -0
@@ -0,0 +1,99 @@
1
+ /*
2
+ * Copyright 2006 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.user.client.DOM;
19
+ import com.google.gwt.user.client.Element;
20
+
21
+ import java.util.Iterator;
22
+
23
+ /**
24
+ * Abstract base class for all panels, which are widgets that can contain other
25
+ * widgets.
26
+ */
27
+ public abstract class Panel extends Widget implements HasWidgets {
28
+
29
+ public void add(Widget w) {
30
+ throw new UnsupportedOperationException("This panel does not support no-arg add()");
31
+ }
32
+
33
+ public void clear() {
34
+ Iterator it = iterator();
35
+ while (it.hasNext()) {
36
+ it.next();
37
+ it.remove();
38
+ }
39
+ }
40
+
41
+ /**
42
+ * This method must be called as part of the add method of any panel. It
43
+ * ensures that the Widget's parent is set properly, and that it is removed
44
+ * from any existing parent widget. It also attaches the child widget's
45
+ * DOM element to its new container, ensuring that this process occurs in the
46
+ * right order.
47
+ *
48
+ * @param w the widget to be adopted
49
+ * @param container the element within which it will be contained
50
+ */
51
+ protected void adopt(Widget w, Element container) {
52
+ // Remove the widget from its current parent, if any.
53
+ w.removeFromParent();
54
+
55
+ // Attach it at the DOM and GWT levels.
56
+ if (container != null) {
57
+ DOM.appendChild(container, w.getElement());
58
+ }
59
+ w.setParent(this);
60
+ }
61
+
62
+ /**
63
+ * This method must be called whenever a Widget is removed. It ensures that
64
+ * the Widget's parent is cleared.
65
+ *
66
+ * @param w the widget to be disowned
67
+ */
68
+ protected void disown(Widget w) {
69
+ // Only disown it if it's actually contained in this panel.
70
+ if (w.getParent() != this) {
71
+ throw new IllegalArgumentException("w is not a child of this panel");
72
+ }
73
+
74
+ // Remove it at the DOM and GWT levels.
75
+ Element elem = w.getElement();
76
+ w.setParent(null);
77
+ DOM.removeChild(DOM.getParent(elem), elem);
78
+ }
79
+
80
+ protected void onAttach() {
81
+ super.onAttach();
82
+
83
+ // Ensure that all child widgets are attached.
84
+ for (Iterator it = iterator(); it.hasNext();) {
85
+ Widget child = (Widget) it.next();
86
+ child.onAttach();
87
+ }
88
+ }
89
+
90
+ protected void onDetach() {
91
+ super.onDetach();
92
+
93
+ // Ensure that all child widgets are detached.
94
+ for (Iterator it = iterator(); it.hasNext();) {
95
+ Widget child = (Widget) it.next();
96
+ child.onDetach();
97
+ }
98
+ }
99
+ }
@@ -0,0 +1,614 @@
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.user.client.DOM;
19
+ import com.google.gwt.user.client.Element;
20
+
21
+ /**
22
+ * The superclass for all user-interface objects. It simply wraps a DOM element,
23
+ * and cannot receive events. Most interesting user-interface classes derive
24
+ * from {@link com.google.gwt.user.client.ui.Widget}.
25
+ *
26
+ * <h3>Styling With CSS</h3>
27
+ * <p>
28
+ * All <code>UIObject</code> objects can be styled using CSS. Style names that
29
+ * are specified programmatically in Java source are implicitly associated with
30
+ * CSS style rules. In terms of HTML and CSS, a GWT style name is the element's
31
+ * CSS "class". By convention, GWT style names are of the form
32
+ * <code>[project]-[widget]</code>.
33
+ * </p>
34
+ *
35
+ * <p>
36
+ * For example, the {@link Button} widget has the style name
37
+ * <code>gwt-Button</code>, meaning that within the <code>Button</code>
38
+ * constructor, the following call occurs:
39
+ *
40
+ * <pre class="code">
41
+ * setStyleName("gwt-Button");</pre>
42
+ *
43
+ * A corresponding CSS style rule can then be written as follows:
44
+ *
45
+ * <pre class="code">
46
+ * // Example of how you might choose to style a Button widget
47
+ * .gwt-Button {
48
+ * background-color: yellow;
49
+ * color: black;
50
+ * font-size: 24pt;
51
+ * }</pre>
52
+ *
53
+ * Note the dot prefix in the CSS style rule. This syntax is called a <a
54
+ * href="http://www.w3.org/TR/REC-CSS2/selector.html#class-html">CSS class
55
+ * selector</a>.
56
+ * </p>
57
+ *
58
+ * <h3>Style Name Specifics</h3>
59
+ * <p>
60
+ * Every <code>UIObject</code> has a <i>primary style name</i> that
61
+ * identifies the key CSS style rule that should always be applied to it. Use
62
+ * {@link #setStyleName(String)} to specify an object's primary style name. In
63
+ * most cases, the primary style name is set in a widget's constructor and never
64
+ * changes again during execution. In the case that no primary style name is
65
+ * specified, it defaults to <code>gwt-nostyle</code>.
66
+ * </p>
67
+ *
68
+ * <p>
69
+ * More complex styling behavior can be achieved by manipulating an object's
70
+ * <i>secondary style names</i>. Secondary style names can be added and removed
71
+ * using {@link #addStyleName(String)} and {@link #removeStyleName(String)}.
72
+ * The purpose of secondary style names is to associate a variety of CSS style
73
+ * rules over time as an object progresses through different visual states.
74
+ * </p>
75
+ *
76
+ * <p>
77
+ * There is an important special formulation of secondary style names called
78
+ * <i>dependent style names</i>. A dependent style name is a secondary style
79
+ * name prefixed with the primary style name of the widget itself. See
80
+ * {@link #addStyleName(String)} for details.
81
+ * </p>
82
+ */
83
+ public abstract class UIObject {
84
+
85
+ private static final String EMPTY_STYLENAME_MSG = "Style names cannot be empty";
86
+
87
+ private static final String NULL_HANDLE_MSG = "Null widget handle. If you "
88
+ + "are creating a composite, ensure that initWidget() has been called.";
89
+
90
+ private static final String STYLE_EMPTY = "gwt-nostyle";
91
+
92
+ public static native boolean isVisible(Element elem) /*-{
93
+ return (elem.style.display != 'none');
94
+ }-*/;
95
+
96
+ public static native void setVisible(Element elem, boolean visible) /*-{
97
+ elem.style.display = visible ? '' : 'none';
98
+ }-*/;
99
+
100
+ /**
101
+ * Sets the object's primary style name and updates all dependent style names.
102
+ *
103
+ * @param elem the element whose style is to be reset
104
+ * @param style the new primary style name
105
+ * @see #setStyleName(Element, String, boolean)
106
+ */
107
+ protected static void resetStyleName(Element elem, String style) {
108
+ if (elem == null) {
109
+ throw new RuntimeException(NULL_HANDLE_MSG);
110
+ }
111
+
112
+ // Style names cannot contain leading or trailing whitespace, and cannot
113
+ // legally be empty.
114
+ style = style.trim();
115
+ if (style.length() == 0) {
116
+ throw new IllegalArgumentException(EMPTY_STYLENAME_MSG);
117
+ }
118
+
119
+ ensurePrimaryStyleName(elem);
120
+ updatePrimaryAndDependentStyleNames(elem, style);
121
+ }
122
+
123
+ /**
124
+ * This convenience method adds or removes a secondary style name to the
125
+ * primary style name for a given element. Set {@link #setStyleName(String)}
126
+ * for a description of how primary and secondary style names are used.
127
+ *
128
+ * @param elem the element whose style is to be modified
129
+ * @param style the secondary style name to be added or removed
130
+ * @param add <code>true</code> to add the given style, <code>false</code>
131
+ * to remove it
132
+ */
133
+ protected static void setStyleName(Element elem, String style, boolean add) {
134
+ if (elem == null) {
135
+ throw new RuntimeException(NULL_HANDLE_MSG);
136
+ }
137
+
138
+ style = style.trim();
139
+ if (style.length() == 0) {
140
+ throw new IllegalArgumentException(EMPTY_STYLENAME_MSG);
141
+ }
142
+
143
+ // Get the current style string.
144
+ String oldStyle = ensurePrimaryStyleName(elem);
145
+ int idx;
146
+ if (oldStyle == null) {
147
+ idx = -1;
148
+ oldStyle = "";
149
+ } else {
150
+ idx = oldStyle.indexOf(style);
151
+ }
152
+
153
+ // Calculate matching index.
154
+ while (idx != -1) {
155
+ if (idx == 0 || oldStyle.charAt(idx - 1) == ' ') {
156
+ int last = idx + style.length();
157
+ int lastPos = oldStyle.length();
158
+ if ((last == lastPos)
159
+ || ((last < lastPos) && (oldStyle.charAt(last) == ' '))) {
160
+ break;
161
+ }
162
+ }
163
+ idx = oldStyle.indexOf(style, idx + 1);
164
+ }
165
+
166
+ if (add) {
167
+ // Only add the style if it's not already present.
168
+ if (idx == -1) {
169
+ if (oldStyle.length() > 0) {
170
+ oldStyle += " ";
171
+ }
172
+ DOM.setElementProperty(elem, "className", oldStyle + style);
173
+ }
174
+ } else {
175
+ // Don't try to remove the style if it's not there.
176
+ if (idx != -1) {
177
+ if (idx == 0) {
178
+ // You can't remove the base (i.e. the first) style name.
179
+ throw new IllegalArgumentException("Cannot remove base style name");
180
+ }
181
+ String begin = oldStyle.substring(0, idx);
182
+ String end = oldStyle.substring(idx + style.length());
183
+ DOM.setElementProperty(elem, "className", begin + end);
184
+ }
185
+ }
186
+ }
187
+
188
+ /**
189
+ * Ensure that the root element has a primary style name. If one is not
190
+ * already present, then it is assigned the default style name.
191
+ *
192
+ * @return the primary style name
193
+ */
194
+ private static String ensurePrimaryStyleName(Element elem) {
195
+ String className = DOM.getElementProperty(elem, "className").trim();
196
+
197
+ if ("".equals(className)) {
198
+ className = STYLE_EMPTY;
199
+ DOM.setElementProperty(elem, "className", className);
200
+ }
201
+
202
+ return className;
203
+ }
204
+
205
+ /**
206
+ * Replaces all instances of the primary style name with newPrimaryStyleName.
207
+ */
208
+ private static native void updatePrimaryAndDependentStyleNames(Element elem, String newStyle) /*-{
209
+ var className = elem.className;
210
+
211
+ var spaceIdx = className.indexOf(' ');
212
+ if (spaceIdx >= 0) {
213
+ // Get the old base style name from the beginning of the className.
214
+ var oldStyle = className.substring(0, spaceIdx);
215
+
216
+ // Replace oldStyle with newStyle. We have to do this by hand because
217
+ // there is no String.replaceAll() and String.replace() takes a regex,
218
+ // which we can't guarantee is safe on arbitrary class names.
219
+ var newClassName = '', curIdx = 0;
220
+ while (true) {
221
+ var idx = className.indexOf(oldStyle, curIdx);
222
+ if (idx == -1) {
223
+ newClassName += className.substring(curIdx);
224
+ break;
225
+ }
226
+
227
+ newClassName += className.substring(curIdx, idx);
228
+ newClassName += newStyle;
229
+ curIdx = idx + oldStyle.length;
230
+ }
231
+
232
+ elem.className = newClassName;
233
+ } else {
234
+ // There was no space, and therefore only one class name, which we can
235
+ // simply clobber.
236
+ elem.className = newStyle;
237
+ }
238
+ }-*/;
239
+
240
+ private Element element;
241
+
242
+ /**
243
+ * Adds a secondary or dependent style name to this object. A secondary style
244
+ * name is an additional style name that is, in HTML/CSS terms, included as a
245
+ * space-separated token in the value of the CSS <code>class</code>
246
+ * attribute for this object's root element.
247
+ *
248
+ * <p>
249
+ * The most important use for this method is to add a special kind of
250
+ * secondary style name called a <i>dependent style name</i>. To add a
251
+ * dependent style name, prefix the 'style' argument with the result of
252
+ * {@link #getStyleName()}. For example, suppose the primary style name is
253
+ * <code>gwt-TextBox</code>. If the following method is called as
254
+ * <code>obj.setReadOnly(true)</code>:
255
+ * </p>
256
+ *
257
+ * <pre class="code">
258
+ * public void setReadOnly(boolean readOnly) {
259
+ * isReadOnlyMode = readOnly;
260
+ *
261
+ * // Create a dependent style name.
262
+ * String readOnlyStyle = getStyleName() + "-readonly";
263
+ *
264
+ * if (readOnly) {
265
+ * addStyleName(readOnlyStyle);
266
+ * } else {
267
+ * removeStyleName(readOnlyStyle);
268
+ * }
269
+ * }</pre>
270
+ *
271
+ * <p>
272
+ * then both of the CSS style rules below will be applied:
273
+ * </p>
274
+ *
275
+ * <pre class="code">
276
+ *
277
+ * // This rule is based on the primary style name and is always active.
278
+ * .gwt-TextBox {
279
+ * font-size: 12pt;
280
+ * }
281
+ *
282
+ * // This rule is based on a dependent style name that is only active
283
+ * // when the widget has called addStyleName(getStyleName() + "-readonly").
284
+ * .gwt-TextBox-readonly {
285
+ * background-color: lightgrey;
286
+ * border: none;
287
+ * }</pre>
288
+ *
289
+ * <p>
290
+ * Dependent style names are powerful because they are automatically updated
291
+ * whenever the primary style name changes. Continuing with the example above,
292
+ * if the primary style name changed due to the following call:
293
+ * </p>
294
+ *
295
+ * <pre class="code">setStyleName("my-TextThingy");</pre>
296
+ *
297
+ * <p>
298
+ * then the object would be re-associated with style rules below rather than
299
+ * those above:
300
+ * </p>
301
+ *
302
+ * <pre class="code">
303
+ * .my-TextThingy {
304
+ * font-size: 12pt;
305
+ * }
306
+ *
307
+ * .my-TextThingy-readonly {
308
+ * background-color: lightgrey;
309
+ * border: none;
310
+ * }</pre>
311
+ *
312
+ * <p>
313
+ * Secondary style names that are not dependent style names are not
314
+ * automatically updated when the primary style name changes.
315
+ * </p>
316
+ *
317
+ * @param style the secondary style name to be added
318
+ * @see UIObject
319
+ * @see #removeStyleName(String)
320
+ */
321
+ public void addStyleName(String style) {
322
+ setStyleName(getStyleElement(), style, true);
323
+ }
324
+
325
+ /**
326
+ * Gets the object's absolute left position in pixels, as measured from the
327
+ * browser window's client area.
328
+ *
329
+ * @return the object's absolute left position
330
+ */
331
+ public int getAbsoluteLeft() {
332
+ return DOM.getAbsoluteLeft(getElement());
333
+ }
334
+
335
+ /**
336
+ * Gets the object's absolute top position in pixels, as measured from the
337
+ * browser window's client area.
338
+ *
339
+ * @return the object's absolute top position
340
+ */
341
+ public int getAbsoluteTop() {
342
+ return DOM.getAbsoluteTop(getElement());
343
+ }
344
+
345
+ /**
346
+ * Gets a handle to the object's underlying DOM element.
347
+ *
348
+ * @return the object's browser element
349
+ */
350
+ public Element getElement() {
351
+ return element;
352
+ }
353
+
354
+ /**
355
+ * Gets the object's offset height in pixels. This is the total height of the
356
+ * object, including decorations such as border, margin, and padding.
357
+ *
358
+ * @return the object's offset height
359
+ */
360
+ public int getOffsetHeight() {
361
+ return DOM.getElementPropertyInt(element, "offsetHeight");
362
+ }
363
+
364
+ /**
365
+ * Gets the object's offset width in pixels. This is the total width of the
366
+ * object, including decorations such as border, margin, and padding.
367
+ *
368
+ * @return the object's offset width
369
+ */
370
+ public int getOffsetWidth() {
371
+ return DOM.getElementPropertyInt(element, "offsetWidth");
372
+ }
373
+
374
+ /**
375
+ * Gets the primary style name associated with the object.
376
+ *
377
+ * @return the object's primary style name
378
+ * @see #setStyleName(String)
379
+ * @see #addStyleName(String)
380
+ * @see #removeStyleName(String)
381
+ */
382
+ public String getStyleName() {
383
+ String fullClassName = ensurePrimaryStyleName(getStyleElement());
384
+
385
+ // The base style name is always the first token of the full CSS class
386
+ // name. There can be no leading whitespace in the class name, so it's not
387
+ // necessary to trim() it.
388
+ int spaceIdx = fullClassName.indexOf(' ');
389
+ if (spaceIdx >= 0) {
390
+ return fullClassName.substring(0, spaceIdx);
391
+ }
392
+ return fullClassName;
393
+ }
394
+
395
+ /**
396
+ * Gets the title associated with this object. The title is the 'tool-tip'
397
+ * displayed to users when they hover over the object.
398
+ *
399
+ * @return the object's title
400
+ */
401
+ public String getTitle() {
402
+ return DOM.getElementProperty(element, "title");
403
+ }
404
+
405
+ /**
406
+ * Determines whether or not this object is visible.
407
+ *
408
+ * @return <code>true</code> if the object is visible
409
+ */
410
+ public boolean isVisible() {
411
+ return isVisible(element);
412
+ }
413
+
414
+ /**
415
+ * Removes a secondary style name.
416
+ *
417
+ * @param style the secondary style name to be removed
418
+ * @see #addStyleName(String)
419
+ */
420
+ public void removeStyleName(String style) {
421
+ setStyleName(getStyleElement(), style, false);
422
+ }
423
+
424
+ /**
425
+ * Sets the object's height. This height does not include decorations such as
426
+ * border, margin, and padding.
427
+ *
428
+ * @param height the object's new height, in CSS units (e.g. "10px", "1em")
429
+ */
430
+ public void setHeight(String height) {
431
+ // This exists to deal with an inconsistency in IE's implementation where
432
+ // it won't accept negative numbers in length measurements
433
+ assert extractLengthValue(height.trim().toLowerCase()) >= 0 :
434
+ "CSS heights should not be negative";
435
+ DOM.setStyleAttribute(element, "height", height);
436
+ }
437
+
438
+ /**
439
+ * Sets the object's size, in pixels, not including decorations such as
440
+ * border, margin, and padding.
441
+ *
442
+ * @param width the object's new width, in pixels
443
+ * @param height the object's new height, in pixels
444
+ */
445
+ public void setPixelSize(int width, int height) {
446
+ if (width >= 0) {
447
+ setWidth(width + "px");
448
+ }
449
+ if (height >= 0) {
450
+ setHeight(height + "px");
451
+ }
452
+ }
453
+
454
+ /**
455
+ * Sets the object's size. This size does not include decorations such as
456
+ * border, margin, and padding.
457
+ *
458
+ * @param width the object's new width, in CSS units (e.g. "10px", "1em")
459
+ * @param height the object's new height, in CSS units (e.g. "10px", "1em")
460
+ */
461
+ public void setSize(String width, String height) {
462
+ setWidth(width);
463
+ setHeight(height);
464
+ }
465
+
466
+ /**
467
+ * Sets the object's primary style name and updates all dependent style names.
468
+ *
469
+ * @param style the new primary style name
470
+ * @see #addStyleName(String)
471
+ * @see #removeStyleName(String)
472
+ */
473
+ public void setStyleName(String style) {
474
+ resetStyleName(getStyleElement(), style);
475
+ }
476
+
477
+ /**
478
+ * Sets the title associated with this object. The title is the 'tool-tip'
479
+ * displayed to users when they hover over the object.
480
+ *
481
+ * @param title the object's new title
482
+ */
483
+ public void setTitle(String title) {
484
+ if (title == null || title.length() == 0) {
485
+ DOM.removeElementAttribute(element, "title");
486
+ } else {
487
+ DOM.setElementAttribute(element, "title", title);
488
+ }
489
+ }
490
+
491
+ /**
492
+ * Sets whether this object is visible.
493
+ *
494
+ * @param visible <code>true</code> to show the object, <code>false</code>
495
+ * to hide it
496
+ */
497
+ public void setVisible(boolean visible) {
498
+ setVisible(element, visible);
499
+ }
500
+
501
+ /**
502
+ * Sets the object's width. This width does not include decorations such as
503
+ * border, margin, and padding.
504
+ *
505
+ * @param width the object's new width, in CSS units (e.g. "10px", "1em")
506
+ */
507
+ public void setWidth(String width) {
508
+ // This exists to deal with an inconsistency in IE's implementation where
509
+ // it won't accept negative numbers in length measurements
510
+ assert extractLengthValue(width.trim().toLowerCase()) >= 0 :
511
+ "CSS widths should not be negative";
512
+ DOM.setStyleAttribute(element, "width", width);
513
+ }
514
+
515
+ /**
516
+ * Adds a set of events to be sunk by this object. Note that only
517
+ * {@link Widget widgets} may actually receive events, but can receive events
518
+ * from all objects contained within them.
519
+ *
520
+ * @param eventBitsToAdd a bitfield representing the set of events to be added
521
+ * to this element's event set
522
+ * @see com.google.gwt.user.client.Event
523
+ */
524
+ public void sinkEvents(int eventBitsToAdd) {
525
+ DOM.sinkEvents(getElement(), eventBitsToAdd
526
+ | DOM.getEventsSunk(getElement()));
527
+ }
528
+
529
+ /**
530
+ * This method is overridden so that any object can be viewed in the debugger
531
+ * as an HTML snippet.
532
+ *
533
+ * @return a string representation of the object
534
+ */
535
+ public String toString() {
536
+ if (element == null) {
537
+ return "(null handle)";
538
+ }
539
+ return DOM.toString(element);
540
+ }
541
+
542
+ /**
543
+ * Removes a set of events from this object's event list.
544
+ *
545
+ * @param eventBitsToRemove a bitfield representing the set of events to be
546
+ * removed from this element's event set
547
+ * @see #sinkEvents
548
+ * @see com.google.gwt.user.client.Event
549
+ */
550
+ public void unsinkEvents(int eventBitsToRemove) {
551
+ DOM.sinkEvents(getElement(), DOM.getEventsSunk(getElement())
552
+ & (~eventBitsToRemove));
553
+ }
554
+
555
+ /**
556
+ * Template method that returns the element to which style names will be
557
+ * applied. By default it returns the root element, but this method may be
558
+ * overridden to apply styles to a child element.
559
+ *
560
+ * @return the element to which style names will be applied
561
+ */
562
+ protected Element getStyleElement() {
563
+ return element;
564
+ }
565
+
566
+ /**
567
+ * Sets this object's browser element. UIObject subclasses must call this
568
+ * method before attempting to call any other methods.
569
+ *
570
+ * If the browser element has already been set, then the current element's
571
+ * position is located in the DOM and removed. The new element is added into
572
+ * the previous element's position.
573
+ *
574
+ * @param elem the object's new element
575
+ */
576
+ protected void setElement(Element elem) {
577
+ if (this.element != null) {
578
+ // replace this.element in its parent with elem.
579
+ replaceNode(this.element, elem);
580
+ }
581
+
582
+ this.element = elem;
583
+
584
+ // We do not actually force the creation of a primary style name here.
585
+ // Instead, we do it lazily -- when it is aboslutely required --
586
+ // in getStyleName(), addStyleName(), and removeStyleName().
587
+ }
588
+
589
+ /**
590
+ * Intended to be used to pull the value out of a CSS length. We rely on the
591
+ * behavior of parseFloat to ignore non-numeric chars in its input. If the
592
+ * value is "auto" or "inherit", 0 will be returned.
593
+ *
594
+ * @param s The CSS length string to extract
595
+ * @return The leading numeric portion of <code>s</code>, or 0 if "auto" or
596
+ * "inherit" are passed in.
597
+ */
598
+ private native double extractLengthValue(String s) /*-{
599
+ if (s == "auto" || s == "inherit" || s == "") {
600
+ return 0;
601
+ } else {
602
+ return parseFloat(s);
603
+ }
604
+ }-*/;
605
+
606
+ private native void replaceNode(Element node, Element newNode) /*-{
607
+ var p = node.parentNode;
608
+ if (!p) {
609
+ return;
610
+ }
611
+ p.insertBefore(newNode, node);
612
+ p.removeChild(node);
613
+ }-*/;
614
+ }