//------------------------------------------------------------ // Helper function to see if the next/prev node should be skipped void nsFilteredContentIterator::CheckAdvNode(nsIDOMNode* aNode, bool& aDidSkip, eDirectionType aDir) { aDidSkip = false; mIsOutOfRange = false; if (aNode && mFilter) { nsCOMPtr<nsIDOMNode> currentNode = aNode; bool skipIt; while (1) { nsresult rv = mFilter->Skip(aNode, &skipIt); if (NS_SUCCEEDED(rv) && skipIt) { aDidSkip = true; // Get the next/prev node and then // see if we should skip that nsCOMPtr<nsIDOMNode> advNode; rv = AdvanceNode(aNode, *getter_AddRefs(advNode), aDir); if (NS_SUCCEEDED(rv) && advNode) { aNode = advNode; } else { return; // fell out of range } } else { if (aNode != currentNode) { nsCOMPtr<nsIContent> content(do_QueryInterface(aNode)); mCurrentIterator->PositionAt(content); } return; // found something } } } }
// Helper function to advance to the next or previous node nsresult FilteredContentIterator::AdvanceNode(nsINode* aNode, nsINode*& aNewNode, eDirectionType aDir) { nsCOMPtr<nsIContent> nextNode; if (aDir == eForward) { nextNode = aNode->GetNextSibling(); } else { nextNode = aNode->GetPreviousSibling(); } if (nextNode) { // If we got here, that means we found the nxt/prv node // make sure it is in our DOMRange bool intersects = ContentIsInTraversalRange(mRange, nextNode, aDir == eForward); if (intersects) { aNewNode = nextNode; NS_ADDREF(aNewNode); return NS_OK; } } else { // The next node was null so we need to walk up the parent(s) nsCOMPtr<nsINode> parent = aNode->GetParentNode(); NS_ASSERTION(parent, "parent can't be nullptr"); // Make sure the parent is in the DOMRange before going further // XXXbz why are we passing nextNode, not the parent??? If this gets fixed, // then ContentIsInTraversalRange can stop null-checking its second arg. bool intersects = ContentIsInTraversalRange(mRange, nextNode, aDir == eForward); if (intersects) { // Now find the nxt/prv node after/before this node nsresult rv = AdvanceNode(parent, aNewNode, aDir); if (NS_SUCCEEDED(rv) && aNewNode) { return NS_OK; } } } // if we get here it pretty much means // we went out of the DOM Range mIsOutOfRange = true; return NS_ERROR_FAILURE; }
//------------------------------------------------------------ // Helper function to advance to the next or previous node nsresult nsFilteredContentIterator::AdvanceNode(nsIDOMNode* aNode, nsIDOMNode*& aNewNode, eDirectionType aDir) { nsCOMPtr<nsIDOMNode> nextNode; if (aDir == eForward) { aNode->GetNextSibling(getter_AddRefs(nextNode)); } else { aNode->GetPreviousSibling(getter_AddRefs(nextNode)); } if (nextNode) { // If we got here, that means we found the nxt/prv node // make sure it is in our DOMRange bool intersects = ContentIsInTraversalRange(mRange, nextNode, aDir == eForward); if (intersects) { aNewNode = nextNode; NS_ADDREF(aNewNode); return NS_OK; } } else { // The next node was null so we need to walk up the parent(s) nsCOMPtr<nsIDOMNode> parent; aNode->GetParentNode(getter_AddRefs(parent)); NS_ASSERTION(parent, "parent can't be NULL"); // Make sure the parent is in the DOMRange before going further bool intersects = ContentIsInTraversalRange(mRange, nextNode, aDir == eForward); if (intersects) { // Now find the nxt/prv node after/before this node nsresult rv = AdvanceNode(parent, aNewNode, aDir); if (NS_SUCCEEDED(rv) && aNewNode) { return NS_OK; } } } // if we get here it pretty much means // we went out of the DOM Range mIsOutOfRange = true; return NS_ERROR_FAILURE; }
static void BuildLoop(ThreadState* thread_state) { BuildQueue *queue = thread_state->m_Queue; ConditionVariable *cv = &queue->m_WorkAvailable; Mutex *mutex = &queue->m_Lock; MutexLock(mutex); while (ShouldKeepBuilding(queue, thread_state->m_ThreadIndex)) { if (NodeState* node = NextNode(queue)) { AdvanceNode(queue, thread_state, node, mutex); } else { CondWait(cv, mutex); } } MutexUnlock(mutex); Log(kSpam, "build thread %d exiting\n", thread_state->m_ThreadIndex); }