documentimpl.java
来自「JAVA的一些源码 JAVA2 STANDARD EDITION DEVELO」· Java 代码 · 共 1,275 行 · 第 1/4 页
JAVA
1,275 行
void removeNodeIterator(NodeIterator nodeIterator) { if (nodeIterator == null) return; if (iterators == null) return; iterators.removeElement(nodeIterator); } // // DocumentRange methods // /** */ public Range createRange() { if (ranges == null) { ranges = new Vector(); } Range range = new RangeImpl(this); ranges.addElement(range); return range; } /** Not a client function. Called by Range.detach(), * so a Range can remove itself from the list of * Ranges. */ void removeRange(Range range) { if (range == null) return; if (ranges == null) return; ranges.removeElement(range); } /** * A method to be called when some text was changed in a text node, * so that live objects can be notified. */ void replacedText(NodeImpl node) { // notify ranges if (ranges != null) { 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 { 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; else ++lc.bubbles; } // 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; else --lc.bubbles; 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:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?