void ScrollingTree::updateTreeFromStateNode(const ScrollingStateNode* stateNode) { if (!stateNode) { m_nodeMap.clear(); m_rootNode = nullptr; return; } // This fuction recurses through the ScrollingStateTree and updates the corresponding ScrollingTreeNodes. // Find the ScrollingTreeNode associated with the current stateNode using the shared ID and our HashMap. ScrollingTreeNodeMap::const_iterator it = m_nodeMap.find(stateNode->scrollingNodeID()); ScrollingTreeNode* node; if (it != m_nodeMap.end()) { node = it->value; node->updateBeforeChildren(*stateNode); } else { // If the node isn't found, it's either new and needs to be added to the tree, or there is a new ID for our // root node. ScrollingNodeID nodeID = stateNode->scrollingNodeID(); if (!stateNode->parent()) { // This is the root node. Nuke the node map. m_nodeMap.clear(); m_rootNode = static_pointer_cast<ScrollingTreeScrollingNode>(createNode(FrameScrollingNode, nodeID)); m_nodeMap.set(nodeID, m_rootNode.get()); m_rootNode->updateBeforeChildren(*stateNode); node = m_rootNode.get(); } else { OwnPtr<ScrollingTreeNode> newNode = createNode(stateNode->nodeType(), nodeID); node = newNode.get(); m_nodeMap.set(nodeID, node); ScrollingTreeNodeMap::const_iterator it = m_nodeMap.find(stateNode->parent()->scrollingNodeID()); ASSERT(it != m_nodeMap.end()); if (it != m_nodeMap.end()) { ScrollingTreeNode* parent = it->value; newNode->setParent(parent); parent->appendChild(newNode.release()); } node->updateBeforeChildren(*stateNode); } } // Now update the children if we have any. Vector<OwnPtr<ScrollingStateNode>>* stateNodeChildren = stateNode->children(); if (stateNodeChildren) { size_t size = stateNodeChildren->size(); for (size_t i = 0; i < size; ++i) updateTreeFromStateNode(stateNodeChildren->at(i).get()); } node->updateAfterChildren(*stateNode); }