jaroslav@323
|
1 |
/**
|
jaroslav@323
|
2 |
* Back 2 Browser Bytecode Translator
|
jaroslav@323
|
3 |
* Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
|
jaroslav@323
|
4 |
*
|
jaroslav@323
|
5 |
* This program is free software: you can redistribute it and/or modify
|
jaroslav@323
|
6 |
* it under the terms of the GNU General Public License as published by
|
jaroslav@323
|
7 |
* the Free Software Foundation, version 2 of the License.
|
jaroslav@323
|
8 |
*
|
jaroslav@323
|
9 |
* This program is distributed in the hope that it will be useful,
|
jaroslav@323
|
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
jaroslav@323
|
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
jaroslav@323
|
12 |
* GNU General Public License for more details.
|
jaroslav@323
|
13 |
*
|
jaroslav@323
|
14 |
* You should have received a copy of the GNU General Public License
|
jaroslav@323
|
15 |
* along with this program. Look for COPYING file in the top folder.
|
jaroslav@323
|
16 |
* If not, see http://opensource.org/licenses/GPL-2.0.
|
jaroslav@323
|
17 |
*/
|
jaroslav@1041
|
18 |
package org.apidesign.bck2brwsr.launcher.fximpl;
|
jaroslav@323
|
19 |
|
jaroslav@360
|
20 |
import java.io.IOException;
|
jaroslav@360
|
21 |
import java.io.InputStream;
|
jaroslav@802
|
22 |
import java.io.UnsupportedEncodingException;
|
jaroslav@332
|
23 |
import java.lang.reflect.InvocationTargetException;
|
jaroslav@323
|
24 |
import java.lang.reflect.Method;
|
jaroslav@412
|
25 |
import java.lang.reflect.Modifier;
|
jaroslav@332
|
26 |
import java.net.URL;
|
jaroslav@360
|
27 |
import java.util.Enumeration;
|
jaroslav@1041
|
28 |
import javafx.scene.web.WebEngine;
|
jaroslav@1041
|
29 |
import netscape.javascript.JSObject;
|
jaroslav@323
|
30 |
|
jaroslav@323
|
31 |
/**
|
jaroslav@323
|
32 |
*
|
jaroslav@323
|
33 |
* @author Jaroslav Tulach <jtulach@netbeans.org>
|
jaroslav@323
|
34 |
*/
|
jaroslav@1041
|
35 |
public final class Console {
|
jaroslav@1041
|
36 |
public Console() {
|
jaroslav@517
|
37 |
}
|
jaroslav@323
|
38 |
|
jaroslav@1041
|
39 |
private static Object getAttr(Object elem, String attr) {
|
jaroslav@1041
|
40 |
return InvokeJS.CObject.call("getAttr", elem, attr);
|
jaroslav@1041
|
41 |
}
|
jaroslav@323
|
42 |
|
jaroslav@1041
|
43 |
private static void setAttr(String id, String attr, Object value) {
|
jaroslav@1041
|
44 |
InvokeJS.CObject.call("setAttrId", id, attr, value);
|
jaroslav@1041
|
45 |
}
|
jaroslav@1041
|
46 |
private static void setAttr(Object id, String attr, Object value) {
|
jaroslav@1041
|
47 |
InvokeJS.CObject.call("setAttr", id, attr, value);
|
jaroslav@1041
|
48 |
}
|
jaroslav@366
|
49 |
|
jaroslav@1041
|
50 |
private static void closeWindow() {}
|
jaroslav@342
|
51 |
|
jaroslav@916
|
52 |
private static Object textArea;
|
jaroslav@916
|
53 |
private static Object statusArea;
|
jaroslav@916
|
54 |
|
jaroslav@343
|
55 |
private static void log(String newText) {
|
jaroslav@916
|
56 |
if (textArea == null) {
|
jaroslav@916
|
57 |
return;
|
jaroslav@916
|
58 |
}
|
jaroslav@343
|
59 |
String attr = "value";
|
jaroslav@916
|
60 |
setAttr(textArea, attr, getAttr(textArea, attr) + "\n" + newText);
|
jaroslav@916
|
61 |
setAttr(textArea, "scrollTop", getAttr(textArea, "scrollHeight"));
|
jaroslav@342
|
62 |
}
|
jaroslav@323
|
63 |
|
jaroslav@916
|
64 |
private static void beginTest(Case c) {
|
jaroslav@916
|
65 |
Object[] arr = new Object[2];
|
jaroslav@916
|
66 |
beginTest(c.getClassName() + "." + c.getMethodName(), c, arr);
|
jaroslav@916
|
67 |
textArea = arr[0];
|
jaroslav@916
|
68 |
statusArea = arr[1];
|
jaroslav@916
|
69 |
}
|
jaroslav@916
|
70 |
|
jaroslav@916
|
71 |
private static void finishTest(Case c, Object res) {
|
jaroslav@916
|
72 |
if ("null".equals(res)) {
|
jaroslav@922
|
73 |
setAttr(statusArea, "innerHTML", "Success");
|
jaroslav@916
|
74 |
} else {
|
jaroslav@922
|
75 |
setAttr(statusArea, "innerHTML", "Result " + res);
|
jaroslav@916
|
76 |
}
|
jaroslav@916
|
77 |
statusArea = null;
|
jaroslav@916
|
78 |
textArea = null;
|
jaroslav@916
|
79 |
}
|
jaroslav@916
|
80 |
|
jaroslav@1041
|
81 |
private static final String BEGIN_TEST =
|
jaroslav@1041
|
82 |
"var ul = window.document.getElementById('bck2brwsr.result');\n"
|
jaroslav@916
|
83 |
+ "var li = window.document.createElement('li');\n"
|
jaroslav@922
|
84 |
+ "var span = window.document.createElement('span');"
|
jaroslav@916
|
85 |
+ "span.innerHTML = test + ' - ';\n"
|
jaroslav@922
|
86 |
+ "var details = window.document.createElement('a');\n"
|
jaroslav@922
|
87 |
+ "details.innerHTML = 'Details';\n"
|
jaroslav@922
|
88 |
+ "details.href = '#';\n"
|
jaroslav@916
|
89 |
+ "var p = window.document.createElement('p');\n"
|
jaroslav@916
|
90 |
+ "var status = window.document.createElement('a');\n"
|
jaroslav@916
|
91 |
+ "status.innerHTML = 'running';"
|
jaroslav@922
|
92 |
+ "details.onclick = function() { li.appendChild(p); li.removeChild(details); status.innerHTML = 'Run Again'; status.href = '#'; };\n"
|
jaroslav@1041
|
93 |
+ "status.onclick = function() { c.again(arr); }\n"
|
jaroslav@916
|
94 |
+ "var pre = window.document.createElement('textarea');\n"
|
jaroslav@922
|
95 |
+ "pre.cols = 100;"
|
jaroslav@922
|
96 |
+ "pre.rows = 10;"
|
jaroslav@916
|
97 |
+ "li.appendChild(span);\n"
|
jaroslav@916
|
98 |
+ "li.appendChild(status);\n"
|
jaroslav@922
|
99 |
+ "var span = window.document.createElement('span');"
|
jaroslav@922
|
100 |
+ "span.innerHTML = ' ';\n"
|
jaroslav@922
|
101 |
+ "li.appendChild(span);\n"
|
jaroslav@922
|
102 |
+ "li.appendChild(details);\n"
|
jaroslav@916
|
103 |
+ "p.appendChild(pre);\n"
|
jaroslav@916
|
104 |
+ "ul.appendChild(li);\n"
|
jaroslav@916
|
105 |
+ "arr[0] = pre;\n"
|
jaroslav@1041
|
106 |
+ "arr[1] = status;\n";
|
jaroslav@1041
|
107 |
|
jaroslav@1041
|
108 |
private static void beginTest(String test, Case c, Object[] arr) {
|
jaroslav@1041
|
109 |
InvokeJS.CObject.call("beginTest", test, c, arr);
|
jaroslav@1041
|
110 |
}
|
jaroslav@916
|
111 |
|
jaroslav@1041
|
112 |
private static final String LOAD_TEXT =
|
jaroslav@1041
|
113 |
"var request = new XMLHttpRequest();\n"
|
jaroslav@519
|
114 |
+ "request.open('GET', url, true);\n"
|
jaroslav@800
|
115 |
+ "request.setRequestHeader('Content-Type', 'text/plain; charset=utf-8');\n"
|
jaroslav@519
|
116 |
+ "request.onreadystatechange = function() {\n"
|
jaroslav@519
|
117 |
+ " if (this.readyState!==4) return;\n"
|
jaroslav@1041
|
118 |
+ " try {"
|
jaroslav@519
|
119 |
+ " arr[0] = this.responseText;\n"
|
jaroslav@519
|
120 |
+ " callback.run__V();\n"
|
jaroslav@1041
|
121 |
+ " } catch (e) { alert(e); }"
|
jaroslav@519
|
122 |
+ "};"
|
jaroslav@1041
|
123 |
+ "request.send();";
|
jaroslav@1041
|
124 |
private static void loadText(String url, Runnable callback, String[] arr) throws IOException {
|
jaroslav@1041
|
125 |
InvokeJS.CObject.call("loadText", url, new Run(callback), arr);
|
jaroslav@1041
|
126 |
}
|
jaroslav@332
|
127 |
|
jaroslav@1041
|
128 |
public static void runHarness(String url) throws IOException {
|
jaroslav@1041
|
129 |
new Console().harness(url);
|
jaroslav@1041
|
130 |
}
|
jaroslav@1041
|
131 |
|
jaroslav@1041
|
132 |
public void harness(String url) throws IOException {
|
jaroslav@343
|
133 |
log("Connecting to " + url);
|
jaroslav@519
|
134 |
Request r = new Request(url);
|
jaroslav@519
|
135 |
}
|
jaroslav@519
|
136 |
|
jaroslav@519
|
137 |
private static class Request implements Runnable {
|
jaroslav@519
|
138 |
private final String[] arr = { null };
|
jaroslav@519
|
139 |
private final String url;
|
jaroslav@939
|
140 |
private Case c;
|
jaroslav@942
|
141 |
private int retries;
|
jaroslav@519
|
142 |
|
jaroslav@519
|
143 |
private Request(String url) throws IOException {
|
jaroslav@519
|
144 |
this.url = url;
|
jaroslav@519
|
145 |
loadText(url, this, arr);
|
jaroslav@519
|
146 |
}
|
jaroslav@939
|
147 |
private Request(String url, String u) throws IOException {
|
jaroslav@939
|
148 |
this.url = url;
|
jaroslav@939
|
149 |
loadText(u, this, arr);
|
jaroslav@939
|
150 |
}
|
jaroslav@519
|
151 |
|
jaroslav@519
|
152 |
@Override
|
jaroslav@519
|
153 |
public void run() {
|
jaroslav@519
|
154 |
try {
|
jaroslav@939
|
155 |
if (c == null) {
|
jaroslav@939
|
156 |
String data = arr[0];
|
jaroslav@939
|
157 |
|
jaroslav@939
|
158 |
if (data == null) {
|
jaroslav@939
|
159 |
log("Some error exiting");
|
jaroslav@939
|
160 |
closeWindow();
|
jaroslav@939
|
161 |
return;
|
jaroslav@939
|
162 |
}
|
jaroslav@939
|
163 |
|
jaroslav@939
|
164 |
if (data.isEmpty()) {
|
jaroslav@939
|
165 |
log("No data, exiting");
|
jaroslav@939
|
166 |
closeWindow();
|
jaroslav@939
|
167 |
return;
|
jaroslav@939
|
168 |
}
|
jaroslav@939
|
169 |
|
jaroslav@939
|
170 |
c = Case.parseData(data);
|
jaroslav@939
|
171 |
beginTest(c);
|
jaroslav@940
|
172 |
log("Got \"" + data + "\"");
|
jaroslav@940
|
173 |
} else {
|
jaroslav@942
|
174 |
log("Processing \"" + arr[0] + "\" for " + retries + " time");
|
jaroslav@939
|
175 |
}
|
jaroslav@942
|
176 |
Object result = retries++ >= 10 ? "java.lang.InterruptedException:timeout" : c.runTest();
|
jaroslav@939
|
177 |
finishTest(c, result);
|
jaroslav@519
|
178 |
|
jaroslav@939
|
179 |
String u = url + "?request=" + c.getRequestId() + "&result=" + result;
|
jaroslav@939
|
180 |
new Request(url, u);
|
jaroslav@939
|
181 |
} catch (Exception ex) {
|
jaroslav@939
|
182 |
if (ex instanceof InterruptedException) {
|
jaroslav@940
|
183 |
log("Re-scheduling in 100ms");
|
jaroslav@940
|
184 |
schedule(this, 100);
|
jaroslav@519
|
185 |
return;
|
jaroslav@519
|
186 |
}
|
jaroslav@707
|
187 |
log(ex.getClass().getName() + ":" + ex.getMessage());
|
jaroslav@342
|
188 |
}
|
jaroslav@332
|
189 |
}
|
jaroslav@332
|
190 |
}
|
jaroslav@356
|
191 |
|
jaroslav@802
|
192 |
private static String encodeURL(String r) throws UnsupportedEncodingException {
|
jaroslav@802
|
193 |
final String SPECIAL = "%$&+,/:;=?@";
|
jaroslav@381
|
194 |
StringBuilder sb = new StringBuilder();
|
jaroslav@802
|
195 |
byte[] utf8 = r.getBytes("UTF-8");
|
jaroslav@802
|
196 |
for (int i = 0; i < utf8.length; i++) {
|
jaroslav@802
|
197 |
int ch = utf8[i] & 0xff;
|
jaroslav@802
|
198 |
if (ch < 32 || ch > 127 || SPECIAL.indexOf(ch) >= 0) {
|
jaroslav@802
|
199 |
final String numbers = "0" + Integer.toHexString(ch);
|
jaroslav@802
|
200 |
sb.append("%").append(numbers.substring(numbers.length() - 2));
|
jaroslav@381
|
201 |
} else {
|
jaroslav@381
|
202 |
if (ch == 32) {
|
jaroslav@381
|
203 |
sb.append("+");
|
jaroslav@381
|
204 |
} else {
|
jaroslav@381
|
205 |
sb.append((char)ch);
|
jaroslav@381
|
206 |
}
|
jaroslav@381
|
207 |
}
|
jaroslav@381
|
208 |
}
|
jaroslav@381
|
209 |
return sb.toString();
|
jaroslav@381
|
210 |
}
|
jaroslav@381
|
211 |
|
jaroslav@939
|
212 |
static String invoke(String clazz, String method) throws
|
jaroslav@939
|
213 |
ClassNotFoundException, InvocationTargetException, IllegalAccessException,
|
jaroslav@939
|
214 |
InstantiationException, InterruptedException {
|
jaroslav@939
|
215 |
final Object r = new Case(null).invokeMethod(clazz, method);
|
jaroslav@356
|
216 |
return r == null ? "null" : r.toString().toString();
|
jaroslav@356
|
217 |
}
|
jaroslav@323
|
218 |
|
jaroslav@360
|
219 |
/** Helper method that inspects the classpath and loads given resource
|
jaroslav@360
|
220 |
* (usually a class file). Used while running tests in Rhino.
|
jaroslav@360
|
221 |
*
|
jaroslav@360
|
222 |
* @param name resource name to find
|
jaroslav@360
|
223 |
* @return the array of bytes in the given resource
|
jaroslav@360
|
224 |
* @throws IOException I/O in case something goes wrong
|
jaroslav@360
|
225 |
*/
|
jaroslav@360
|
226 |
public static byte[] read(String name) throws IOException {
|
jaroslav@360
|
227 |
URL u = null;
|
jaroslav@360
|
228 |
Enumeration<URL> en = Console.class.getClassLoader().getResources(name);
|
jaroslav@360
|
229 |
while (en.hasMoreElements()) {
|
jaroslav@360
|
230 |
u = en.nextElement();
|
jaroslav@360
|
231 |
}
|
jaroslav@360
|
232 |
if (u == null) {
|
jaroslav@360
|
233 |
throw new IOException("Can't find " + name);
|
jaroslav@360
|
234 |
}
|
jaroslav@360
|
235 |
try (InputStream is = u.openStream()) {
|
jaroslav@360
|
236 |
byte[] arr;
|
jaroslav@360
|
237 |
arr = new byte[is.available()];
|
jaroslav@360
|
238 |
int offset = 0;
|
jaroslav@360
|
239 |
while (offset < arr.length) {
|
jaroslav@360
|
240 |
int len = is.read(arr, offset, arr.length - offset);
|
jaroslav@360
|
241 |
if (len == -1) {
|
jaroslav@360
|
242 |
throw new IOException("Can't read " + name);
|
jaroslav@360
|
243 |
}
|
jaroslav@360
|
244 |
offset += len;
|
jaroslav@360
|
245 |
}
|
jaroslav@360
|
246 |
return arr;
|
jaroslav@360
|
247 |
}
|
jaroslav@360
|
248 |
}
|
jaroslav@360
|
249 |
|
jaroslav@517
|
250 |
private static void turnAssetionStatusOn() {
|
jaroslav@517
|
251 |
}
|
jaroslav@939
|
252 |
|
jaroslav@1041
|
253 |
private static Object schedule(Runnable r, int time) {
|
jaroslav@1041
|
254 |
return InvokeJS.CObject.call("schedule", new Run(r), time);
|
jaroslav@1041
|
255 |
}
|
jaroslav@342
|
256 |
|
jaroslav@342
|
257 |
private static final class Case {
|
jaroslav@342
|
258 |
private final Object data;
|
jaroslav@939
|
259 |
private Object inst;
|
jaroslav@342
|
260 |
|
jaroslav@342
|
261 |
private Case(Object data) {
|
jaroslav@342
|
262 |
this.data = data;
|
jaroslav@342
|
263 |
}
|
jaroslav@342
|
264 |
|
jaroslav@342
|
265 |
public static Case parseData(String s) {
|
jaroslav@342
|
266 |
return new Case(toJSON(s));
|
jaroslav@342
|
267 |
}
|
jaroslav@342
|
268 |
|
jaroslav@342
|
269 |
public String getMethodName() {
|
jaroslav@1041
|
270 |
return (String) value("methodName", data);
|
jaroslav@342
|
271 |
}
|
jaroslav@342
|
272 |
|
jaroslav@342
|
273 |
public String getClassName() {
|
jaroslav@1041
|
274 |
return (String) value("className", data);
|
jaroslav@342
|
275 |
}
|
jaroslav@342
|
276 |
|
jaroslav@1041
|
277 |
public int getRequestId() {
|
jaroslav@1041
|
278 |
Object v = value("request", data);
|
jaroslav@1041
|
279 |
if (v instanceof Number) {
|
jaroslav@1041
|
280 |
return ((Number)v).intValue();
|
jaroslav@1041
|
281 |
}
|
jaroslav@1041
|
282 |
return Integer.parseInt(v.toString());
|
jaroslav@342
|
283 |
}
|
jaroslav@526
|
284 |
|
jaroslav@526
|
285 |
public String getHtmlFragment() {
|
jaroslav@1041
|
286 |
return (String) value("html", data);
|
jaroslav@526
|
287 |
}
|
jaroslav@342
|
288 |
|
jaroslav@916
|
289 |
void again(Object[] arr) {
|
jaroslav@916
|
290 |
try {
|
jaroslav@916
|
291 |
textArea = arr[0];
|
jaroslav@916
|
292 |
statusArea = arr[1];
|
jaroslav@916
|
293 |
setAttr(textArea, "value", "");
|
jaroslav@916
|
294 |
runTest();
|
jaroslav@916
|
295 |
} catch (Exception ex) {
|
jaroslav@916
|
296 |
log(ex.getClass().getName() + ":" + ex.getMessage());
|
jaroslav@916
|
297 |
}
|
jaroslav@916
|
298 |
}
|
jaroslav@916
|
299 |
|
jaroslav@939
|
300 |
private Object runTest() throws IllegalAccessException,
|
jaroslav@939
|
301 |
IllegalArgumentException, ClassNotFoundException, UnsupportedEncodingException,
|
jaroslav@939
|
302 |
InvocationTargetException, InstantiationException, InterruptedException {
|
jaroslav@916
|
303 |
if (this.getHtmlFragment() != null) {
|
jaroslav@916
|
304 |
setAttr("bck2brwsr.fragment", "innerHTML", this.getHtmlFragment());
|
jaroslav@916
|
305 |
}
|
jaroslav@916
|
306 |
log("Invoking " + this.getClassName() + '.' + this.getMethodName() + " as request: " + this.getRequestId());
|
jaroslav@916
|
307 |
Object result = invokeMethod(this.getClassName(), this.getMethodName());
|
jaroslav@916
|
308 |
setAttr("bck2brwsr.fragment", "innerHTML", "");
|
jaroslav@916
|
309 |
log("Result: " + result);
|
jaroslav@916
|
310 |
result = encodeURL("" + result);
|
jaroslav@916
|
311 |
log("Sending back: ...?request=" + this.getRequestId() + "&result=" + result);
|
jaroslav@916
|
312 |
return result;
|
jaroslav@916
|
313 |
}
|
jaroslav@939
|
314 |
|
jaroslav@939
|
315 |
private Object invokeMethod(String clazz, String method)
|
jaroslav@939
|
316 |
throws ClassNotFoundException, InvocationTargetException,
|
jaroslav@939
|
317 |
InterruptedException, IllegalAccessException, IllegalArgumentException,
|
jaroslav@939
|
318 |
InstantiationException {
|
jaroslav@939
|
319 |
Method found = null;
|
jaroslav@939
|
320 |
Class<?> c = Class.forName(clazz);
|
jaroslav@939
|
321 |
for (Method m : c.getMethods()) {
|
jaroslav@939
|
322 |
if (m.getName().equals(method)) {
|
jaroslav@939
|
323 |
found = m;
|
jaroslav@939
|
324 |
}
|
jaroslav@939
|
325 |
}
|
jaroslav@939
|
326 |
Object res;
|
jaroslav@939
|
327 |
if (found != null) {
|
jaroslav@939
|
328 |
try {
|
jaroslav@939
|
329 |
if ((found.getModifiers() & Modifier.STATIC) != 0) {
|
jaroslav@939
|
330 |
res = found.invoke(null);
|
jaroslav@939
|
331 |
} else {
|
jaroslav@939
|
332 |
if (inst == null) {
|
jaroslav@939
|
333 |
inst = c.newInstance();
|
jaroslav@939
|
334 |
}
|
jaroslav@939
|
335 |
res = found.invoke(inst);
|
jaroslav@939
|
336 |
}
|
jaroslav@939
|
337 |
} catch (Throwable ex) {
|
jaroslav@939
|
338 |
if (ex instanceof InvocationTargetException) {
|
jaroslav@939
|
339 |
ex = ((InvocationTargetException) ex).getTargetException();
|
jaroslav@939
|
340 |
}
|
jaroslav@939
|
341 |
if (ex instanceof InterruptedException) {
|
jaroslav@939
|
342 |
throw (InterruptedException)ex;
|
jaroslav@939
|
343 |
}
|
jaroslav@939
|
344 |
res = ex.getClass().getName() + ":" + ex.getMessage();
|
jaroslav@939
|
345 |
}
|
jaroslav@939
|
346 |
} else {
|
jaroslav@939
|
347 |
res = "Can't find method " + method + " in " + clazz;
|
jaroslav@939
|
348 |
}
|
jaroslav@939
|
349 |
return res;
|
jaroslav@939
|
350 |
}
|
jaroslav@916
|
351 |
|
jaroslav@1041
|
352 |
private static Object toJSON(String s) {
|
jaroslav@1041
|
353 |
return InvokeJS.CObject.call("toJSON", s);
|
jaroslav@1041
|
354 |
}
|
jaroslav@342
|
355 |
|
jaroslav@1041
|
356 |
private static Object value(String p, Object d) {
|
jaroslav@1041
|
357 |
return ((JSObject)d).getMember(p);
|
jaroslav@1041
|
358 |
}
|
jaroslav@342
|
359 |
}
|
jaroslav@1041
|
360 |
|
jaroslav@1041
|
361 |
private static String safe(String txt) {
|
jaroslav@1041
|
362 |
return "try {" + txt + "} catch (err) { alert(err); }";
|
jaroslav@1041
|
363 |
}
|
jaroslav@1041
|
364 |
|
jaroslav@1041
|
365 |
static {
|
jaroslav@1041
|
366 |
turnAssetionStatusOn();
|
jaroslav@1041
|
367 |
}
|
jaroslav@1041
|
368 |
|
jaroslav@1041
|
369 |
private static final class InvokeJS {
|
jaroslav@1041
|
370 |
static final JSObject CObject = initJS();
|
jaroslav@1041
|
371 |
|
jaroslav@1041
|
372 |
private static JSObject initJS() {
|
jaroslav@1041
|
373 |
WebEngine web = (WebEngine) System.getProperties().get("webEngine");
|
jaroslav@1041
|
374 |
return (JSObject) web.executeScript("(function() {"
|
jaroslav@1041
|
375 |
+ "var CObject = {};"
|
jaroslav@1041
|
376 |
|
jaroslav@1041
|
377 |
+ "CObject.getAttr = function(elem, attr) { return elem[attr].toString(); };"
|
jaroslav@1041
|
378 |
|
jaroslav@1041
|
379 |
+ "CObject.setAttrId = function(id, attr, value) { window.document.getElementById(id)[attr] = value; };"
|
jaroslav@1041
|
380 |
+ "CObject.setAttr = function(elem, attr, value) { elem[attr] = value; };"
|
jaroslav@1041
|
381 |
|
jaroslav@1041
|
382 |
+ "CObject.beginTest = function(test, c, arr) {" + safe(BEGIN_TEST) + "};"
|
jaroslav@1041
|
383 |
|
jaroslav@1041
|
384 |
+ "CObject.loadText = function(url, callback, arr) {" + safe(LOAD_TEXT.replace("run__V", "run")) + "};"
|
jaroslav@1041
|
385 |
|
jaroslav@1041
|
386 |
+ "CObject.schedule = function(r, time) { return window.setTimeout(function() { r.run(); }, time); };"
|
jaroslav@1041
|
387 |
|
jaroslav@1041
|
388 |
+ "CObject.toJSON = function(s) { return eval('(' + s + ')'); };"
|
jaroslav@1041
|
389 |
|
jaroslav@1041
|
390 |
+ "return CObject;"
|
jaroslav@1041
|
391 |
+ "})(this)");
|
jaroslav@1041
|
392 |
}
|
jaroslav@1041
|
393 |
}
|
jaroslav@1041
|
394 |
|
jaroslav@323
|
395 |
}
|