+++ /dev/null
-// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL]
-package org.xwt;
-
-import java.util.*;
-import org.xwt.js.*;
-import org.xwt.util.*;
-import java.io.*;
-
-/**
- * This class encapsulates a single trap placed on a given node. The
- * traps for a given property name on a given box are maintained as a
- * linked list stack, with the most recently placed trap at the head
- * of the list.
- */
-public class Trap {
-
- // Static Data //////////////////////////////////////////////////////////////
-
- private static Function cascadeHelper = null;
- private static String cascadeHelperText =
- "return function(q) { var ret = arguments.doTrap;" +
- "if (ret != false && !arguments.didCascade) arguments.cascade = q; };";
- static {
- try {
- cascadeHelper = JS.parse("cascadeHelper", 1, new StringReader(cascadeHelperText));
- cascadeHelper = (Function)new JS.Context(cascadeHelper, null).resume();
- } catch (Exception e) {
- Log.log(Trap.class, e);
- }
- }
-
- /** List of properties that cannot be trapped */
- private static final Hash PROHIBITED = new Hash(120, 3);
-
- static {
- String[] p = new String[] {
- "shrink", "hshrink", "vshrink", "x", "y",
- "width", "height", "flex", "colspan", "rowspan", "cols",
- "rows", "align", "invisible", "absolute", "globalx",
- "globaly", "minwidth", "minheight", "height", "width",
- "maxwidth", "maxheight", "numchildren", "hpad", "vpad",
- "buffered", "cursor", "mousex", "mousey",
- "mouseinside", "thisbox", "indexof", "path", "font", "fontsize"
- };
- for(int i=0; i<p.length; i++) PROHIBITED.put(p[i], Boolean.TRUE);
- };
-
-
- // Instance Members ////////////////////////////////////////////////////////
-
- /** the box on which this trap was placed */
- private Box trapee = null;
-
- /** the function for this trap */
- Function f = null;
-
- /** the next trap down the trap stack */
- private Trap next = null;
-
- /** the property that the trap was placed on */
- private Object name = null;
-
-
- // Static Methods //////////////////////////////////////////////////////////////////////////
-
- /**
- * adds a trap.
- * @param trapee the box to place the trap on
- * @param name the name of the property to trap on
- * @param f the function to place as a trap
- */
- static void addTrap(Box trapee, Object name, Function f) {
-
- // check if this script has already placed a trap on this property
- for(Trap t = (Trap)trapee.get(name, Trap.class); t != null; t = t.next)
- if (t.f == f) return;
-
- // actually place the trap
- trapee.put2(name, Trap.class, new Trap(trapee, name.toString(), f, (Trap)trapee.get(name, Trap.class)));
- }
-
-
- /**
- * deletes a trap.
- * @param trapee the box to remove the trap from
- * @param name the name of the property to trap on
- * @param f the function to remove
- */
- static void delTrap(Box trapee, Object name, Function f) {
- Trap t = (Trap)trapee.get(name, Trap.class);
- if (t.f == f) { trapee.put2(name, Trap.class, t.next); return; }
- for(; t.next != null; t = t.next)
- if (t.next.f == f) { t.next = t.next.next; return; }
- Log.logJS("warning: tried to remove a trap that had not been placed");
- }
-
-
- // Instance Methods //////////////////////////////////////////////////////////////////////////
-
- private Trap(Box b, String n, Function f, Trap nx)
- { trapee = b; name = n; this.f = f; this.next = nx; }
-
- // Read Traps //////////////////////////////////////////////////////////////////////
-
- public Object perform() {
- if (f.getNumFormalArgs() > 0) return cascade();
- else return new JS.TailCall().set(f, new TrapArgs(this));
- }
-
- public Object cascade() {
- if (next != null) return next.perform();
- else return trapee.get(name, true);
- }
-
- // Write Traps //////////////////////////////////////////////////////////////////////
-
- public Object perform(Object val) {
- if (f.getNumFormalArgs() == 0) return cascade(val);
- else return new JS.TailCall().set(cascadeHelper, new TrapArgs(this, val));
- }
-
- public Object cascade(Object val) {
- if (next != null) return next.perform(val);
- else return trapee.put(name, val, true);
- }
-
- // Args ///////////////////////////////////////////////////////////////////////////
-
- private static class TrapArgs extends JS.Array {
- private Trap t;
- public boolean cascadeHappened = false;
- public TrapArgs(Trap t) { this.t = t; }
- public TrapArgs(Trap t, Object value) { this.t = t; addElement(value); }
-
- public Object put(Object key, Object val) {
- if (key.equals("cascade")) { cascadeHappened = true; return t.cascade(val); }
- else return super.put(key, val);
- }
-
- public Object get(Object key) {
- // common case
- if(!(key instanceof String)) return super.get(key);
- if (key.equals("trapee")) return t.trapee;
- if (key.equals("doTrap")) return new JS.TailCall().set(t.f, this);
- if (key.equals("didCascade")) return cascadeHappened ? Boolean.TRUE : Boolean.FALSE;
- if (key.equals("trapname")) return t.name;
- if (key.equals("cascade")) return t.cascade();
- if (key.equals("callee")) return t.f;
- return super.get(key);
- }
- }
-}
-