/** * Count the immediate children of this node. Use to implement NodeList.getLength(). * * @return int */ private int nodeListGetLength() { if (fNodeListCache == null) { // get rid of trivial cases if (firstChild == null) { return 0; } if (firstChild == lastChild()) { return 1; } // otherwise request a cache object fNodeListCache = ownerDocument.getNodeListCache(this); } if (fNodeListCache.fLength == -1) { // is the cached length invalid ? int l; ChildNode n; // start from the cached node if we have one if (fNodeListCache.fChildIndex != -1 && fNodeListCache.fChild != null) { l = fNodeListCache.fChildIndex; n = fNodeListCache.fChild; } else { n = firstChild; l = 0; } while (n != null) { l++; n = n.nextSibling; } fNodeListCache.fLength = l; } return fNodeListCache.fLength; } // nodeListGetLength():int
/** * Return the Nth immediate child of this node, or null if the index is out of bounds. Use to * implement NodeList.item(). * * @param index int */ private Node nodeListItem(int index) { if (fNodeListCache == null) { // get rid of trivial case if (firstChild == lastChild()) { return index == 0 ? firstChild : null; } // otherwise request a cache object fNodeListCache = ownerDocument.getNodeListCache(this); } int i = fNodeListCache.fChildIndex; ChildNode n = fNodeListCache.fChild; boolean firstAccess = true; // short way if (i != -1 && n != null) { firstAccess = false; if (i < index) { while (i < index && n != null) { i++; n = n.nextSibling; } } else if (i > index) { while (i > index && n != null) { i--; n = n.previousSibling(); } } } else { // long way if (index < 0) { return null; } n = firstChild; for (i = 0; i < index && n != null; i++) { n = n.nextSibling; } } // release cache if reaching last child or first child if (!firstAccess && (n == firstChild || n == lastChild())) { fNodeListCache.fChildIndex = -1; fNodeListCache.fChild = null; ownerDocument.freeNodeListCache(fNodeListCache); // we can keep using the cache until it is actually reused // fNodeListCache will be nulled by the pool (document) if that // happens. // fNodeListCache = null; } else { // otherwise update it fNodeListCache.fChildIndex = i; fNodeListCache.fChild = n; } return n; } // nodeListItem(int):Node