1 18 package org.apache.batik.script.rhino; 19 20 import java.lang.ref.SoftReference ; 21 import java.lang.reflect.Method ; 22 import java.util.Map ; 23 import java.util.HashMap ; 24 import java.util.WeakHashMap ; 25 26 import org.mozilla.javascript.Context; 27 import org.mozilla.javascript.Function; 28 import org.mozilla.javascript.JavaScriptException; 29 import org.mozilla.javascript.NativeJavaObject; 30 import org.mozilla.javascript.NativeObject; 31 import org.mozilla.javascript.Scriptable; 32 import org.mozilla.javascript.ScriptableObject; 33 import org.mozilla.javascript.Undefined; 34 import org.mozilla.javascript.WrappedException; 35 import org.w3c.dom.events.Event ; 36 import org.w3c.dom.events.EventListener ; 37 import org.w3c.dom.events.EventTarget ; 38 39 51 class EventTargetWrapper extends NativeJavaObject { 52 53 56 static class FunctionEventListener implements EventListener { 57 private Function function; 58 private RhinoInterpreter interpreter; 59 FunctionEventListener(Function f, RhinoInterpreter i) { 60 function = f; 61 interpreter = i; 62 } 63 public void handleEvent(Event evt) { 64 try { 65 interpreter.callHandler(function, evt); 66 } catch (JavaScriptException e) { 67 throw new WrappedException(e); 72 } 73 } 74 } 75 76 static class HandleEventListener implements EventListener { 77 private final static String HANDLE_EVENT = "handleEvent"; 78 79 private Scriptable scriptable; 80 private Object [] array = new Object [1]; 81 private RhinoInterpreter interpreter; 82 83 HandleEventListener(Scriptable s, RhinoInterpreter interpreter) { 84 scriptable = s; 85 this.interpreter = interpreter; 86 } 87 public void handleEvent(Event evt) { 88 try { 89 array[0] = evt; 90 interpreter.enterContext(); 91 ScriptableObject.callMethod(scriptable, HANDLE_EVENT, array); 92 } catch (JavaScriptException e) { 93 throw new WrappedException(e); 98 } finally { 99 Context.exit(); 100 } 101 } 102 } 103 104 static abstract class FunctionProxy implements Function { 105 protected Function delegate; 106 107 public FunctionProxy(Function delegate) { 108 this.delegate = delegate; 109 } 110 111 public Scriptable construct(Context cx, 112 Scriptable scope, Object [] args) 113 throws JavaScriptException { 114 return this.delegate.construct(cx, scope, args); 115 } 116 117 public String getClassName() { 118 return this.delegate.getClassName(); 119 } 120 121 public Object get(String name, Scriptable start) { 122 return this.delegate.get(name, start); 123 } 124 125 public Object get(int index, Scriptable start) { 126 return this.delegate.get(index, start); 127 } 128 129 public boolean has(String name, Scriptable start) { 130 return this.delegate.has(name, start); 131 } 132 133 public boolean has(int index, Scriptable start) { 134 return this.delegate.has(index, start); 135 } 136 137 public void put(String name, Scriptable start, Object value) { 138 this.delegate.put(name, start, value); 139 } 140 141 public void put(int index, Scriptable start, Object value) { 142 this.delegate.put(index, start, value); 143 } 144 145 public void delete(String name) { 146 this.delegate.delete(name); 147 } 148 149 public void delete(int index) { 150 this.delegate.delete(index); 151 } 152 153 public Scriptable getPrototype() { 154 return this.delegate.getPrototype(); 155 } 156 157 public void setPrototype(Scriptable prototype) { 158 this.delegate.setPrototype(prototype); 159 } 160 161 public Scriptable getParentScope() { 162 return this.delegate.getParentScope(); 163 } 164 165 public void setParentScope(Scriptable parent) { 166 this.delegate.setParentScope(parent); 167 } 168 169 public Object [] getIds() { 170 return this.delegate.getIds(); 171 } 172 173 public Object getDefaultValue(Class hint) { 174 return this.delegate.getDefaultValue(hint); 175 } 176 177 public boolean hasInstance(Scriptable instance) { 178 return this.delegate.hasInstance(instance); 179 } 180 } 181 182 191 static class FunctionAddProxy extends FunctionProxy { 192 private Map listenerMap; 193 194 FunctionAddProxy(Function delegate, Map listenerMap) { 195 super(delegate); 196 this.listenerMap = listenerMap; 197 } 198 199 public Object call(Context ctx, Scriptable scope, 200 Scriptable thisObj, Object [] args) 201 throws JavaScriptException { 202 NativeJavaObject njo = (NativeJavaObject)thisObj; 203 if (args[1] instanceof Function) { 204 EventListener evtListener = new FunctionEventListener 205 ((Function)args[1], 206 ((RhinoInterpreter.ExtendedContext)ctx).getInterpreter()); 207 listenerMap.put(args[1], new SoftReference (evtListener)); 208 Class [] paramTypes = { String .class, Function.class, 210 Boolean.TYPE }; 211 for (int i = 0; i < args.length; i++) 212 args[i] = Context.toType(args[i], paramTypes[i]); 213 ((EventTarget )njo.unwrap()).addEventListener 214 ((String )args[0], evtListener, 215 ((Boolean )args[2]).booleanValue()); 216 return Undefined.instance; 217 } 218 if (args[1] instanceof NativeObject) { 219 EventListener evtListener = 220 new HandleEventListener((Scriptable)args[1], 221 ((RhinoInterpreter.ExtendedContext) 222 ctx).getInterpreter()); 223 listenerMap.put(args[1], new SoftReference (evtListener)); 224 Class [] paramTypes = { String .class, Scriptable.class, 226 Boolean.TYPE }; 227 for (int i = 0; i < args.length; i++) 228 args[i] = Context.toType(args[i], paramTypes[i]); 229 ((EventTarget )njo.unwrap()).addEventListener 230 ((String )args[0], evtListener, 231 ((Boolean )args[2]).booleanValue()); 232 return Undefined.instance; 233 } 234 return delegate.call(ctx, scope, thisObj, args); 235 } 236 } 237 238 static class FunctionRemoveProxy extends FunctionProxy { 239 private Map listenerMap; 240 241 FunctionRemoveProxy(Function delegate, Map listenerMap) { 242 super(delegate); 243 this.listenerMap = listenerMap; 244 } 245 246 public Object call(Context ctx, Scriptable scope, 247 Scriptable thisObj, Object [] args) 248 throws JavaScriptException { 249 NativeJavaObject njo = (NativeJavaObject)thisObj; 250 if (args[1] instanceof Function) { 251 SoftReference sr = (SoftReference )listenerMap.get(args[1]); 252 if (sr == null) 253 return Undefined.instance; 254 EventListener el = (EventListener )sr.get(); 255 if (el == null) 256 return Undefined.instance; 257 Class [] paramTypes = { String .class, Function.class, 259 Boolean.TYPE }; 260 for (int i = 0; i < args.length; i++) 261 args[i] = Context.toType(args[i], paramTypes[i]); 262 ((EventTarget )njo.unwrap()).removeEventListener 263 ((String )args[0], el, ((Boolean )args[2]).booleanValue()); 264 return Undefined.instance; 265 } 266 if (args[1] instanceof NativeObject) { 267 SoftReference sr = (SoftReference )listenerMap.get(args[1]); 268 if (sr == null) 269 return Undefined.instance; 270 EventListener el = (EventListener )sr.get(); 271 if (el == null) 272 return Undefined.instance; 273 Class [] paramTypes = { String .class, Scriptable.class, 275 Boolean.TYPE }; 276 for (int i = 0; i < args.length; i++) 277 args[i] = Context.toType(args[i], paramTypes[i]); 278 279 ((EventTarget )njo.unwrap()).removeEventListener 280 ((String )args[0], el, ((Boolean )args[2]).booleanValue()); 281 return Undefined.instance; 282 } 283 return delegate.call(ctx, scope, thisObj, args); 284 } 285 } 286 287 private static WeakHashMap mapOfListenerMap; 292 293 private final static String ADD_NAME = "addEventListener"; 294 private final static String REMOVE_NAME = "removeEventListener"; 295 private final static Class [] ARGS_TYPE = { String .class, 296 EventListener .class, 297 Boolean.TYPE }; 298 private final static String NAME = "name"; 299 300 EventTargetWrapper(Scriptable scope, EventTarget object) { 301 super(scope, object, null); 302 } 303 304 307 public Object get(String name, Scriptable start) { 308 Object method = super.get(name, start); 309 if (name.equals(ADD_NAME)) { 310 method = new FunctionAddProxy((Function)method, initMap()); 313 } 314 if (name.equals(REMOVE_NAME)) { 315 method = new FunctionRemoveProxy((Function)method, initMap()); 318 } 319 return method; 320 } 321 322 public Map initMap() { 326 Map map = null; 327 if (mapOfListenerMap == null) 328 mapOfListenerMap = new WeakHashMap (10); 329 if ((map = (Map )mapOfListenerMap.get(unwrap())) == null) { 330 mapOfListenerMap.put(unwrap(), map = new WeakHashMap (2)); 331 } 332 return map; 333 } 334 } 335 | Popular Tags |