documentimpl.java

来自「JAVA 所有包」· Java 代码 · 共 1,302 行 · 第 1/4 页

JAVA
1,302
字号
            int size = ranges.size();            for (int i = 0; i != size; i++) {                ((RangeImpl)ranges.elementAt(i)).receiveReplacedText(node);            }        }    }    /**     * A method to be called when some text was deleted from a text node,     * so that live objects can be notified.     */    void deletedText(NodeImpl node, int offset, int count) {        // notify ranges        if (ranges != null) {            int size = ranges.size();            for (int i = 0; i != size; i++) {                ((RangeImpl)ranges.elementAt(i)).receiveDeletedText(node,                                                                offset, count);            }        }    }    /**     * A method to be called when some text was inserted into a text node,     * so that live objects can be notified.     */    void insertedText(NodeImpl node, int offset, int count) {        // notify ranges        if (ranges != null) {            int size = ranges.size();            for (int i = 0; i != size; i++) {                ((RangeImpl)ranges.elementAt(i)).receiveInsertedText(node,                                                                offset, count);            }        }    }    /**     * A method to be called when a text node has been split,     * so that live objects can be notified.     */    void splitData(Node node, Node newNode, int offset) {        // notify ranges        if (ranges != null) {            int size = ranges.size();            for (int i = 0; i != size; i++) {                ((RangeImpl)ranges.elementAt(i)).receiveSplitData(node,                                                              newNode, offset);            }        }    }    //    // DocumentEvent methods    //    /**     * Introduced in DOM Level 2. Optional. <p>     * Create and return Event objects.     *     * @param type The eventType parameter specifies the type of Event     * interface to be created.  If the Event interface specified is supported     * by the implementation this method will return a new Event of the     * interface type requested. If the Event is to be dispatched via the     * dispatchEvent method the appropriate event init method must be called     * after creation in order to initialize the Event's values.  As an     * example, a user wishing to synthesize some kind of Event would call     * createEvent with the parameter "Events". The initEvent method could then     * be called on the newly created Event to set the specific type of Event     * to be dispatched and set its context information.     * @return Newly created Event     * @exception DOMException NOT_SUPPORTED_ERR: Raised if the implementation     * does not support the type of Event interface requested     * @since WD-DOM-Level-2-19990923     */    public Event createEvent(String type)	throws DOMException {	    if (type.equalsIgnoreCase("Events") || "Event".equals(type))	        return new EventImpl();	    if (type.equalsIgnoreCase("MutationEvents") ||                "MutationEvent".equals(type))	        return new MutationEventImpl();	    else {            String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_SUPPORTED_ERR", null);	        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);        }	}    /**     * Sets whether the DOM implementation generates mutation events     * upon operations.     */    void setMutationEvents(boolean set) {        mutationEvents = set;    }    /**     * Returns true if the DOM implementation generates mutation events.     */    boolean getMutationEvents() {        return mutationEvents;    }    /**     * Store event listener registered on a given node     * This is another place where we could use weak references! Indeed, the     * node here won't be GC'ed as long as some listener is registered on it,     * since the eventsListeners table will have a reference to the node.     */    protected void setEventListeners(NodeImpl n, Vector listeners) {        if (eventListeners == null) {            eventListeners = new Hashtable();        }        if (listeners == null) {            eventListeners.remove(n);            if (eventListeners.isEmpty()) {                // stop firing events when there isn't any listener                mutationEvents = false;            }        } else {            eventListeners.put(n, listeners);            // turn mutation events on            mutationEvents = true;        }    }    /**     * Retreive event listener registered on a given node     */    protected Vector getEventListeners(NodeImpl n) {        if (eventListeners == null) {            return null;        }        return (Vector) eventListeners.get(n);    }    //    // EventTarget support (public and internal)    //    //    // Constants    //    /*     * NON-DOM INTERNAL: Class LEntry is just a struct used to represent     * event listeners registered with this node. Copies of this object     * are hung from the nodeListeners Vector.     * <p>     * I considered using two vectors -- one for capture,     * one for bubble -- but decided that since the list of listeners      * is probably short in most cases, it might not be worth spending     * the space. ***** REVISIT WHEN WE HAVE MORE EXPERIENCE.     */    class LEntry implements Serializable {        private static final long serialVersionUID = 3258416144514626360L;        String type;        EventListener listener;        boolean useCapture;	            /** NON-DOM INTERNAL: Constructor for Listener list Entry          * @param type Event name (NOT event group!) to listen for.         * @param listener Who gets called when event is dispatched         * @param useCaptue True iff listener is registered on         *  capturing phase rather than at-target or bubbling         */        LEntry(String type, EventListener listener, boolean useCapture)        {            this.type = type;            this.listener = listener;            this.useCapture = useCapture;        }    } // LEntry	    /**     * Introduced in DOM Level 2. <p> Register an event listener with this     * Node. A listener may be independently registered as both Capturing and     * Bubbling, but may only be registered once per role; redundant     * registrations are ignored.     * @param node node to add listener to     * @param type Event name (NOT event group!) to listen for.     * @param listener Who gets called when event is dispatched     * @param useCapture True iff listener is registered on     *  capturing phase rather than at-target or bubbling     */    protected void addEventListener(NodeImpl node, String type,                                    EventListener listener, boolean useCapture)    {        // We can't dispatch to blank type-name, and of course we need        // a listener to dispatch to        if (type == null || type.equals("") || listener == null)            return;              // Each listener may be registered only once per type per phase.        // Simplest way to code that is to zap the previous entry, if any.        removeEventListener(node, type, listener, useCapture);	            Vector nodeListeners = getEventListeners(node);        if(nodeListeners == null) {            nodeListeners = new Vector();            setEventListeners(node, nodeListeners);        }        nodeListeners.addElement(new LEntry(type, listener, useCapture));	            // Record active listener        LCount lc = LCount.lookup(type);        if (useCapture) {            ++lc.captures;            ++lc.total;        }        else {            ++lc.bubbles;            ++lc.total;        }    } // addEventListener(NodeImpl,String,EventListener,boolean) :void	    /**     * Introduced in DOM Level 2. <p> Deregister an event listener previously     * registered with this Node.  A listener must be independently removed     * from the Capturing and Bubbling roles. Redundant removals (of listeners     * not currently registered for this role) are ignored.     * @param node node to remove listener from     * @param type Event name (NOT event group!) to listen for.     * @param listener Who gets called when event is dispatched     * @param useCapture True iff listener is registered on     *  capturing phase rather than at-target or bubbling     */    protected void removeEventListener(NodeImpl node, String type,                                       EventListener listener,                                       boolean useCapture)    {        // If this couldn't be a valid listener registration, ignore request        if (type == null || type.equals("") || listener == null)            return;        Vector nodeListeners = getEventListeners(node);        if (nodeListeners == null)            return;        // Note that addListener has previously ensured that         // each listener may be registered only once per type per phase.        // count-down is OK for deletions!        for (int i = nodeListeners.size() - 1; i >= 0; --i) {            LEntry le = (LEntry) nodeListeners.elementAt(i);            if (le.useCapture == useCapture && le.listener == listener &&                 le.type.equals(type)) {                nodeListeners.removeElementAt(i);                // Storage management: Discard empty listener lists                if (nodeListeners.size() == 0)                    setEventListeners(node, null);                // Remove active listener                LCount lc = LCount.lookup(type);                if (useCapture) {                    --lc.captures;                    --lc.total;                }                else {                    --lc.bubbles;                    --lc.total;                }                break;  // Found it; no need to loop farther.            }        }    } // removeEventListener(NodeImpl,String,EventListener,boolean) :void    protected void copyEventListeners(NodeImpl src, NodeImpl tgt) {        Vector nodeListeners = getEventListeners(src);	if (nodeListeners == null) {	    return;	}	setEventListeners(tgt, (Vector) nodeListeners.clone());    }    /**     * Introduced in DOM Level 2. <p>     * Distribution engine for DOM Level 2 Events.      * <p>     * Event propagation runs as follows:     * <ol>     * <li>Event is dispatched to a particular target node, which invokes     *   this code. Note that the event's stopPropagation flag is     *   cleared when dispatch begins; thereafter, if it has      *   been set before processing of a node commences, we instead     *   immediately advance to the DEFAULT phase.     * <li>The node's ancestors are established as destinations for events.     *   For capture and bubble purposes, node ancestry is determined at      *   the time dispatch starts. If an event handler alters the document      *   tree, that does not change which nodes will be informed of the event.      * <li>CAPTURING_PHASE: Ancestors are scanned, root to target, for      *   Capturing listeners. If found, they are invoked (see below).      * <li>AT_TARGET:      *   Event is dispatched to NON-CAPTURING listeners on the     *   target node. Note that capturing listeners on this node are _not_     *   invoked.     * <li>BUBBLING_PHASE: Ancestors are scanned, target to root, for     *   non-capturing listeners.      * <li>Default processing: Some DOMs have default behaviors bound to     *   specific nodes. If this DOM does, and if the event's preventDefault     *   flag has not been set, we now return to the target node and process     *   its default handler for this event, if any.     * </ol>     * <p>     * Note that registration of handlers during processing of an event does     * not take effect during this phase of this event; they will not be called     * until the next time this node is visited by dispatchEvent. On the other     * hand, removals take effect immediately.     * <p>     * If an event handler itself causes events to be dispatched, they are     * processed synchronously, before processing resumes     * on the event which triggered them. Please be aware that this may      * result in events arriving at listeners "out of order" relative     * to the actual sequence of requests.     * <p>     * Note that our implementation resets the event's stop/prevent flags     * when dispatch begins.     * I believe the DOM's intent is that event objects be redispatchable,     * though it isn't stated in those terms.     * @param node node to dispatch to     * @param event the event object to be dispatched to      *              registered EventListeners     * @return true if the event's <code>preventDefault()</code>     *              method was invoked by an EventListener; otherwise false.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?