/** * NON-DOM INTERNAL: Within DOM actions,we sometimes need to be able to control which mutation * events are spawned. This version of the removeChild operation allows us to do so. It is not * intended for use by application programs. */ Node internalRemoveChild(Node oldChild, boolean replace) throws DOMException { CoreDocumentImpl ownerDocument = ownerDocument(); if (ownerDocument.errorChecking) { if (isReadOnly()) { throw new DOMException( DOMException.NO_MODIFICATION_ALLOWED_ERR, DOMMessageFormatter.formatMessage( DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null)); } if (oldChild != null && oldChild.getParentNode() != this) { throw new DOMException( DOMException.NOT_FOUND_ERR, DOMMessageFormatter.formatMessage( DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null)); } } ChildNode oldInternal = (ChildNode) oldChild; // notify document ownerDocument.removingNode(this, oldInternal, replace); // update cached length if we have any if (fNodeListCache != null) { if (fNodeListCache.fLength != -1) { fNodeListCache.fLength--; } if (fNodeListCache.fChildIndex != -1) { // if the removed node is the cached node // move the cache to its (soon former) previous sibling if (fNodeListCache.fChild == oldInternal) { fNodeListCache.fChildIndex--; fNodeListCache.fChild = oldInternal.previousSibling(); } else { // otherwise just invalidate the cache fNodeListCache.fChildIndex = -1; } } } // Patch linked list around oldChild // Note: lastChild == firstChild.previousSibling if (oldInternal == firstChild) { // removing first child oldInternal.isFirstChild(false); firstChild = oldInternal.nextSibling; if (firstChild != null) { firstChild.isFirstChild(true); firstChild.previousSibling = oldInternal.previousSibling; } } else { ChildNode prev = oldInternal.previousSibling; ChildNode next = oldInternal.nextSibling; prev.nextSibling = next; if (next == null) { // removing last child firstChild.previousSibling = prev; } else { // removing some other child in the middle next.previousSibling = prev; } } // Save previous sibling for normalization checking. ChildNode oldPreviousSibling = oldInternal.previousSibling(); // Remove oldInternal's references to tree oldInternal.ownerNode = ownerDocument; oldInternal.isOwned(false); oldInternal.nextSibling = null; oldInternal.previousSibling = null; changed(); // notify document ownerDocument.removedNode(this, replace); checkNormalizationAfterRemove(oldPreviousSibling); return oldInternal; } // internalRemoveChild(Node,boolean):Node