diff options
Diffstat (limited to 'khtml/java/org/kde/javascript/JSObject.java')
-rw-r--r-- | khtml/java/org/kde/javascript/JSObject.java | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/khtml/java/org/kde/javascript/JSObject.java b/khtml/java/org/kde/javascript/JSObject.java new file mode 100644 index 000000000..11e7f9f99 --- /dev/null +++ b/khtml/java/org/kde/javascript/JSObject.java @@ -0,0 +1,183 @@ +package org.kde.javascript; + +import java.applet.Applet; +import org.kde.kjas.server.KJASAppletContext; +import org.kde.kjas.server.Main; + +public class JSObject extends netscape.javascript.JSObject { + public String returnvalue = null; + public Thread thread; + + private String jsobject; + private int id; + private Applet applet; + private String appletID = null; + + /* JavaScript code: + * __lc=[[JS objects],call func(index,script,appletname,isglobal)] + */ + private final static String decls = "if(!window.__lc) window.__lc=[[window],function(i,s,a,g){var v;var len=window.__lc[0].length;if(i>=len)v='E unknown object';else{var r;try{r=eval((g?'':'window.__lc[0][i]')+s);}catch(e){v='E '+e;r='E ';}finally{var t=typeof r;if(t=='undefined')v='V ';else if(t=='number')v='N '+r;else if(t=='string'){if(r!='E ')v='S '+r;}else{window.__lc[0][len]=r;v=''+len+' '+(r==window.__lc?'[array]':r);}}}a.__lc_ret=v},0]"; + + public JSObject(Applet a, String name, int _id) { + Main.info("JSObject.ctor: " + name); + jsobject = new String(name); + applet = a; + id = _id; + KJASAppletContext kc = (KJASAppletContext)applet.getAppletContext(); + appletID = kc.getAppletID(a); + if (id == 0) { + kc.evaluateJavaScript(decls, appletID, null); + } + } + + int getId() { + return id; + } + + private String escapeString(String string) { + StringBuffer sb = new StringBuffer(); + int idx = 0; + boolean cr = false; + char [] chars = string.toCharArray(); + while (idx < chars.length) { + if (cr && chars[idx] != '\n') { + cr = false; + sb.append("\\n"); + } + switch (chars[idx]) { + case '\\': + sb.append("\\\\"); + break; + case '"': + sb.append("\\\""); + break; + case '\n': + cr = false; + sb.append("\\n"); + break; + case '\r': + cr = true; + break; + default: + sb.append(chars[idx]); + } + idx++; + } + if (cr) + sb.append("\\n"); + return sb.toString(); + } + + private Object evaluate(String script, boolean global) throws netscape.javascript.JSException { + Main.info("evaluate (\"" + script + "\")"); + + KJASAppletContext kc = (KJASAppletContext) applet.getAppletContext(); + //String appletname = kc.getAppletName(appletID); + thread = Thread.currentThread(); + + if (!kc.evaluateJavaScript("window.__lc[1](" + id + ",\"" + escapeString(script) + "\",this" + (global ? ",true)" : ")"), appletID, this)) { + Main.debug("evaluate on not active applet"); + return null; + } + boolean timedout = true; + try { + Thread.sleep(30000); + } catch (InterruptedException ex) { + timedout = false; + } + thread = null; + if (timedout || returnvalue == null) + return null; + + /* lets see what we've got */ + String retval = returnvalue; + int pos = retval.indexOf(' '); + String type = retval.substring(0, pos); + if (type.equals("V")) // Void + return null; + String value = retval.substring(pos+1); + if (type.equals("E")) // Error + throw new netscape.javascript.JSException("Script error: " + value); + Main.info("value=" + value + " (type=" + type + ")"); + if (type.equals("N")) // Number + return new Double(value); + if (type.equals("S")) // String + return value; + + /* Is it an applet? */ + if (value.startsWith("[object APPLET ref=")) { + int p1 = value.indexOf('='); + int p2 = value.indexOf(']', p1+1); + int applethashcode = Integer.parseInt(value.substring(p1+1, p2)); + java.util.Enumeration e = kc.getApplets(); + while (e.hasMoreElements()) { + Applet app = (Applet) e.nextElement(); + if (app.hashCode() == applethashcode) + return app; + } + return null; + } + /* Is it a Java object then? */ + if (value.startsWith("[object ") && value.indexOf("ref=") > 0) { + int p1 = value.indexOf("ref="); + int p2 = value.indexOf(']', p1+4); + int objecthashcode = Integer.parseInt(value.substring(p1+4, p2)); + return kc.getJSReferencedObject(applet, objecthashcode); + } + /* Ok, make it a JSObject */ + return new JSObject(applet, value, Integer.parseInt(type)); + } + private String convertValueJ2JS(Object o) { + if (o == null) + return new String("null"); + if (o instanceof java.lang.Number || o instanceof java.lang.Boolean) + return o.toString(); + if (o instanceof netscape.javascript.JSObject) + return new String("window.__lc[0][" + ((JSObject)o).getId() + "]"); + return new String("\"" + escapeString(o.toString()) + "\""); + } + public Object call(String func, Object [] args) throws netscape.javascript.JSException { + Main.info("JSObject.call: " + jsobject + "." + func); + String script = new String("." + func + "("); + for (int i = 0; args != null && i < args.length; i++) + script += (i > 0 ? "," : "") + convertValueJ2JS(args[i]); + script += ")"; + return evaluate(script, false); + } + public Object eval(String s) throws netscape.javascript.JSException { + return evaluate(s, true); + } + public boolean equals(Object obj) { + Main.info("JSObject.equals"); + return super.equals(obj); + } + public Object getMember(String name) throws netscape.javascript.JSException { + Main.info("JSObject.getMember: " + jsobject + "." + name); + return evaluate("." + name, false); + } + public void setMember(String name, java.lang.Object o) throws netscape.javascript.JSException { + Main.info("JSObject.setMember: " + jsobject + "." + name); + evaluate("." + name + "=" + convertValueJ2JS(o), false); + } + public void removeMember(String name) throws netscape.javascript.JSException { + Main.info("JSObject.removeMember: " + jsobject + "." + name); + evaluate("." + name + "=null", false); + } + /* get array element; JS: this[index] */ + public Object getSlot(int index)throws netscape.javascript.JSException { + Main.info("JSObject.getSlot: " + jsobject + "[" + index + "]"); + return evaluate("[" + index + "]", false); + } + public void setSlot(int index, Object o) throws netscape.javascript.JSException { + Main.info("JSObject.setSlot: " + jsobject + "[" + index + "]"); + evaluate("[" + index + "]=" + convertValueJ2JS(o), false); + } + public String toString(){ + Main.info("JSObject.toString: " + jsobject); + return new String(jsobject); + } + public static JSObject getWindow(Applet a, int dummy) { + Main.info("JSObject.getWindow"); + return new JSObject(a, "[WINDOW]", 0); + } +} |