diff options
Diffstat (limited to 'gnu/xml/dom/DomNode.java')
-rw-r--r-- | gnu/xml/dom/DomNode.java | 142 |
1 files changed, 57 insertions, 85 deletions
diff --git a/gnu/xml/dom/DomNode.java b/gnu/xml/dom/DomNode.java index 3f29fb128..5cd5be269 100644 --- a/gnu/xml/dom/DomNode.java +++ b/gnu/xml/dom/DomNode.java @@ -38,6 +38,7 @@ exception statement from your version. */ package gnu.xml.dom; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.Map; @@ -149,7 +150,7 @@ public abstract class DomNode boolean readonly; // event registrations - private ListenerRecord[] listeners; + private HashSet listeners; private int nListeners; // DOM Level 3 userData dictionary. @@ -167,19 +168,6 @@ public abstract class DomNode */ public void compact() { - if (listeners != null && listeners.length != nListeners) - { - if (nListeners == 0) - { - listeners = null; - } - else - { - ListenerRecord[] l = new ListenerRecord[nListeners]; - System.arraycopy(listeners, 0, l, 0, nListeners); - listeners = l; - } - } } /** @@ -201,6 +189,7 @@ public abstract class DomNode } } this.owner = owner; + this.listeners = new HashSet(); } @@ -372,6 +361,16 @@ public abstract class DomNode return; } break; + case DOCUMENT_TYPE_NODE: + if (!owner.building) + break; + switch (childNodeType) + { + case COMMENT_NODE: + case PROCESSING_INSTRUCTION_NODE: + return; + } + break; } if (owner.checkingWellformedness) { @@ -960,12 +959,6 @@ public abstract class DomNode */ public void trimToSize() { - if (listeners != null && listeners.length != nListeners) - { - ListenerRecord[] newKids = new ListenerRecord[length]; - System.arraycopy(listeners, 0, newKids, 0, nListeners); - listeners = newKids; - } } /** @@ -1175,7 +1168,7 @@ public abstract class DomNode node.next = null; node.readonly = false; - node.listeners = null; + node.listeners = new HashSet(); node.nListeners = 0; return node; @@ -1264,16 +1257,17 @@ public abstract class DomNode elementName = name; matchAnyURI = "*".equals(uri); matchAnyName = "*".equals(name); - + DomNode.this.addEventListener("DOMNodeInserted", this, true); DomNode.this.addEventListener("DOMNodeRemoved", this, true); } void detach() { - current.detach(); + if (current != null) + current.detach(); current = null; - + DomNode.this.removeEventListener("DOMNodeInserted", this, true); DomNode.this.removeEventListener("DOMNodeRemoved", this, true); } @@ -1336,6 +1330,8 @@ public abstract class DomNode return; } + if (current != null) + current.detach(); current = null; } @@ -1354,6 +1350,7 @@ public abstract class DomNode lastIndex--; } Node ret = current.previousNode (); + current.detach(); current = null; return ret; } @@ -1361,9 +1358,11 @@ public abstract class DomNode // somewhere after last node while (++lastIndex != index) current.nextNode (); - Node ret = current.nextNode (); - current = null; - return ret; + + Node ret = current.nextNode (); + current.detach(); + current = null; + return ret; } public int getLength() @@ -1375,7 +1374,7 @@ public abstract class DomNode { retval++; } - current = null; + iter.detach(); return retval; } @@ -1403,13 +1402,18 @@ public abstract class DomNode this.useCapture = useCapture; } - boolean equals(ListenerRecord rec) + public boolean equals(Object o) { + ListenerRecord rec = (ListenerRecord)o; return listener == rec.listener && useCapture == rec.useCapture && type == rec.type; } + public int hashCode() + { + return listener.hashCode() ^ type.hashCode(); + } } /** @@ -1464,30 +1468,12 @@ public abstract class DomNode EventListener listener, boolean useCapture) { - if (listeners == null) - { - listeners = new ListenerRecord[1]; - } - else if (nListeners == listeners.length) - { - ListenerRecord[] newListeners = - new ListenerRecord[listeners.length + NKIDS_DELTA]; - System.arraycopy(listeners, 0, newListeners, 0, nListeners); - listeners = newListeners; - } - // prune duplicates ListenerRecord record; record = new ListenerRecord(type, listener, useCapture); - for (int i = 0; i < nListeners; i++) - { - if (record.equals(listeners[i])) - { - return; - } - } - listeners [nListeners++] = record; + listeners.add(record); + nListeners = listeners.size(); } // XXX this exception should be discarded from DOM @@ -1672,11 +1658,14 @@ public abstract class DomNode ListenerRecord[] notificationSet) { int count = 0; + Iterator iter; + + iter = current.listeners.iterator(); // do any of this set of listeners get notified? - for (int i = 0; i < current.nListeners; i++) + while (iter.hasNext()) { - ListenerRecord rec = current.listeners[i]; + ListenerRecord rec = (ListenerRecord)iter.next(); if (rec.useCapture != capture) { @@ -1697,6 +1686,7 @@ public abstract class DomNode } notificationSet[count++] = rec; } + iter = null; // Notify just those listeners e.currentNode = current; @@ -1704,18 +1694,21 @@ public abstract class DomNode { try { + iter = current.listeners.iterator(); // Late in the DOM CR process (3rd or 4th CR?) the // removeEventListener spec became asymmetric with respect // to addEventListener ... effect is now immediate. - for (int j = 0; j < current.nListeners; j++) + while (iter.hasNext()) { - if (current.listeners[j].equals(notificationSet[i])) + ListenerRecord rec = (ListenerRecord)iter.next(); + + if (rec.equals(notificationSet[i])) { notificationSet[i].listener.handleEvent(e); break; } } - + iter = null; } catch (Exception x) { @@ -1733,36 +1726,8 @@ public abstract class DomNode EventListener listener, boolean useCapture) { - for (int i = 0; i < nListeners; i++) - { - if (listeners[i].listener != listener) - { - continue; - } - if (listeners[i].useCapture != useCapture) - { - continue; - } - if (!listeners[i].type.equals(type)) - { - continue; - } - - if (nListeners == 1) - { - listeners = null; - nListeners = 0; - } - else - { - for (int j = i + 1; j < nListeners; j++) - { - listeners[i++] = listeners[j++]; - } - listeners[--nListeners] = null; - } - break; - } + listeners.remove(new ListenerRecord(type, listener, useCapture)); + nListeners = listeners.size(); // no exceptions reported } @@ -1779,6 +1744,8 @@ public abstract class DomNode readonly = false; for (DomNode ctx = first; ctx != null; ctx = ctx.next) { + boolean saved2 = ctx.readonly; + ctx.readonly = false; switch (ctx.nodeType) { case TEXT_NODE: @@ -1794,7 +1761,11 @@ public abstract class DomNode int len = attrs.getLength(); for (int i = 0; i < len; i++) { - attrs.item(i).normalize(); + DomNode attr = (DomNode) attrs.item(i); + boolean saved3 = attr.readonly; + attr.readonly = false; + attr.normalize(); + attr.readonly = saved3; } // Fall through case DOCUMENT_NODE: @@ -1804,6 +1775,7 @@ public abstract class DomNode ctx.normalize(); break; } + ctx.readonly = saved2; } readonly = saved; } |