Example #1
0
void ScrollingTree::updateTreeFromStateNode(const ScrollingStateNode* stateNode, OrphanScrollingNodeMap& orphanNodes)
{
    if (!stateNode) {
        m_nodeMap.clear();
        m_rootNode = nullptr;
        return;
    }
    
    ScrollingNodeID nodeID = stateNode->scrollingNodeID();
    ScrollingNodeID parentNodeID = stateNode->parentNodeID();

    auto it = m_nodeMap.find(nodeID);

    RefPtr<ScrollingTreeNode> node;
    if (it != m_nodeMap.end())
        node = it->value;
    else {
        node = createScrollingTreeNode(stateNode->nodeType(), nodeID);
        if (!parentNodeID) {
            // This is the root node. Clear the node map.
            ASSERT(stateNode->nodeType() == FrameScrollingNode);
            m_rootNode = node;
            m_nodeMap.clear();
        } 
        m_nodeMap.set(nodeID, node.get());
    }

    if (parentNodeID) {
        auto parentIt = m_nodeMap.find(parentNodeID);
        ASSERT_WITH_SECURITY_IMPLICATION(parentIt != m_nodeMap.end());
        if (parentIt != m_nodeMap.end()) {
            ScrollingTreeNode* parent = parentIt->value;
            node->setParent(parent);
            parent->appendChild(node);
        }
    }

    node->updateBeforeChildren(*stateNode);
    
    // Move all children into the orphanNodes map. Live ones will get added back as we recurse over children.
    if (auto nodeChildren = node->children()) {
        for (auto& childScrollingNode : *nodeChildren) {
            childScrollingNode->setParent(nullptr);
            orphanNodes.add(childScrollingNode->scrollingNodeID(), childScrollingNode);
        }
        nodeChildren->clear();
    }

    // Now update the children if we have any.
    if (auto children = stateNode->children()) {
        for (auto& child : *children)
            updateTreeFromStateNode(child.get(), orphanNodes);
    }

    node->updateAfterChildren(*stateNode);
}
Example #2
0
void ScrollingTree::viewportChangedViaDelegatedScrolling(ScrollingNodeID nodeID, const WebCore::FloatRect& viewportRect, double scale)
{
    ScrollingTreeNode* node = nodeForID(nodeID);
    if (!node)
        return;

    if (!node->isScrollingNode())
        return;

    toScrollingTreeScrollingNode(node)->updateLayersAfterViewportChange(viewportRect, scale);
}
void ScrollingTree::removeDestroyedNodes(ScrollingStateTree* stateTree)
{
    const Vector<ScrollingNodeID>& removedNodes = stateTree->removedNodes();
    size_t size = removedNodes.size();
    for (size_t i = 0; i < size; ++i) {
        ScrollingTreeNode* node = m_nodeMap.take(removedNodes[i]);
        // Never destroy the root node. There will be a new root node in the state tree, and we will
        // associate it with our existing root node in updateTreeFromStateNode().
        if (node && node->parent())
            m_rootNode->removeChild(node);
    }
}
Example #4
0
void ScrollingTree::scrollPositionChangedViaDelegatedScrolling(ScrollingNodeID nodeID, const WebCore::FloatPoint& scrollPosition)
{
    ScrollingTreeNode* node = nodeForID(nodeID);
    if (!node)
        return;

    if (node->nodeType() != OverflowScrollingNode)
        return;

    // Update descendant nodes
    toScrollingTreeScrollingNode(node)->updateLayersAfterDelegatedScroll(scrollPosition);

    // Update GraphicsLayers and scroll state.
    scrollingTreeNodeDidScroll(nodeID, scrollPosition);
}
Example #5
0
void ScrollingTree::removeDestroyedNodes(const ScrollingStateTree& stateTree)
{
    for (const auto& removedNode : stateTree.removedNodes()) {
        ScrollingTreeNode* node = m_nodeMap.take(removedNode);
        if (!node)
            continue;

        if (node->scrollingNodeID() == m_latchedNode)
            clearLatchedNode();

        // Never destroy the root node. There will be a new root node in the state tree, and we will
        // associate it with our existing root node in updateTreeFromStateNode().
        if (node->parent())
            m_rootNode->removeChild(node);
    }
}
Example #6
0
void ScrollingTree::updateTreeFromStateNode(ScrollingStateNode* stateNode)
{
    // 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());

    if (it != m_nodeMap.end()) {
        ScrollingTreeNode* node = it->value;
        node->update(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.
            if (!m_rootNode)
                m_rootNode = ScrollingTreeScrollingNode::create(this, nodeID);

            m_nodeMap.set(nodeID, m_rootNode.get());
            m_rootNode->update(stateNode);
        } else {
            OwnPtr<ScrollingTreeNode> newNode;
            if (stateNode->isScrollingNode())
                newNode = ScrollingTreeScrollingNode::create(this, nodeID);
            else if (stateNode->isFixedNode())
                newNode = ScrollingTreeFixedNode::create(this, nodeID);
            else if (stateNode->isStickyNode())
                newNode = ScrollingTreeStickyNode::create(this, nodeID);
            else
                ASSERT_NOT_REACHED();

            ScrollingTreeNode* newNodeRawPtr = newNode.get();
            m_nodeMap.set(nodeID, newNodeRawPtr);
            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());
            }
            newNodeRawPtr->update(stateNode);
        }
    }

    // Now update the children if we have any.
    Vector<OwnPtr<ScrollingStateNode> >* stateNodeChildren = stateNode->children();
    if (!stateNodeChildren)
        return;

    size_t size = stateNodeChildren->size();
    for (size_t i = 0; i < size; ++i)
        updateTreeFromStateNode(stateNodeChildren->at(i).get());
}
Example #7
0
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);
}
void ScrollingTree::updateTreeFromStateNode(ScrollingStateNode* stateNode)
{
    // 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());

    if (it != m_nodeMap.end()) {
        ScrollingTreeNode* node = it->value;
        node->update(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.
        if (!stateNode->parent()) {
            // This is the root node.
            m_rootNode->setScrollingNodeID(stateNode->scrollingNodeID());
            m_nodeMap.set(stateNode->scrollingNodeID(), m_rootNode.get());
            m_rootNode->update(stateNode);
        } else {
            // FIXME: In the future, we will have more than just ScrollingTreeScrollingNode, so we'll have to
            // figure out which type of node to create.
            OwnPtr<ScrollingTreeNode> newNode = ScrollingTreeScrollingNode::create(this);
            ScrollingTreeNode* newNodeRawPtr = newNode.get();
            m_nodeMap.set(stateNode->scrollingNodeID(), newNodeRawPtr);
            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());
            }
            newNodeRawPtr->update(stateNode);
        }
    }

    // Now update the children if we have any.
    Vector<OwnPtr<ScrollingStateNode> >* stateNodeChildren = stateNode->children();
    if (!stateNodeChildren)
        return;

    size_t size = stateNodeChildren->size();
    for (size_t i = 0; i < size; ++i)
        updateTreeFromStateNode(stateNodeChildren->at(i).get());
}