You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-commits@xmlgraphics.apache.org by ca...@apache.org on 2005/09/13 15:31:09 UTC

svn commit: r280553 [5/9] - in /xmlgraphics/batik/trunk: ./ resources/org/apache/batik/apps/svgbrowser/resources/ sources/org/apache/batik/bridge/ sources/org/apache/batik/bridge/svg12/ sources/org/apache/batik/css/engine/ sources/org/apache/batik/dom/...

Added: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12BridgeEventSupport.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12BridgeEventSupport.java?rev=280553&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12BridgeEventSupport.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12BridgeEventSupport.java Tue Sep 13 06:29:29 2005
@@ -0,0 +1,789 @@
+/*
+
+   Copyright 2005  The Apache Software Foundation 
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.batik.bridge.svg12;
+
+import java.awt.Point;
+import java.awt.event.KeyEvent;
+import java.awt.geom.Point2D;
+
+import org.apache.batik.bridge.BridgeContext;
+import org.apache.batik.bridge.BridgeEventSupport;
+import org.apache.batik.bridge.FocusManager;
+import org.apache.batik.bridge.UserAgent;
+import org.apache.batik.dom.events.AbstractEvent;
+import org.apache.batik.dom.events.DOMKeyboardEvent;
+import org.apache.batik.dom.events.DOMMouseEvent;
+import org.apache.batik.dom.events.DOMTextEvent;
+import org.apache.batik.dom.events.NodeEventTarget;
+import org.apache.batik.dom.svg12.SVGOMWheelEvent;
+import org.apache.batik.dom.util.DOMUtilities;
+import org.apache.batik.gvt.GraphicsNode;
+import org.apache.batik.gvt.event.EventDispatcher;
+import org.apache.batik.gvt.event.GraphicsNodeKeyEvent;
+import org.apache.batik.gvt.event.GraphicsNodeMouseEvent;
+import org.apache.batik.gvt.event.GraphicsNodeMouseWheelEvent;
+import org.apache.batik.gvt.event.GraphicsNodeMouseWheelListener;
+import org.apache.batik.util.XMLConstants;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.events.DocumentEvent;
+import org.w3c.dom.events.EventListener;
+import org.w3c.dom.events.EventTarget;
+
+/**
+ * This class is responsible for tracking GraphicsNodeMouseEvents and
+ * forwarding them to the DOM as regular DOM MouseEvents.  This SVG 1.2
+ * specific class handles DOM Level 3 keyboard events and also ensures
+ * that mouse events under sXBL have appropriate bubble limits.
+ *
+ * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
+ * @version $Id$
+ */
+public abstract class SVG12BridgeEventSupport extends BridgeEventSupport {
+
+    /**
+     * Is called only for the root element in order to dispatch GVT
+     * events to the DOM.
+     */
+    public static void addGVTListener(BridgeContext ctx, Document doc) {
+        UserAgent ua = ctx.getUserAgent();
+        if (ua != null) {
+            EventDispatcher dispatcher = ua.getEventDispatcher();
+            if (dispatcher != null) {
+                final Listener listener = new Listener(ctx, ua);
+                dispatcher.addGraphicsNodeMouseListener(listener);
+                dispatcher.addGraphicsNodeMouseWheelListener(listener);
+                dispatcher.addGraphicsNodeKeyListener(listener);
+                // add an unload listener on the SVGDocument to remove
+                // that listener for dispatching events
+                EventListener l = new GVTUnloadListener(dispatcher, listener);
+                NodeEventTarget target = (NodeEventTarget) doc;
+                target.addEventListenerNS
+                    (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+                     "SVGUnload",
+                     l, false, null);
+                storeEventListenerNS
+                    (ctx, target,
+                     XMLConstants.XML_EVENTS_NAMESPACE_URI,
+                     "SVGUnload",
+                     l, false);
+            }
+        }
+    }
+
+    /**
+     * A GraphicsNodeMouseListener that dispatch DOM events accordingly.
+     */
+    protected static class Listener
+            extends BridgeEventSupport.Listener 
+            implements GraphicsNodeMouseWheelListener {
+
+        public Listener(BridgeContext ctx, UserAgent u) {
+            super(ctx, u);
+        }
+
+        // Key -------------------------------------------------------------
+
+        /**
+         * Invoked when a key has been pressed.
+         * @param evt the graphics node key event
+         */
+        public void keyPressed(GraphicsNodeKeyEvent evt) {
+            // XXX isDown is not preventing key repeats
+            if (!isDown) {
+                isDown = true;
+                dispatchKeyboardEvent("keydown", evt);
+            }
+            if (evt.getKeyChar() == KeyEvent.CHAR_UNDEFINED) {
+                // We will not get a KEY_TYPED event for this char
+                // so generate a keypress event here.
+                dispatchTextEvent(evt);
+            }
+        }
+
+        /**
+         * Invoked when a key has been released.
+         * @param evt the graphics node key event
+         */
+        public void keyReleased(GraphicsNodeKeyEvent evt) {
+            dispatchKeyboardEvent("keyup", evt);
+            isDown = false;
+        }
+
+        /**
+         * Invoked when a key has been typed.
+         * @param evt the graphics node key event
+         */
+        public void keyTyped(GraphicsNodeKeyEvent evt) {
+            dispatchTextEvent(evt);
+        }
+
+        /**
+         * Dispatch a DOM 3 Keyboard event.
+         */
+        protected void dispatchKeyboardEvent(String eventType,
+                                             GraphicsNodeKeyEvent evt) {
+            FocusManager fmgr = context.getFocusManager();
+            if (fmgr == null) {
+                return;
+            }
+
+            Element targetElement = (Element) fmgr.getCurrentEventTarget();
+            if (targetElement == null) {
+                return;
+            }
+            DocumentEvent d = (DocumentEvent) targetElement.getOwnerDocument();
+            DOMKeyboardEvent keyEvt
+                = (DOMKeyboardEvent) d.createEvent("KeyboardEvent");
+            String modifiers
+                = DOMUtilities.getModifiersList(evt.getLockState(),
+                                                evt.getModifiers());
+            keyEvt.initKeyboardEventNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
+                                       eventType, 
+                                       true,
+                                       true,
+                                       null,
+                                       mapKeyCodeToIdentifier(evt.getKeyCode()),
+                                       mapKeyLocation(evt.getKeyLocation()),
+                                       modifiers);
+
+            try {
+                ((EventTarget)targetElement).dispatchEvent(keyEvt);
+            } catch (RuntimeException e) {
+                ua.displayError(e);
+            }
+        }
+
+        /**
+         * Dispatch a DOM 3 Text event.
+         */
+        protected void dispatchTextEvent(GraphicsNodeKeyEvent evt) {
+            FocusManager fmgr = context.getFocusManager();
+            if (fmgr == null) {
+                return;
+            }
+
+            Element targetElement = (Element) fmgr.getCurrentEventTarget();
+            if (targetElement == null) {
+                return;
+            }
+            DocumentEvent d = (DocumentEvent) targetElement.getOwnerDocument();
+            DOMTextEvent textEvt = (DOMTextEvent) d.createEvent("TextEvent");
+            textEvt.initTextEventNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
+                                    "textInput", 
+                                    true,
+                                    true,
+                                    null,
+                                    String.valueOf(evt.getKeyChar()));
+
+            try {
+                ((EventTarget) targetElement).dispatchEvent(textEvt);
+            } catch (RuntimeException e) {
+                ua.displayError(e);
+            }
+        }
+
+        /**
+         * Maps Java KeyEvent location numbers to DOM 3 location numbers.
+         */
+        protected int mapKeyLocation(int location) {
+            return location - 1;
+        }
+
+        /**
+         * Array to hold the map of Java keycodes to DOM 3 key strings.
+         */
+        protected static String[][] IDENTIFIER_KEY_CODES = new String[256][];
+        static {
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_0,
+                                 KeyEvent.VK_0);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_1,
+                                 KeyEvent.VK_1);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_2,
+                                 KeyEvent.VK_2);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_3,
+                                 KeyEvent.VK_3);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_4,
+                                 KeyEvent.VK_4);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_5,
+                                 KeyEvent.VK_5);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_6,
+                                 KeyEvent.VK_6);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_7,
+                                 KeyEvent.VK_7);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_8,
+                                 KeyEvent.VK_8);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_9,
+                                 KeyEvent.VK_9);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_ACCEPT,
+                                 KeyEvent.VK_ACCEPT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_AGAIN,
+                                 KeyEvent.VK_AGAIN);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_A,
+                                 KeyEvent.VK_A);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_ALL_CANDIDATES,
+                                 KeyEvent.VK_ALL_CANDIDATES);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_ALPHANUMERIC,
+                                 KeyEvent.VK_ALPHANUMERIC);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_ALT_GRAPH,
+                                 KeyEvent.VK_ALT_GRAPH);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_ALT,
+                                 KeyEvent.VK_ALT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_AMPERSAND,
+                                 KeyEvent.VK_AMPERSAND);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_APOSTROPHE,
+                                 KeyEvent.VK_QUOTE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_ASTERISK,
+                                 KeyEvent.VK_ASTERISK);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_AT,
+                                 KeyEvent.VK_AT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_BACKSLASH,
+                                 KeyEvent.VK_BACK_SLASH);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_BACKSPACE,
+                                 KeyEvent.VK_BACK_SPACE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_B,
+                                 KeyEvent.VK_B);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_CANCEL,
+                                 KeyEvent.VK_CANCEL);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_CAPS_LOCK,
+                                 KeyEvent.VK_CAPS_LOCK);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_CIRCUMFLEX,
+                                 KeyEvent.VK_CIRCUMFLEX);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_C,
+                                 KeyEvent.VK_C);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_CLEAR,
+                                 KeyEvent.VK_CLEAR);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_CODE_INPUT,
+                                 KeyEvent.VK_CODE_INPUT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COLON,
+                                 KeyEvent.VK_COLON);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_ACUTE,
+                                 KeyEvent.VK_DEAD_ACUTE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_BREVE,
+                                 KeyEvent.VK_DEAD_BREVE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_CARON,
+                                 KeyEvent.VK_DEAD_CARON);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_CEDILLA,
+                                 KeyEvent.VK_DEAD_CEDILLA);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_CIRCUMFLEX,
+                                 KeyEvent.VK_DEAD_CIRCUMFLEX);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_DIERESIS,
+                                 KeyEvent.VK_DEAD_DIAERESIS);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_DOT_ABOVE,
+                                 KeyEvent.VK_DEAD_ABOVEDOT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_DOUBLE_ACUTE,
+                                 KeyEvent.VK_DEAD_DOUBLEACUTE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_GRAVE,
+                                 KeyEvent.VK_DEAD_GRAVE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_IOTA,
+                                 KeyEvent.VK_DEAD_IOTA);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_MACRON,
+                                 KeyEvent.VK_DEAD_MACRON);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_OGONEK,
+                                 KeyEvent.VK_DEAD_OGONEK);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_RING_ABOVE,
+                                 KeyEvent.VK_DEAD_ABOVERING);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMBINING_TILDE,
+                                 KeyEvent.VK_DEAD_TILDE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMMA,
+                                 KeyEvent.VK_COMMA);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COMPOSE,
+                                 KeyEvent.VK_COMPOSE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_CONTROL,
+                                 KeyEvent.VK_CONTROL);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_CONVERT,
+                                 KeyEvent.VK_CONVERT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_COPY,
+                                 KeyEvent.VK_COPY);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_CUT,
+                                 KeyEvent.VK_CUT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_DELETE,
+                                 KeyEvent.VK_DELETE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_D,
+                                 KeyEvent.VK_D);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_DOLLAR,
+                                 KeyEvent.VK_DOLLAR);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_DOWN,
+                                 KeyEvent.VK_DOWN);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_E,
+                                 KeyEvent.VK_E);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_END,
+                                 KeyEvent.VK_END);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_ENTER,
+                                 KeyEvent.VK_ENTER);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_EQUALS,
+                                 KeyEvent.VK_EQUALS);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_ESCAPE,
+                                 KeyEvent.VK_ESCAPE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_EURO,
+                                 KeyEvent.VK_EURO_SIGN);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_EXCLAMATION,
+                                 KeyEvent.VK_EXCLAMATION_MARK);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F10,
+                                 KeyEvent.VK_F10);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F11,
+                                 KeyEvent.VK_F11);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F12,
+                                 KeyEvent.VK_F12);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F13,
+                                 KeyEvent.VK_F13);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F14,
+                                 KeyEvent.VK_F14);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F15,
+                                 KeyEvent.VK_F15);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F16,
+                                 KeyEvent.VK_F16);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F17,
+                                 KeyEvent.VK_F17);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F18,
+                                 KeyEvent.VK_F18);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F19,
+                                 KeyEvent.VK_F19);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F1,
+                                 KeyEvent.VK_F1);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F20,
+                                 KeyEvent.VK_F20);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F21,
+                                 KeyEvent.VK_F21);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F22,
+                                 KeyEvent.VK_F22);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F23,
+                                 KeyEvent.VK_F23);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F24,
+                                 KeyEvent.VK_F24);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F2,
+                                 KeyEvent.VK_F2);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F3,
+                                 KeyEvent.VK_F3);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F4,
+                                 KeyEvent.VK_F4);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F5,
+                                 KeyEvent.VK_F5);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F6,
+                                 KeyEvent.VK_F6);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F7,
+                                 KeyEvent.VK_F7);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F8,
+                                 KeyEvent.VK_F8);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F9,
+                                 KeyEvent.VK_F9);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_FINAL_MODE,
+                                 KeyEvent.VK_FINAL);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_FIND,
+                                 KeyEvent.VK_FIND);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_F,
+                                 KeyEvent.VK_F);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_FULL_STOP,
+                                 KeyEvent.VK_PERIOD);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_FULL_WIDTH,
+                                 KeyEvent.VK_FULL_WIDTH);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_G,
+                                 KeyEvent.VK_G);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_GRAVE,
+                                 KeyEvent.VK_BACK_QUOTE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_GREATER_THAN,
+                                 KeyEvent.VK_GREATER);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_HALF_WIDTH,
+                                 KeyEvent.VK_HALF_WIDTH);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_HASH,
+                                 KeyEvent.VK_NUMBER_SIGN);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_HELP,
+                                 KeyEvent.VK_HELP);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_HIRAGANA,
+                                 KeyEvent.VK_HIRAGANA);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_H,
+                                 KeyEvent.VK_H);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_HOME,
+                                 KeyEvent.VK_HOME);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_I,
+                                 KeyEvent.VK_I);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_INSERT,
+                                 KeyEvent.VK_INSERT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_INVERTED_EXCLAMATION,
+                                 KeyEvent.VK_INVERTED_EXCLAMATION_MARK);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_JAPANESE_HIRAGANA,
+                                 KeyEvent.VK_JAPANESE_HIRAGANA);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_JAPANESE_KATAKANA,
+                                 KeyEvent.VK_JAPANESE_KATAKANA);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_JAPANESE_ROMAJI,
+                                 KeyEvent.VK_JAPANESE_ROMAN);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_J,
+                                 KeyEvent.VK_J);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_KANA_MODE,
+                                 KeyEvent.VK_KANA_LOCK);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_KANJI_MODE,
+                                 KeyEvent.VK_KANJI);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_KATAKANA,
+                                 KeyEvent.VK_KATAKANA);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_K,
+                                 KeyEvent.VK_K);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_LEFT_BRACE,
+                                 KeyEvent.VK_BRACELEFT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_LEFT,
+                                 KeyEvent.VK_LEFT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_LEFT_PARENTHESIS,
+                                 KeyEvent.VK_LEFT_PARENTHESIS);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_LEFT_SQUARE_BRACKET,
+                                 KeyEvent.VK_OPEN_BRACKET);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_LESS_THAN,
+                                 KeyEvent.VK_LESS);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_L,
+                                 KeyEvent.VK_L);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_META,
+                                 KeyEvent.VK_META);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_META,
+                                 KeyEvent.VK_META);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_MINUS,
+                                 KeyEvent.VK_MINUS);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_M,
+                                 KeyEvent.VK_M);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_MODE_CHANGE,
+                                 KeyEvent.VK_MODECHANGE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_N,
+                                 KeyEvent.VK_N);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_NONCONVERT,
+                                 KeyEvent.VK_NONCONVERT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_NUM_LOCK,
+                                 KeyEvent.VK_NUM_LOCK);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_NUM_LOCK,
+                                 KeyEvent.VK_NUM_LOCK);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_O,
+                                 KeyEvent.VK_O);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_PAGE_DOWN,
+                                 KeyEvent.VK_PAGE_DOWN);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_PAGE_UP,
+                                 KeyEvent.VK_PAGE_UP);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_PASTE,
+                                 KeyEvent.VK_PASTE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_PAUSE,
+                                 KeyEvent.VK_PAUSE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_P,
+                                 KeyEvent.VK_P);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_PLUS,
+                                 KeyEvent.VK_PLUS);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_PREVIOUS_CANDIDATE,
+                                 KeyEvent.VK_PREVIOUS_CANDIDATE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_PRINT_SCREEN,
+                                 KeyEvent.VK_PRINTSCREEN);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_PROPS,
+                                 KeyEvent.VK_PROPS);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_Q,
+                                 KeyEvent.VK_Q);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_QUOTE,
+                                 KeyEvent.VK_QUOTEDBL);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_RIGHT_BRACE,
+                                 KeyEvent.VK_BRACERIGHT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_RIGHT,
+                                 KeyEvent.VK_RIGHT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_RIGHT_PARENTHESIS,
+                                 KeyEvent.VK_RIGHT_PARENTHESIS);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_RIGHT_SQUARE_BRACKET,
+                                 KeyEvent.VK_CLOSE_BRACKET);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_R,
+                                 KeyEvent.VK_R);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_ROMAN_CHARACTERS,
+                                 KeyEvent.VK_ROMAN_CHARACTERS);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_SCROLL,
+                                 KeyEvent.VK_SCROLL_LOCK);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_SCROLL,
+                                 KeyEvent.VK_SCROLL_LOCK);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_SEMICOLON,
+                                 KeyEvent.VK_SEMICOLON);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_SEMIVOICED_SOUND,
+                                 KeyEvent.VK_DEAD_SEMIVOICED_SOUND);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_SHIFT,
+                                 KeyEvent.VK_SHIFT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_SHIFT,
+                                 KeyEvent.VK_SHIFT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_S,
+                                 KeyEvent.VK_S);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_SLASH,
+                                 KeyEvent.VK_SLASH);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_SPACE,
+                                 KeyEvent.VK_SPACE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_STOP,
+                                 KeyEvent.VK_STOP);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_TAB,
+                                 KeyEvent.VK_TAB);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_T,
+                                 KeyEvent.VK_T);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_U,
+                                 KeyEvent.VK_U);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_UNDERSCORE,
+                                 KeyEvent.VK_UNDERSCORE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_UNDO,
+                                 KeyEvent.VK_UNDO);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_UNIDENTIFIED,
+                                 KeyEvent.VK_UNDEFINED);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_UP,
+                                 KeyEvent.VK_UP);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_V,
+                                 KeyEvent.VK_V);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_VOICED_SOUND,
+                                 KeyEvent.VK_DEAD_VOICED_SOUND);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_W,
+                                 KeyEvent.VK_W);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_X,
+                                 KeyEvent.VK_X);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_Y,
+                                 KeyEvent.VK_Y);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_Z,
+                                 KeyEvent.VK_Z);
+            // Java keycodes for duplicate keys
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_0,
+                                 KeyEvent.VK_NUMPAD0);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_1,
+                                 KeyEvent.VK_NUMPAD1);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_2,
+                                 KeyEvent.VK_NUMPAD2);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_3,
+                                 KeyEvent.VK_NUMPAD3);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_4,
+                                 KeyEvent.VK_NUMPAD4);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_5,
+                                 KeyEvent.VK_NUMPAD5);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_6,
+                                 KeyEvent.VK_NUMPAD6);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_7,
+                                 KeyEvent.VK_NUMPAD7);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_8,
+                                 KeyEvent.VK_NUMPAD8);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_9,
+                                 KeyEvent.VK_NUMPAD9);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_ASTERISK,
+                                 KeyEvent.VK_MULTIPLY);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_DOWN,
+                                 KeyEvent.VK_KP_DOWN);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_FULL_STOP,
+                                 KeyEvent.VK_DECIMAL);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_LEFT,
+                                 KeyEvent.VK_KP_LEFT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_MINUS,
+                                 KeyEvent.VK_SUBTRACT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_PLUS,
+                                 KeyEvent.VK_ADD);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_RIGHT,
+                                 KeyEvent.VK_KP_RIGHT);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_SLASH,
+                                 KeyEvent.VK_DIVIDE);
+            putIdentifierKeyCode(DOMKeyboardEvent.KEY_UP,
+                                 KeyEvent.VK_KP_UP);
+        }
+
+        /**
+         * Put a key code to key identifier mapping into the
+         * IDENTIFIER_KEY_CODES table.
+         */
+        protected static void putIdentifierKeyCode(String keyIdentifier,
+                                                   int keyCode) {
+            if (IDENTIFIER_KEY_CODES[keyCode / 256] == null) {
+                IDENTIFIER_KEY_CODES[keyCode / 256] = new String[256];
+            }
+            IDENTIFIER_KEY_CODES[keyCode / 256][keyCode % 256] = keyIdentifier;
+        }
+
+        /**
+         * Convert a Java key code to a DOM 3 key string.
+         */
+        protected String mapKeyCodeToIdentifier(int keyCode) {
+            String[] a = IDENTIFIER_KEY_CODES[keyCode / 256];
+            if (a == null) {
+                return DOMKeyboardEvent.KEY_UNIDENTIFIED;
+            }
+            return a[keyCode % 256];
+        }
+
+        // MouseWheel ------------------------------------------------------
+
+        public void mouseWheelMoved(GraphicsNodeMouseWheelEvent evt) {
+            FocusManager fmgr = context.getFocusManager();
+            if (fmgr == null) {
+                return;
+            }
+
+            Element targetElement = (Element) fmgr.getCurrentEventTarget();
+            if (targetElement == null) {
+                return;
+            }
+            Document doc = targetElement.getOwnerDocument();
+            targetElement = doc.getDocumentElement();
+            DocumentEvent d = (DocumentEvent) doc;
+            SVGOMWheelEvent wheelEvt
+                = (SVGOMWheelEvent) d.createEvent("WheelEvent");
+            wheelEvt.initWheelEventNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
+                                      "wheel", 
+                                      true,
+                                      true,
+                                      null,
+                                      evt.getWheelDelta());
+
+            try {
+                ((EventTarget)targetElement).dispatchEvent(wheelEvt);
+            } catch (RuntimeException e) {
+                ua.displayError(e);
+            }
+        }
+
+        // Mouse -----------------------------------------------------------
+
+        public void mouseEntered(GraphicsNodeMouseEvent evt) {
+            Point clientXY = evt.getClientPoint();
+            GraphicsNode node = evt.getGraphicsNode();
+            Element targetElement = getEventTarget
+                (node, new Point2D.Float(evt.getX(), evt.getY()));
+            Element relatedElement = getRelatedElement(evt);
+            int n = 0;
+            if (relatedElement != null && targetElement != null) {
+                n = DefaultXBLManager.computeBubbleLimit(targetElement,
+                                                         relatedElement);
+            }
+            dispatchMouseEvent("mouseover", 
+                               targetElement,
+                               relatedElement,
+                               clientXY, 
+                               evt, 
+                               true,
+                               n);
+        }
+
+        public void mouseExited(GraphicsNodeMouseEvent evt) {
+            Point clientXY = evt.getClientPoint();
+            // Get the 'new' node for the DOM event.
+            GraphicsNode node = evt.getRelatedNode();
+            Element targetElement = getEventTarget(node, clientXY);
+            if (lastTargetElement != null) {
+                int n = 0;
+                if (targetElement != null) {
+                    // moving from one element to another
+                    n = DefaultXBLManager.computeBubbleLimit(lastTargetElement,
+                                                             targetElement);
+                }
+                dispatchMouseEvent("mouseout", 
+                                   lastTargetElement, // target
+                                   targetElement,     // relatedTarget
+                                   clientXY,
+                                   evt,
+                                   true,
+                                   n);
+                lastTargetElement = null;
+            }
+        }
+
+        public void mouseMoved(GraphicsNodeMouseEvent evt) {
+            Point clientXY = evt.getClientPoint();
+            GraphicsNode node = evt.getGraphicsNode();
+            Element targetElement = getEventTarget(node, clientXY);
+            Element holdLTE = lastTargetElement;
+            if (holdLTE != targetElement) {
+                if (holdLTE != null) {
+                    int n = 0;
+                    if (targetElement != null) {
+                        n = DefaultXBLManager.computeBubbleLimit(holdLTE,
+                                                                 targetElement);
+                    }
+                    dispatchMouseEvent("mouseout", 
+                                       holdLTE, // target
+                                       targetElement,     // relatedTarget
+                                       clientXY,
+                                       evt,
+                                       true,
+                                       n);
+                }
+                if (targetElement != null) {
+                    int n = 0;
+                    if (holdLTE != null) {
+                        n = DefaultXBLManager.computeBubbleLimit(targetElement,
+                                                                 holdLTE);
+                    }
+                    dispatchMouseEvent("mouseover", 
+                                       targetElement,     // target
+                                       holdLTE, // relatedTarget
+                                       clientXY,
+                                       evt,
+                                       true,
+                                       n);
+                }
+            }
+            dispatchMouseEvent("mousemove", 
+                               targetElement,     // target
+                               null,              // relatedTarget
+                               clientXY,
+                               evt,
+                               false,
+                               0);
+        }
+
+        /**
+         * Dispatches a DOM MouseEvent according to the specified
+         * parameters.
+         *
+         * @param eventType the event type
+         * @param targetElement the target of the event
+         * @param relatedElement the related target if any
+         * @param clientXY the mouse coordinates in the client space
+         * @param evt the GVT GraphicsNodeMouseEvent
+         * @param cancelable true means the event is cancelable
+         * @param bubbleLimit the limit to the number of nodes the event
+         *                    will bubble to
+         */
+        protected void dispatchMouseEvent(String eventType,
+                                          Element targetElement,
+                                          Element relatedElement,
+                                          Point clientXY,
+                                          GraphicsNodeMouseEvent evt,
+                                          boolean cancelable,
+                                          int bubbleLimit) {
+            if (targetElement == null) {
+                return;
+            }
+            short button = getButton(evt);
+            Point screenXY = evt.getScreenPoint();
+            // create the coresponding DOM MouseEvent
+            DocumentEvent d = (DocumentEvent)targetElement.getOwnerDocument();
+            DOMMouseEvent mouseEvt
+                = (DOMMouseEvent) d.createEvent("MouseEvents");
+            String modifiers
+                = DOMUtilities.getModifiersList(evt.getLockState(),
+                                                evt.getModifiers());
+            mouseEvt.initMouseEventNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
+                                      eventType, 
+                                      true, 
+                                      cancelable, 
+                                      null,
+                                      evt.getClickCount(),
+                                      screenXY.x, 
+                                      screenXY.y,
+                                      clientXY.x,
+                                      clientXY.y,
+                                      button, 
+                                      (EventTarget)relatedElement,
+                                      modifiers);
+
+            ((AbstractEvent) mouseEvt).setBubbleLimit(bubbleLimit);
+
+            try {
+                ((EventTarget)targetElement).dispatchEvent(mouseEvt);
+            } catch (RuntimeException e) {
+                ua.displayError(e);
+            } finally {
+                lastTargetElement = targetElement;
+            }
+        }
+    }
+}

Propchange: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12BridgeEventSupport.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12BridgeExtension.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12BridgeExtension.java?rev=280553&r1=280552&r2=280553&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12BridgeExtension.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12BridgeExtension.java Tue Sep 13 06:29:29 2005
@@ -24,6 +24,7 @@
 import org.apache.batik.bridge.SVGBridgeExtension;
 import org.apache.batik.util.SVGConstants;
 import org.apache.batik.util.SVG12Constants;
+import org.apache.batik.util.XBLConstants;
 import org.w3c.dom.Element;
 
 /**
@@ -94,9 +95,24 @@
         // bridges to handle elements in the SVG namespace
         super.registerTags(ctx);
 
+        // Bridges for SVG 1.2 elements
         ctx.putBridge(new SVGFlowRootElementBridge());
         ctx.putBridge(new SVGMultiImageElementBridge());
         ctx.putBridge(new SVGSolidColorElementBridge());
+
+        ctx.putBridge(new SVG12TextElementBridge());
+
+        // Bridges for XBL shadow trees and content elements
+        ctx.putBridge(new XBLShadowTreeElementBridge());
+        ctx.putBridge(new XBLContentElementBridge());
+
+        // Default bridge to handle bindable elements
+        ctx.setDefaultBridge(new BindableElementBridge());
+
+        // Namespaces to avoid for default bridges
+        ctx.putReservedNamespaceURI(null);
+        ctx.putReservedNamespaceURI(SVGConstants.SVG_NAMESPACE_URI);
+        ctx.putReservedNamespaceURI(XBLConstants.XBL_NAMESPACE_URI);
     }
 
     /**
@@ -108,6 +124,9 @@
      */
     public boolean isDynamicElement(Element e) {
         String ns = e.getNamespaceURI();
+        if (XBLConstants.XBL_NAMESPACE_URI.equals(ns)) {
+            return true;
+        }
         if (!SVGConstants.SVG_NAMESPACE_URI.equals(ns)) {
             return false;
         }

Added: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12BridgeUpdateHandler.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12BridgeUpdateHandler.java?rev=280553&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12BridgeUpdateHandler.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12BridgeUpdateHandler.java Tue Sep 13 06:29:29 2005
@@ -0,0 +1,38 @@
+/*
+
+   Copyright 2005  The Apache Software Foundation 
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.batik.bridge.svg12;
+
+import org.apache.batik.bridge.BridgeUpdateHandler;
+import org.apache.batik.dom.xbl.ShadowTreeEvent;
+
+import org.w3c.dom.Element;
+
+/**
+ * A BridgeUpdateHandler interface for SVG 1.2 specific events.  This is
+ * for XBL event notification.
+ *
+ * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
+ * @version $Id$
+ */
+public interface SVG12BridgeUpdateHandler extends BridgeUpdateHandler {
+
+    /**
+     * Invoked when a bindable element's binding has changed.
+     */
+    void handleBindingEvent(Element bindableElement, Element shadowTree);
+}

Propchange: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12BridgeUpdateHandler.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12FocusManager.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12FocusManager.java?rev=280553&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12FocusManager.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12FocusManager.java Tue Sep 13 06:29:29 2005
@@ -0,0 +1,201 @@
+/*
+
+   Copyright 2005  The Apache Software Foundation 
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.batik.bridge.svg12;
+
+import org.apache.batik.bridge.FocusManager;
+import org.apache.batik.dom.AbstractNode;
+import org.apache.batik.dom.events.AbstractEvent;
+import org.apache.batik.dom.events.DOMUIEvent;
+import org.apache.batik.dom.events.EventSupport;
+import org.apache.batik.dom.svg12.XBLEventSupport;
+import org.apache.batik.util.XMLConstants;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.events.DocumentEvent;
+import org.w3c.dom.events.Event;
+import org.w3c.dom.events.EventTarget;
+
+/**
+ * Focus manager for SVG 1.2 documents.  Ensures bubble limits of DOM
+ * focus events are set appropriately for sXBL. support.
+ *
+ * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
+ * @version $Id$
+ */
+public class SVG12FocusManager extends FocusManager {
+
+    /**
+     * Constructs a new <tt>SVG12FocusManager</tt> for the specified document.
+     *
+     * @param doc the document
+     */
+    public SVG12FocusManager(Document doc) {
+        super(doc);
+    }
+
+    /**
+     * Adds the event listeners to the document.
+     */
+    protected void addEventListeners(Document doc) {
+        AbstractNode n = (AbstractNode) doc;
+        XBLEventSupport es = (XBLEventSupport) n.initializeEventSupport();
+
+        mouseclickListener = new MouseClickTracker();
+        es.addImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "click",
+             mouseclickListener, true);
+
+        mouseoverListener = new MouseOverTracker();
+        es.addImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "mouseover",
+             mouseoverListener, true);
+
+        mouseoutListener = new MouseOutTracker();
+        es.addImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "mouseout",
+             mouseoutListener, true);
+
+        domFocusInListener = new DOMFocusInTracker();
+        es.addImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMFocusIn",
+             domFocusInListener, true);
+
+        domFocusOutListener = new DOMFocusOutTracker();
+        es.addImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMFocusOut",
+             domFocusOutListener, true);
+    }
+
+    /**
+     * Removes the event listeners from the document.
+     */
+    protected void removeEventListeners(Document doc) {
+        AbstractNode n = (AbstractNode) doc;
+        XBLEventSupport es = (XBLEventSupport) n.getEventSupport();
+
+        es.removeImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "click",
+             mouseclickListener, true);
+        es.removeImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "mouseover",
+             mouseoverListener, true);
+        es.removeImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "mouseout",
+             mouseoutListener, true);
+        es.removeImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMFocusIn",
+             domFocusInListener, true);
+        es.removeImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMFocusOut",
+             domFocusOutListener, true);
+    }
+
+    /**
+     * The class that is responsible for tracking 'mouseclick' changes.
+     */
+    protected class MouseClickTracker extends FocusManager.MouseClickTracker {
+        public void handleEvent(Event evt) {
+            super.handleEvent(EventSupport.getUltimateOriginalEvent(evt));
+        }
+    }
+
+    /**
+     * The class that is responsible for tracking 'DOMFocusIn' changes.
+     */
+    protected class DOMFocusInTracker extends FocusManager.DOMFocusInTracker {
+        public void handleEvent(Event evt) {
+            super.handleEvent(EventSupport.getUltimateOriginalEvent(evt));
+        }
+    }
+
+    /**
+     * The class that is responsible for tracking 'mouseover' changes.
+     */
+    protected class MouseOverTracker extends FocusManager.MouseOverTracker {
+        public void handleEvent(Event evt) {
+            super.handleEvent(EventSupport.getUltimateOriginalEvent(evt));
+        }
+    }
+
+    /**
+     * The class that is responsible for tracking 'mouseout' changes.
+     */
+    protected class MouseOutTracker extends FocusManager.MouseOutTracker {
+        public void handleEvent(Event evt) {
+            super.handleEvent(EventSupport.getUltimateOriginalEvent(evt));
+        }
+    }
+
+    /**
+     * Fires a 'DOMFocusIn' event to the specified target.
+     *
+     * @param target the newly focussed event target
+     * @param relatedTarget the previously focussed event target
+     */
+    protected void fireDOMFocusInEvent(EventTarget target,
+                                       EventTarget relatedTarget) {
+        DocumentEvent docEvt = 
+            (DocumentEvent)((Element)target).getOwnerDocument();
+        DOMUIEvent uiEvt = (DOMUIEvent)docEvt.createEvent("UIEvents");
+        uiEvt.initUIEventNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
+                            "DOMFocusIn",
+                            true,
+                            false,  // canBubbleArg
+                            null,   // cancelableArg
+                            0);     // detailArg
+        int limit = DefaultXBLManager.computeBubbleLimit((Node) relatedTarget,
+                                                         (Node) target);
+        ((AbstractEvent) uiEvt).setBubbleLimit(limit);
+        target.dispatchEvent(uiEvt);
+    }
+
+    /**
+     * Fires a 'DOMFocusOut' event to the specified target.
+     *
+     * @param target the previously focussed event target
+     * @param relatedTarget the newly focussed event target
+     */
+    protected void fireDOMFocusOutEvent(EventTarget target,
+                                        EventTarget relatedTarget) {
+        DocumentEvent docEvt = 
+            (DocumentEvent)((Element)target).getOwnerDocument();
+        DOMUIEvent uiEvt = (DOMUIEvent)docEvt.createEvent("UIEvents");
+        uiEvt.initUIEventNS(XMLConstants.XML_EVENTS_NAMESPACE_URI,
+                            "DOMFocusOut",
+                            true,
+                            false,  // canBubbleArg
+                            null,   // cancelableArg
+                            0);     // detailArg
+        int limit = DefaultXBLManager.computeBubbleLimit((Node) target,
+                                                         (Node) relatedTarget);
+        ((AbstractEvent) uiEvt).setBubbleLimit(limit);
+        target.dispatchEvent(uiEvt);
+    }
+}

Propchange: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12FocusManager.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12ScriptingEnvironment.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12ScriptingEnvironment.java?rev=280553&r1=280552&r2=280553&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12ScriptingEnvironment.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12ScriptingEnvironment.java Tue Sep 13 06:29:29 2005
@@ -1,3 +1,20 @@
+/*
+
+   Copyright 2005  The Apache Software Foundation 
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
 package org.apache.batik.bridge.svg12;
 
 import org.apache.batik.bridge.BridgeContext;
@@ -7,6 +24,7 @@
 import org.apache.batik.bridge.SVGUtilities;
 import org.apache.batik.dom.AbstractDocument;
 import org.apache.batik.dom.AbstractElement;
+import org.apache.batik.dom.svg12.XBLEventSupport;
 import org.apache.batik.dom.util.DOMUtilities;
 import org.apache.batik.dom.util.TriplyIndexedTable;
 import org.apache.batik.util.SVGConstants;
@@ -49,6 +67,46 @@
      * Maps (event namespace, event local name, element) to a handler.
      */
     protected TriplyIndexedTable handlerScriptingListeners;
+
+    /**
+     * Adds DOM listeners to the document.
+     */
+    protected void addDocumentListeners() {
+        AbstractDocument doc = (AbstractDocument) document;
+        XBLEventSupport es = (XBLEventSupport) doc.initializeEventSupport();
+        es.addImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMNodeInserted",
+             domNodeInsertedListener, false);
+        es.addImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMNodeRemoved",
+             domNodeRemovedListener, false);
+        es.addImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMAttrModified",
+             domAttrModifiedListener, false);
+    }
+
+    /**
+     * Removes DOM listeners from the document.
+     */
+    protected void removeDocumentListeners() {
+        AbstractDocument doc = (AbstractDocument) document;
+        XBLEventSupport es = (XBLEventSupport) doc.initializeEventSupport();
+        es.removeImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMNodeInserted",
+             domNodeInsertedListener, false);
+        es.removeImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMNodeRemoved",
+             domNodeRemovedListener, false);
+        es.removeImplementationEventListenerNS
+            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+             "DOMAttrModified",
+             domAttrModifiedListener, false);
+    }
 
     /**
      * Adds the scripting listeners to the given element.

Added: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12TextElementBridge.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12TextElementBridge.java?rev=280553&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12TextElementBridge.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12TextElementBridge.java Tue Sep 13 06:29:29 2005
@@ -0,0 +1,44 @@
+/*
+
+   Copyright 2005  The Apache Software Foundation 
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.batik.bridge.svg12;
+
+import org.apache.batik.bridge.SVGTextElementBridge;
+import org.apache.batik.dom.xbl.ShadowTreeEvent;
+
+import org.w3c.dom.Element;
+
+/**
+ * Bridge class for SVG 'text' elements with support for text content
+ * that has been specified with XBL.
+ *
+ * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
+ * @version $Id$
+ */
+public class SVG12TextElementBridge
+        extends SVGTextElementBridge
+        implements SVG12BridgeUpdateHandler {
+
+    // SVG12BridgeUpdateHandler //////////////////////////////////////////////
+
+    /**
+     * Invoked when a bindable element's binding has changed.
+     */
+    public void handleBindingEvent(Element bindableElement,
+                                   Element shadowTree) {
+    }
+}

Propchange: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12TextElementBridge.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12URIResolver.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12URIResolver.java?rev=280553&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12URIResolver.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12URIResolver.java Tue Sep 13 06:29:29 2005
@@ -0,0 +1,85 @@
+/*
+
+   Copyright 2005  The Apache Software Foundation 
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.batik.bridge.svg12;
+
+import org.apache.batik.bridge.DocumentLoader;
+import org.apache.batik.bridge.URIResolver;
+import org.apache.batik.dom.AbstractNode;
+import org.apache.batik.dom.xbl.NodeXBL;
+import org.apache.batik.dom.xbl.XBLShadowTreeElement;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.svg.SVGDocument;
+
+/**
+ * A URIResolver for SVG 1.2 documents.  This is to allow resolution of
+ * fragment IDs within shadow trees to work properly.
+ *
+ * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
+ * @version $Id$
+ */
+public class SVG12URIResolver extends URIResolver {
+
+    /**
+     * Creates a new SVG12URIResolver object.
+     */
+    public SVG12URIResolver(SVGDocument doc, DocumentLoader dl) {
+        super(doc, dl);
+    }
+
+    /**
+     * Returns the base URI of the referer element.
+     */
+    protected String getRefererBaseURI(Element ref) {
+        AbstractNode aref = (AbstractNode) ref;
+        if (aref.getXblBoundElement() != null) {
+            return null;
+        }
+        return aref.getBaseURI();
+    }
+
+    /**
+     * Returns the node referenced by the given fragment identifier.
+     * This is called when the whole URI just contains a fragment identifier
+     * and there is no XML Base URI in effect.
+     * @param frag the URI fragment
+     * @param ref  the context element from which to resolve the URI fragment
+     */
+    protected Node getNodeByFragment(String frag, Element ref) {
+        NodeXBL refx = (NodeXBL) ref;
+        NodeXBL boundElt = (NodeXBL) refx.getXblBoundElement();
+        if (boundElt != null) {
+            XBLShadowTreeElement shadow
+                = (XBLShadowTreeElement) boundElt.getXblShadowTree();
+            Node n = shadow.getElementById(frag);
+            if (n != null) {
+                return n;
+            }
+            NodeList nl = refx.getXblDefinitions();
+            for (int i = 0; i < nl.getLength(); i++) {
+                n = nl.item(i).getOwnerDocument().getElementById(frag);
+                if (n != null) {
+                    return n;
+                }
+            }
+        }
+        return super.getNodeByFragment(frag, ref);
+    }
+}

Propchange: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVG12URIResolver.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVGFlowRootElementBridge.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVGFlowRootElementBridge.java?rev=280553&r1=280552&r2=280553&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVGFlowRootElementBridge.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/SVGFlowRootElementBridge.java Tue Sep 13 06:29:29 2005
@@ -22,7 +22,6 @@
 import java.awt.font.TextAttribute;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
 import java.text.AttributedCharacterIterator;
 import java.text.AttributedString;
 import java.util.ArrayList;
@@ -33,18 +32,14 @@
 
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
-import org.w3c.dom.events.EventTarget;
 
 import org.apache.batik.bridge.Bridge;
-import org.apache.batik.bridge.BridgeException;
 import org.apache.batik.bridge.BridgeContext;
 import org.apache.batik.bridge.CSSUtilities;
-import org.apache.batik.bridge.GraphicsNodeBridge;
 import org.apache.batik.bridge.GVTBuilder;
 import org.apache.batik.bridge.SVGTextElementBridge;
 import org.apache.batik.bridge.SVGUtilities;
 import org.apache.batik.bridge.TextUtilities;
-import org.apache.batik.bridge.UnitProcessor;
 import org.apache.batik.bridge.UserAgent;
 import org.apache.batik.bridge.SVGAElementBridge;
 
@@ -56,22 +51,22 @@
 import org.apache.batik.css.engine.value.Value;
 import org.apache.batik.css.engine.value.ValueConstants;
 
+import org.apache.batik.dom.events.NodeEventTarget;
 import org.apache.batik.dom.util.XMLSupport;
 import org.apache.batik.dom.util.XLinkSupport;
 
 import org.apache.batik.gvt.GraphicsNode;
-import org.apache.batik.gvt.TextNode;
 import org.apache.batik.gvt.flow.BlockInfo;
 import org.apache.batik.gvt.flow.FlowTextNode;
 import org.apache.batik.gvt.flow.RegionInfo;
 import org.apache.batik.gvt.flow.TextLineBreaks;
 
 import org.apache.batik.gvt.text.GVTAttributedCharacterIterator;
-import org.apache.batik.gvt.text.TextPaintInfo;
 import org.apache.batik.gvt.text.TextPath;
 
 import org.apache.batik.util.SVG12Constants;
 import org.apache.batik.util.SVG12CSSConstants;
+import org.apache.batik.util.XMLConstants;
 
 /**
  * Bridge class for the &lt;flowRoot> element.
@@ -444,22 +439,25 @@
 					       asb, lnLocs);
                 } else if (ln.equals(SVG_A_TAG)) {
                     if (ctx.isInteractive()) {
-                        EventTarget target = (EventTarget)nodeElement;
+                        NodeEventTarget target = (NodeEventTarget)nodeElement;
                         UserAgent ua = ctx.getUserAgent();
-                        target.addEventListener
-                            (SVG_EVENT_CLICK, 
+                        target.addEventListenerNS
+                            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+                             SVG_EVENT_CLICK, 
                              new SVGAElementBridge.AnchorListener(ua),
-                             false);
+                             false, null);
                     
-                        target.addEventListener
-                            (SVG_EVENT_MOUSEOVER,
+                        target.addEventListenerNS
+                            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+                             SVG_EVENT_MOUSEOVER,
                              new SVGAElementBridge.CursorMouseOverListener(ua),
-                             false);
+                             false, null);
                     
-                        target.addEventListener
-                            (SVG_EVENT_MOUSEOUT,
+                        target.addEventListenerNS
+                            (XMLConstants.XML_EVENTS_NAMESPACE_URI,
+                             SVG_EVENT_MOUSEOUT,
                              new SVGAElementBridge.CursorMouseOutListener(ua),
-                             false);
+                             false, null);
                     }
                     fillAttributedStringBuffer(ctx,
                                                nodeElement,

Added: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/XBLContentElementBridge.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/XBLContentElementBridge.java?rev=280553&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/XBLContentElementBridge.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/XBLContentElementBridge.java Tue Sep 13 06:29:29 2005
@@ -0,0 +1,214 @@
+/*
+
+   Copyright 2005  The Apache Software Foundation 
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.batik.bridge.svg12;
+
+import org.apache.batik.bridge.AbstractGraphicsNodeBridge;
+import org.apache.batik.bridge.Bridge;
+import org.apache.batik.bridge.BridgeContext;
+import org.apache.batik.bridge.GVTBuilder;
+import org.apache.batik.bridge.SVGUtilities;
+import org.apache.batik.bridge.svg12.ContentManager;
+import org.apache.batik.bridge.svg12.ContentSelectionChangedEvent;
+import org.apache.batik.bridge.svg12.ContentSelectionChangedListener;
+import org.apache.batik.bridge.svg12.DefaultXBLManager;
+import org.apache.batik.dom.AbstractDocument;
+import org.apache.batik.dom.svg12.XBLOMContentElement;
+import org.apache.batik.util.XBLConstants;
+import org.apache.batik.gvt.CompositeGraphicsNode;
+import org.apache.batik.gvt.GraphicsNode;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.events.MutationEvent;
+
+/**
+ * Bridge class for the &lt;xbl:content&gt; element.
+ *
+ * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
+ * @version $Id$
+ */
+public class XBLContentElementBridge extends AbstractGraphicsNodeBridge {
+    
+    /**
+     * The event listener for content element selection changes.
+     */
+    protected ContentChangedListener contentChangedListener;
+
+    /**
+     * The ContentManager object used for the content element selection
+     * change events.
+     */
+    protected ContentManager contentManager;
+
+    /**
+     * Constructs a new bridge for the &lt;xbl:content&gt; element.
+     */
+    public XBLContentElementBridge() {
+    }
+
+    /**
+     * Returns 'content'.
+     */
+    public String getLocalName() {
+        return XBLConstants.XBL_CONTENT_TAG;
+    }
+
+    /**
+     * Returns the XBL namespace.
+     */
+    public String getNamespaceURI() {
+        return XBLConstants.XBL_NAMESPACE_URI;
+    }
+
+    /**
+     * Returns a new instance of this bridge.
+     */
+    public Bridge getInstance() {
+        return new XBLContentElementBridge();
+    }
+
+    /**
+     * Creates a <tt>GraphicsNode</tt> according to the specified parameters.
+     *
+     * @param ctx the bridge context to use
+     * @param e the element that describes the graphics node to build
+     * @return a graphics node that represents the specified element
+     */
+    public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) {
+        CompositeGraphicsNode gn = buildCompositeGraphicsNode(ctx, e, null);
+        return gn;
+    }
+
+    /**
+     * Creates a <tt>GraphicsNode</tt> from the input element and
+     * populates the input <tt>CompositeGraphicsNode</tt>
+     *
+     * @param ctx the bridge context to use
+     * @param e the element that describes the graphics node to build
+     * @param cgn the CompositeGraphicsNode where the use graphical 
+     *        content will be appended. The composite node is emptied
+     *        before appending new content.
+     */
+    public CompositeGraphicsNode buildCompositeGraphicsNode
+        (BridgeContext ctx, Element e, CompositeGraphicsNode cgn) {
+
+        XBLOMContentElement content = (XBLOMContentElement) e;
+        AbstractDocument doc = (AbstractDocument) e.getOwnerDocument();
+        DefaultXBLManager xm = (DefaultXBLManager) doc.getXBLManager();
+        contentManager = xm.getContentManager(e);
+
+        if (cgn == null) {
+            cgn = new CompositeGraphicsNode();
+        } else {
+            int s = cgn.size();
+            for (int i = 0; i < s; i++) {
+                cgn.remove(0);
+            }
+        }
+
+        GVTBuilder builder = ctx.getGVTBuilder();
+        NodeList nl = contentManager.getSelectedContent(content);
+        if (nl != null) {
+            for (int i = 0; i < nl.getLength(); i++) {
+                Node n = nl.item(i);
+                if (n.getNodeType() == Node.ELEMENT_NODE) {
+                    GraphicsNode gn = builder.build(ctx, (Element) n);
+                    cgn.add(gn);
+                }
+            }
+        }
+
+        if (ctx.isDynamic()) {
+            if (contentChangedListener == null) {
+                // Should be the same ContentManager each build
+                contentChangedListener = new ContentChangedListener();
+                contentManager.addContentSelectionChangedListener
+                    (content, contentChangedListener);
+            }
+        }
+
+        return cgn;
+    }
+
+    /**
+     * Creates a <tt>CompositeGraphicsNode</tt>.
+     */
+    protected GraphicsNode instantiateGraphicsNode() {
+        // Not needed, since createGraphicsNode is overridden
+        return null;
+    }
+
+    /**
+     * Builds using the specified BridgeContext and element, the
+     * specified graphics node.
+     *
+     * @param ctx the bridge context to use
+     * @param e the element that describes the graphics node to build
+     * @param node the graphics node to build
+     */
+    public void buildGraphicsNode(BridgeContext ctx,
+                                  Element e,
+                                  GraphicsNode node) {
+        initializeDynamicSupport(ctx, e, node);
+    }
+
+    /**
+     * Returns true if the graphics node has to be displayed, false
+     * otherwise.
+     */
+    public boolean getDisplay(Element e) {
+        return true;
+    }
+
+    /**
+     * Returns false as the &lt;xbl:content&gt; element's selected nodes
+     * are built all in this class.
+     */
+    public boolean isComposite() {
+        return false;
+    }
+
+    /**
+     * Dispose this bridge by removing the ContentSelectionChangedListener
+     * object.
+     */
+    public void dispose() {
+        super.dispose();
+
+        if (contentChangedListener != null) {
+            contentManager.removeContentSelectionChangedListener
+                ((XBLOMContentElement) e, contentChangedListener);
+        }
+    }
+
+    /**
+     * Class to respond to content selection changes and cause GVT rebuilds.
+     */
+    protected class ContentChangedListener
+            implements ContentSelectionChangedListener {
+
+        /**
+         * Invoked after an xbl:content element has updated its selected
+         * nodes list.
+         * @param csce the ContentSelectionChangedEvent object
+         */
+        public void contentSelectionChanged(ContentSelectionChangedEvent csce) {
+            buildCompositeGraphicsNode(ctx, e, (CompositeGraphicsNode) node);
+        }
+    }
+}

Propchange: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/XBLContentElementBridge.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/XBLShadowTreeElementBridge.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/XBLShadowTreeElementBridge.java?rev=280553&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/XBLShadowTreeElementBridge.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/XBLShadowTreeElementBridge.java Tue Sep 13 06:29:29 2005
@@ -0,0 +1,174 @@
+/*
+
+   Copyright 2005  The Apache Software Foundation 
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.batik.bridge.svg12;
+
+import java.awt.RenderingHints;
+import java.awt.geom.Rectangle2D;
+
+import org.apache.batik.bridge.Bridge;
+import org.apache.batik.bridge.BridgeContext;
+import org.apache.batik.bridge.AbstractGraphicsNodeBridge;
+import org.apache.batik.bridge.GVTBuilder;
+import org.apache.batik.bridge.SVGUtilities;
+import org.apache.batik.dom.svg12.XBLOMTemplateElement;
+import org.apache.batik.util.XBLConstants;
+import org.apache.batik.gvt.CompositeGraphicsNode;
+import org.apache.batik.gvt.GraphicsNode;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.events.MutationEvent;
+
+/**
+ * Bridge class for the &lt;xbl:shadowTree&gt; element.
+ *
+ * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
+ * @version $Id$
+ */
+public class XBLShadowTreeElementBridge extends AbstractGraphicsNodeBridge {
+    
+    /**
+     * Constructs a new bridge for the &lt;xbl:shadowTree&gt; element.
+     */
+    public XBLShadowTreeElementBridge() {}
+
+    /**
+     * Returns 'shadowTree'.
+     */
+    public String getLocalName() {
+        return XBLConstants.XBL_SHADOW_TREE_TAG;
+    }
+
+    /**
+     * Returns the XBL namespace.
+     */
+    public String getNamespaceURI() {
+        return XBLConstants.XBL_NAMESPACE_URI;
+    }
+
+    /**
+     * Returns a new instance of this bridge.
+     */
+    public Bridge getInstance() {
+        return new XBLShadowTreeElementBridge();
+    }
+
+    /**
+     * Creates a <tt>GraphicsNode</tt> according to the specified parameters.
+     *
+     * @param ctx the bridge context to use
+     * @param e the element that describes the graphics node to build
+     * @return a graphics node that represents the specified element
+     */
+    public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) {
+        // 'requiredFeatures', 'requiredExtensions' and 'systemLanguage'
+        if (!SVGUtilities.matchUserAgent(e, ctx.getUserAgent())) {
+            return null;
+        }
+
+        return new CompositeGraphicsNode();
+    }
+
+    /**
+     * Creates a <tt>CompositeGraphicsNode</tt>.
+     */
+    protected GraphicsNode instantiateGraphicsNode() {
+        // Not needed, since createGraphicsNode is overridden
+        return null;
+    }
+
+    /**
+     * Builds using the specified BridgeContext and element, the
+     * specified graphics node.
+     *
+     * @param ctx the bridge context to use
+     * @param e the element that describes the graphics node to build
+     * @param node the graphics node to build
+     */
+    public void buildGraphicsNode(BridgeContext ctx,
+                                  Element e,
+                                  GraphicsNode node) {
+        initializeDynamicSupport(ctx, e, node);
+    }
+
+    /**
+     * Returns true if the graphics node has to be displayed, false
+     * otherwise.
+     */
+    public boolean getDisplay(Element e) {
+        return true;
+    }
+
+    /**
+     * Returns true as the &lt;xbl:template&gt; element is a container.
+     */
+    public boolean isComposite() {
+        return true;
+    }
+
+    // BridgeUpdateHandler implementation //////////////////////////////////
+
+    /**
+     * Invoked when an MutationEvent of type 'DOMNodeInserted' is fired.
+     */
+    public void handleDOMNodeInsertedEvent(MutationEvent evt) {
+        if (evt.getTarget() instanceof Element) {
+            handleElementAdded((CompositeGraphicsNode)node, 
+                               e, 
+                               (Element)evt.getTarget());
+        }
+    }
+
+    /**
+     * Invoked when an MutationEvent of type 'DOMNodeInserted' is fired.
+     */
+    public void handleElementAdded(CompositeGraphicsNode gn, 
+                                   Node parent, 
+                                   Element childElt) {
+        // build the graphics node
+        GVTBuilder builder = ctx.getGVTBuilder();
+        GraphicsNode childNode = builder.build(ctx, childElt);
+        if (childNode == null) {
+            return; // the added element is not a graphic element
+        }
+        
+        // Find the index where the GraphicsNode should be added
+        int idx = -1;
+        for(Node ps = childElt.getPreviousSibling(); ps != null;
+            ps = ps.getPreviousSibling()) {
+            if (ps.getNodeType() != Node.ELEMENT_NODE)
+                continue;
+            Element pse = (Element)ps;
+            GraphicsNode psgn = ctx.getGraphicsNode(pse);
+            while ((psgn != null) && (psgn.getParent() != gn)) {
+                // In some cases the GN linked is
+                // a child (in particular for images).
+                psgn = psgn.getParent();
+            }
+            if (psgn == null)
+                continue;
+            idx = gn.indexOf(psgn);
+            if (idx == -1)
+                continue;
+            break;
+        }
+        // insert after prevSibling, if
+        // it was -1 this becomes 0 (first slot)
+        idx++; 
+        gn.add(idx, childNode);
+    }
+}

Propchange: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/XBLShadowTreeElementBridge.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/XPathPatternContentSelector.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/XPathPatternContentSelector.java?rev=280553&view=auto
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/XPathPatternContentSelector.java (added)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/XPathPatternContentSelector.java Tue Sep 13 06:29:29 2005
@@ -0,0 +1,247 @@
+/*
+
+   Copyright 2005  The Apache Software Foundation 
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.batik.bridge.svg12;
+
+import java.util.ArrayList;
+
+import org.apache.batik.bridge.BridgeException;
+import org.apache.batik.bridge.ErrorConstants;
+import org.apache.batik.dom.AbstractDocument;
+import org.apache.batik.dom.svg12.XBLOMContentElement;
+import org.apache.batik.util.XBLConstants;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xpath.XPath;
+import org.apache.xpath.XPathContext;
+import org.apache.xpath.objects.XObject;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.xpath.XPathException;
+
+/**
+ * A class to handle the XPath Pattern syntax for XBL content elements.
+ *
+ * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
+ * @version $Id$
+ */
+public class XPathPatternContentSelector extends AbstractContentSelector {
+
+    /**
+     * The Xalan prefix resolver.
+     */
+    protected NSPrefixResolver prefixResolver = new NSPrefixResolver();
+
+    /**
+     * The XPath expression.
+     */
+    protected XPath xpath;
+
+    /**
+     * The XPath context.
+     */
+    protected XPathContext context;
+
+    /**
+     * The selected nodes.
+     */
+    protected SelectedNodes selectedContent;
+
+    /**
+     * The expression string.
+     */
+    protected String expression;
+
+    /**
+     * Creates a new XPathPatternContentSelector.
+     */
+    public XPathPatternContentSelector(ContentManager cm,
+                                       XBLOMContentElement content,
+                                       Element bound,
+                                       String selector) {
+        super(cm, content, bound);
+        try {
+            xpath = new XPath(selector, null, prefixResolver, XPath.MATCH);
+            context = new XPathContext();
+            expression = selector;
+        } catch (javax.xml.transform.TransformerException te) {
+            AbstractDocument doc
+                = (AbstractDocument) content.getOwnerDocument();
+            throw doc.createXPathException
+                (XPathException.INVALID_EXPRESSION_ERR,
+                 "xpath.invalid.expression",
+                 new Object[] { selector, te.getMessage() });
+        }
+    }
+
+    /**
+     * Returns a list of nodes that were matched by the given selector
+     * string.
+     */
+    public NodeList getSelectedContent() {
+        if (selectedContent == null) {
+            selectedContent = new SelectedNodes();
+        }
+        return selectedContent;
+    }
+
+    /**
+     * Forces this selector to update its selected nodes list.
+     * Returns true if the selected node list needed updating.
+     * This assumes that the previous content elements in this
+     * shadow tree (in document order) have up-to-date selectedContent
+     * lists.
+     */
+    boolean update() {
+        if (selectedContent == null) {
+            selectedContent = new SelectedNodes();
+            return true;
+        }
+        return selectedContent.update();
+    }
+
+    /**
+     * Implementation of NodeList that contains the nodes that matched
+     * this selector.
+     */
+    protected class SelectedNodes implements NodeList {
+
+        /**
+         * The selected nodes.
+         */
+        protected ArrayList nodes = new ArrayList(10);
+
+        /**
+         * Creates a new SelectedNodes object.
+         */
+        public SelectedNodes() {
+            update();
+        }
+
+        protected boolean update() {
+            ArrayList oldNodes = (ArrayList) nodes.clone();
+            nodes.clear();
+            for (Node n = boundElement.getFirstChild();
+                    n != null;
+                    n = n.getNextSibling()) {
+                update(n);
+            }
+            int nodesSize = nodes.size();
+            if (oldNodes.size() != nodesSize) {
+                return true;
+            }
+            for (int i = 0; i < nodesSize; i++) {
+                if (oldNodes.get(i) != nodes.get(i)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        protected boolean descendantSelected(Node n) {
+            n = n.getFirstChild();
+            while (n != null) {
+                if (isSelected(n) || descendantSelected(n)) {
+                    return true;
+                }
+                n = n.getNextSibling();
+            }
+            return false;
+        }
+
+        protected void update(Node n) {
+            if (!isSelected(n)) {
+                try {
+                    double matchScore
+                        = xpath.execute(context, n, prefixResolver).num();
+                    if (matchScore != XPath.MATCH_SCORE_NONE) {
+                        if (!descendantSelected(n)) {
+                            nodes.add(n);
+                        }
+                    } else {
+                        n = n.getFirstChild();
+                        while (n != null) {
+                            update(n);
+                            n = n.getNextSibling();
+                        }
+                    }
+                } catch (javax.xml.transform.TransformerException te) {
+                    AbstractDocument doc
+                        = (AbstractDocument) contentElement.getOwnerDocument();
+                    throw doc.createXPathException
+                        (XPathException.INVALID_EXPRESSION_ERR,
+                         "xpath.error",
+                         new Object[] { expression, te.getMessage() });
+                }
+            }
+        }
+
+        /**
+         * <b>DOM</b>: Implements {@link org.w3c.dom.NodeList#item(int)}.
+         */
+        public Node item(int index) {
+            if (index < 0 || index >= nodes.size()) {
+                return null;
+            }
+            return (Node) nodes.get(index);
+        }
+
+        /**
+         * <b>DOM</b>: Implements {@link org.w3c.dom.NodeList#getLength()}.
+         * @return {@link #children}.
+         */
+        public int getLength() {
+            return nodes.size();
+        }
+    }
+    /**
+     * Xalan prefix resolver.
+     */
+    protected class NSPrefixResolver implements PrefixResolver {
+
+        /**
+         * Get the base URI for this resolver.  Since this resolver isn't
+         * associated with a particular node, returns null.
+         */
+        public String getBaseIdentifier() {
+            return null;
+        }
+
+        /**
+         * Resolves the given namespace prefix.
+         */
+        public String getNamespaceForPrefix(String prefix) {
+            return contentElement.lookupNamespaceURI(prefix);
+        }
+
+        /**
+         * Resolves the given namespace prefix.
+         */
+        public String getNamespaceForPrefix(String prefix, Node context) {
+            // ignore the context node
+            return contentElement.lookupNamespaceURI(prefix);
+        }
+
+        /**
+         * Returns whether this PrefixResolver handles a null prefix.
+         */
+        public boolean handlesNullPrefixes() {
+            return false;
+        }
+    }
+}

Propchange: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/svg12/XPathPatternContentSelector.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision