You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by le...@apache.org on 2001/01/25 00:37:10 UTC
cvs commit: xml-xerces/java/src/org/apache/xerces/dom AttrImpl.java
lehors 01/01/24 15:37:10
Modified: java/src/org/apache/xerces/dom AttrImpl.java
Log:
fixed insertBefore and replaceChild to handle gracefully the
cases where a node is inserted before itself or is replaced by itself.
It was confirmed by the W3C DOM WG that the DOM spec allows these operations.
I also cleaned up a little internalInsertBefore.
Revision Changes Path
1.27 +154 -165 xml-xerces/java/src/org/apache/xerces/dom/AttrImpl.java
Index: AttrImpl.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/dom/AttrImpl.java,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- AttrImpl.java 2001/01/23 17:54:36 1.26
+++ AttrImpl.java 2001/01/24 23:37:09 1.27
@@ -633,49 +633,8 @@
Node internalInsertBefore(Node newChild, Node refChild,int mutationMask)
throws DOMException {
- if (isReadOnly())
- throw new DOMException(
- DOMException.NO_MODIFICATION_ALLOWED_ERR,
- "DOM001 Modification not allowed");
-
DocumentImpl ownerDocument = ownerDocument();
boolean errorChecking = ownerDocument.errorChecking;
- if (errorChecking && newChild.getOwnerDocument() != ownerDocument) {
- throw new DOMException(DOMException.WRONG_DOCUMENT_ERR,
- "DOM005 Wrong document");
- }
-
- if (needsSyncChildren()) {
- synchronizeChildren();
- }
-
- if (errorChecking) {
- // Prevent cycles in the tree
- // newChild cannot be ancestor of this Node,
- // and actually cannot be this
- boolean treeSafe = true;
- for (NodeImpl a = this;
- treeSafe && a != null;
- a = a.parentNode()) {
- treeSafe = newChild != a;
- }
- if(!treeSafe) {
- throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
- "DOM006 Hierarchy request error");
- }
-
- // refChild must in fact be a child of this node (or null)
- if(refChild != null && refChild.getParentNode() != this) {
- throw new DOMException(DOMException.NOT_FOUND_ERR,
- "DOM008 Not found");
- }
- // refChild cannot be same as newChild
- if(refChild == newChild) {
- throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
- "DOM006 Hierarchy request error");
- }
- }
-
if (newChild.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) {
// SLOW BUT SAFE: We could insert the whole subtree without
// juggling so many next/previous pointers. (Wipe out the
@@ -708,150 +667,180 @@
while (newChild.hasChildNodes()) {
insertBefore(newChild.getFirstChild(), refChild);
}
+ return newChild;
}
- else if (errorChecking &&
- (!(newChild instanceof ChildNode)
- ||
- !ownerDocument.isKidOK(this, newChild))) {
- throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
- "DOM006 Hierarchy request error");
+
+ if (newChild == refChild) {
+ // stupid case that must be handled as a no-op triggering events...
+ refChild = refChild.getNextSibling();
+ removeChild(newChild);
+ insertBefore(newChild, refChild);
+ return newChild;
}
- else {
- makeChildNode(); // make sure we have a node and not a string
- // Convert to internal type, to avoid repeated casting
- ChildNode newInternal = (ChildNode)newChild;
+ if (needsSyncChildren()) {
+ synchronizeChildren();
+ }
- EnclosingAttr enclosingAttr=null;
- if(MUTATIONEVENTS && ownerDocument.mutationEvents
- && (mutationMask&MUTATION_AGGREGATE)!=0)
- {
- // MUTATION PREPROCESSING
- // No direct pre-events, but if we're within the scope
- // of an Attr and DOMAttrModified was requested,
- // we need to preserve its previous value.
- LCount lc=LCount.lookup(MutationEventImpl.DOM_ATTR_MODIFIED);
- if(lc.captures+lc.bubbles+lc.defaults>0)
- {
- enclosingAttr=getEnclosingAttr();
- }
+ if (errorChecking) {
+ if (isReadOnly()) {
+ throw new DOMException(
+ DOMException.NO_MODIFICATION_ALLOWED_ERR,
+ "DOM001 Modification not allowed");
+ }
+ if (newChild.getOwnerDocument() != ownerDocument) {
+ throw new DOMException(DOMException.WRONG_DOCUMENT_ERR,
+ "DOM005 Wrong document");
+ }
+ if (!ownerDocument.isKidOK(this, newChild)) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
+ "DOM006 Hierarchy request error");
+ }
+ // refChild must be a child of this node (or null)
+ if (refChild != null && refChild.getParentNode() != this) {
+ throw new DOMException(DOMException.NOT_FOUND_ERR,
+ "DOM008 Not found");
}
- Node oldparent = newInternal.parentNode();
- if (oldparent != null) {
- oldparent.removeChild(newInternal);
+ // Prevent cycles in the tree
+ // newChild cannot be ancestor of this Node,
+ // and actually cannot be this
+ boolean treeSafe = true;
+ for (NodeImpl a = this; treeSafe && a != null; a = a.parentNode())
+ {
+ treeSafe = newChild != a;
+ }
+ if(!treeSafe) {
+ throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
+ "DOM006 Hierarchy request error");
}
+ }
- // Convert to internal type, to avoid repeated casting
- ChildNode refInternal = (ChildNode) refChild;
+ makeChildNode(); // make sure we have a node and not a string
- // Attach up
- newInternal.ownerNode = this;
- newInternal.isOwned(true);
+ // Convert to internal type, to avoid repeated casting
+ ChildNode newInternal = (ChildNode)newChild;
- // Attach before and after
- // Note: firstChild.previousSibling == lastChild!!
- ChildNode firstChild = (ChildNode) value;
- if (firstChild == null) {
- // this our first and only child
- value = newInternal; // firstchild = newInternal;
- newInternal.isFirstChild(true);
- newInternal.previousSibling = newInternal;
+ EnclosingAttr enclosingAttr=null;
+ if (MUTATIONEVENTS && ownerDocument.mutationEvents
+ && (mutationMask&MUTATION_AGGREGATE)!=0) {
+ // MUTATION PREPROCESSING
+ // No direct pre-events, but if we're within the scope
+ // of an Attr and DOMAttrModified was requested,
+ // we need to preserve its previous value.
+ LCount lc=LCount.lookup(MutationEventImpl.DOM_ATTR_MODIFIED);
+ if (lc.captures+lc.bubbles+lc.defaults>0) {
+ enclosingAttr=getEnclosingAttr();
+ }
+ }
+
+ Node oldparent = newInternal.parentNode();
+ if (oldparent != null) {
+ oldparent.removeChild(newInternal);
+ }
+
+ // Convert to internal type, to avoid repeated casting
+ ChildNode refInternal = (ChildNode) refChild;
+
+ // Attach up
+ newInternal.ownerNode = this;
+ newInternal.isOwned(true);
+
+ // Attach before and after
+ // Note: firstChild.previousSibling == lastChild!!
+ ChildNode firstChild = (ChildNode) value;
+ if (firstChild == null) {
+ // this our first and only child
+ value = newInternal; // firstchild = newInternal;
+ newInternal.isFirstChild(true);
+ newInternal.previousSibling = newInternal;
+ } else {
+ if (refInternal == null) {
+ // this is an append
+ ChildNode lastChild = firstChild.previousSibling;
+ lastChild.nextSibling = newInternal;
+ newInternal.previousSibling = lastChild;
+ firstChild.previousSibling = newInternal;
} else {
- if (refInternal == null) {
- // this is an append
- ChildNode lastChild = firstChild.previousSibling;
- lastChild.nextSibling = newInternal;
- newInternal.previousSibling = lastChild;
+ // this is an insert
+ if (refChild == firstChild) {
+ // at the head of the list
+ firstChild.isFirstChild(false);
+ newInternal.nextSibling = firstChild;
+ newInternal.previousSibling = firstChild.previousSibling;
firstChild.previousSibling = newInternal;
+ value = newInternal; // firstChild = newInternal;
+ newInternal.isFirstChild(true);
} else {
- // this is an insert
- if (refChild == firstChild) {
- // at the head of the list
- firstChild.isFirstChild(false);
- newInternal.nextSibling = firstChild;
- newInternal.previousSibling =
- firstChild.previousSibling;
- firstChild.previousSibling = newInternal;
- value = newInternal; // firstChild = newInternal;
- newInternal.isFirstChild(true);
- } else {
- // somewhere in the middle
- ChildNode prev = refInternal.previousSibling;
- newInternal.nextSibling = refInternal;
- prev.nextSibling = newInternal;
- refInternal.previousSibling = newInternal;
- newInternal.previousSibling = prev;
- }
+ // somewhere in the middle
+ ChildNode prev = refInternal.previousSibling;
+ newInternal.nextSibling = refInternal;
+ prev.nextSibling = newInternal;
+ refInternal.previousSibling = newInternal;
+ newInternal.previousSibling = prev;
}
}
+ }
- changed();
+ changed();
- if(MUTATIONEVENTS && ownerDocument.mutationEvents)
- {
- // MUTATION POST-EVENTS:
- // "Local" events (non-aggregated)
- if( (mutationMask&MUTATION_LOCAL) != 0)
- {
- // New child is told it was inserted, and where
- LCount lc =
- LCount.lookup(MutationEventImpl.DOM_NODE_INSERTED);
- if(lc.captures+lc.bubbles+lc.defaults>0)
- {
- MutationEvent me= new MutationEventImpl();
- me.initMutationEvent(
- MutationEventImpl.DOM_NODE_INSERTED,
- true,false,this,null,
- null,null,(short)0);
- newInternal.dispatchEvent(me);
- }
+ if (MUTATIONEVENTS && ownerDocument.mutationEvents) {
+ // MUTATION POST-EVENTS:
+ // "Local" events (non-aggregated)
+ if ((mutationMask&MUTATION_LOCAL) != 0) {
+ // New child is told it was inserted, and where
+ LCount lc = LCount.lookup(MutationEventImpl.DOM_NODE_INSERTED);
+ if (lc.captures+lc.bubbles+lc.defaults>0) {
+ MutationEvent me= new MutationEventImpl();
+ me.initMutationEvent(MutationEventImpl.DOM_NODE_INSERTED,
+ true,false,this,null,
+ null,null,(short)0);
+ newInternal.dispatchEvent(me);
+ }
- // If within the Document, tell the subtree it's been added
- // to the Doc.
- lc=LCount.lookup(
+ // If within the Document, tell the subtree it's been added
+ // to the Doc.
+ lc=LCount.lookup(
MutationEventImpl.DOM_NODE_INSERTED_INTO_DOCUMENT);
- if(lc.captures+lc.bubbles+lc.defaults>0)
- {
- NodeImpl eventAncestor=this;
- if(enclosingAttr!=null)
- eventAncestor=
- (NodeImpl)(enclosingAttr.node.getOwnerElement());
- if(eventAncestor!=null) // Might have been orphan Attr
- {
- NodeImpl p=eventAncestor;
- while(p!=null)
- {
- eventAncestor=p; // Last non-null ancestor
- // In this context, ancestry includes
- // walking back from Attr to Element
- if(p.getNodeType()==ATTRIBUTE_NODE)
- p=(ElementImpl)
- ((AttrImpl)p).getOwnerElement();
- else
- p=p.parentNode();
+ if (lc.captures+lc.bubbles+lc.defaults>0) {
+ NodeImpl eventAncestor=this;
+ if (enclosingAttr!=null)
+ eventAncestor=
+ (NodeImpl)(enclosingAttr.node.getOwnerElement());
+ if (eventAncestor!=null) { // Might have been orphan Attr
+ NodeImpl p=eventAncestor;
+ while (p!=null) {
+ eventAncestor=p; // Last non-null ancestor
+ // In this context, ancestry includes
+ // walking back from Attr to Element
+ if (p.getNodeType()==ATTRIBUTE_NODE) {
+ p=(ElementImpl)((AttrImpl)p).getOwnerElement();
}
- if(eventAncestor.getNodeType()==Node.DOCUMENT_NODE)
- {
- MutationEvent me= new MutationEventImpl();
- me.initMutationEvent(MutationEventImpl
- .DOM_NODE_INSERTED_INTO_DOCUMENT,
- false,false,null,null,
- null,null,(short)0);
- dispatchEventToSubtree(newInternal,me);
+ else {
+ p=p.parentNode();
}
}
+ if (eventAncestor.getNodeType()==Node.DOCUMENT_NODE) {
+ MutationEvent me= new MutationEventImpl();
+ me.initMutationEvent(MutationEventImpl
+ .DOM_NODE_INSERTED_INTO_DOCUMENT,
+ false,false,null,null,
+ null,null,(short)0);
+ dispatchEventToSubtree(newInternal,me);
+ }
}
}
-
- // Subroutine: Transmit DOMAttrModified and DOMSubtreeModified
- // (Common to most kinds of mutation)
- if( (mutationMask&MUTATION_AGGREGATE) != 0)
- dispatchAggregateEvents(enclosingAttr);
}
- checkNormalizationAfterInsert(newInternal);
+ // Subroutine: Transmit DOMAttrModified and DOMSubtreeModified
+ // (Common to most kinds of mutation)
+ if ((mutationMask&MUTATION_AGGREGATE) != 0) {
+ dispatchAggregateEvents(enclosingAttr);
+ }
}
+
+ checkNormalizationAfterInsert(newInternal);
+
return newChild;
} // internalInsertBefore(Node,Node,int):Node
@@ -1066,7 +1055,9 @@
} // End mutation preprocessing
internalInsertBefore(newChild, oldChild,MUTATION_LOCAL);
- internalRemoveChild(oldChild,MUTATION_LOCAL);
+ if (newChild != oldChild) {
+ internalRemoveChild(oldChild,MUTATION_LOCAL);
+ }
if(MUTATIONEVENTS && ownerDocument.mutationEvents)
{
@@ -1115,13 +1106,11 @@
return (Node) value;
}
}
- ChildNode nodeListNode = (ChildNode) value;
- for (int nodeListIndex = 0;
- nodeListIndex < index && nodeListNode != null;
- nodeListIndex++) {
- nodeListNode = nodeListNode.nextSibling;
+ ChildNode node = (ChildNode) value;
+ for (int i = 0; i < index && node != null; i++) {
+ node = node.nextSibling;
}
- return nodeListNode;
+ return node;
} // item(int):Node