// We now traverse the frame tree and item tree a second time, loading frames that
// do have the content the item requests.
void HistoryController::recursiveGoToItem(HistoryItem* item, HistoryItem* fromItem, FrameLoadType type)
{
    ASSERT(item);
    ASSERT(fromItem);

    if (itemsAreClones(item, fromItem)) {
        // Just iterate over the rest, looking for frames to navigate.
        const HistoryItemVector& childItems = item->children();

        int size = childItems.size();
        for (int i = 0; i < size; ++i) {
            String childFrameName = childItems[i]->target();
            HistoryItem* fromChildItem = fromItem->childItemWithTarget(childFrameName);
            ASSERT(fromChildItem);
            Frame* childFrame = m_frame->tree()->child(childFrameName);
            ASSERT(childFrame);
            childFrame->loader()->history()->recursiveGoToItem(childItems[i].get(), fromChildItem, type);
        }
    } else {
        m_frame->loader()->loadItem(item, type);
    }
}
Example #2
0
// The general idea here is to traverse the frame tree and the item tree in parallel,
// tracking whether each frame already has the content the item requests.  If there is
// a match, we set the provisional item and recurse.  Otherwise we will reload that
// frame and all its kids in recursiveGoToItem.
void HistoryController::recursiveSetProvisionalItem(HistoryItem* item, HistoryItem* fromItem, FrameLoadType type)
{
    ASSERT(item);

    if (itemsAreClones(item, fromItem)) {
        // Set provisional item, which will be committed in recursiveUpdateForCommit.
        m_provisionalItem = item;

        const HistoryItemVector& childItems = item->children();

        int size = childItems.size();

        for (int i = 0; i < size; ++i) {
            String childFrameName = childItems[i]->target();
            HistoryItem* fromChildItem = fromItem->childItemWithTarget(childFrameName);
            ASSERT(fromChildItem);
            Frame* childFrame = m_frame->tree()->child(childFrameName);
            ASSERT(childFrame);
            childFrame->loader()->history()->recursiveSetProvisionalItem(childItems[i].get(), fromChildItem, type);
        }
    }
}
Example #3
0
void HistoryController::recursiveUpdateForCommit()
{
    // The frame that navigated will now have a null provisional item.
    // Ignore it and its children.
    if (!m_provisionalItem)
        return;

    // For each frame that already had the content the item requested (based on
    // (a matching URL and frame tree snapshot), just restore the scroll position.
    // Save form state (works from currentItem, since m_frameLoadComplete is true)
    if (m_currentItem && itemsAreClones(m_currentItem.get(), m_provisionalItem.get())) {
        ASSERT(m_frameLoadComplete);
        saveDocumentState();
        saveScrollPositionAndViewStateToItem(m_currentItem.get());
        saveTextWrapWidth(m_currentItem.get());

        if (FrameView* view = m_frame->view())
            view->setWasScrolledByUser(false);

        // Now commit the provisional item
        m_frameLoadComplete = false;
        m_previousItem = m_currentItem;
        m_currentItem = m_provisionalItem;
        m_provisionalItem = 0;

        // Restore form state (works from currentItem)
        restoreDocumentState();

        // Restore the scroll position (we choose to do this rather than going back to the anchor point)
        restoreScrollPositionAndViewState();
        restoreTextWrapWidth();
    }

    // Iterate over the rest of the tree
    for (Frame* child = m_frame->tree()->firstChild(); child; child = child->tree()->nextSibling())
        child->loader()->history()->recursiveUpdateForCommit();
}