1acd5ddca5e89a5311281877bf0905ea8a17b29b
[WebKit-https.git] / Source / WebKit / Shared / WebBackForwardListItem.cpp
1 /*
2  * Copyright (C) 2010-2011, 2016 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebBackForwardListItem.h"
28
29 #include <WebCore/URL.h>
30
31 namespace WebKit {
32
33 static uint64_t highestItemID = 0;
34
35 Ref<WebBackForwardListItem> WebBackForwardListItem::create(BackForwardListItemState&& backForwardListItemState, uint64_t pageID)
36 {
37     return adoptRef(*new WebBackForwardListItem(WTFMove(backForwardListItemState), pageID));
38 }
39
40 WebBackForwardListItem::WebBackForwardListItem(BackForwardListItemState&& backForwardListItemState, uint64_t pageID)
41     : m_itemState(WTFMove(backForwardListItemState))
42     , m_pageID(pageID)
43 {
44     if (m_itemState.identifier > highestItemID)
45         highestItemID = m_itemState.identifier;
46 }
47
48 WebBackForwardListItem::~WebBackForwardListItem()
49 {
50 }
51
52 static const FrameState* childItemWithDocumentSequenceNumber(const FrameState& frameState, int64_t number)
53 {
54     for (const auto& child : frameState.children) {
55         if (child.documentSequenceNumber == number)
56             return &child;
57     }
58
59     return nullptr;
60 }
61
62 static bool documentTreesAreEqual(const FrameState& a, const FrameState& b)
63 {
64     if (a.documentSequenceNumber != b.documentSequenceNumber)
65         return false;
66
67     if (a.children.size() != b.children.size())
68         return false;
69
70     for (const auto& child : a.children) {
71         const FrameState* otherChild = childItemWithDocumentSequenceNumber(b, child.documentSequenceNumber);
72         if (!otherChild || !documentTreesAreEqual(child, *otherChild))
73             return false;
74     }
75
76     return true;
77 }
78
79 bool WebBackForwardListItem::itemIsInSameDocument(const WebBackForwardListItem& other) const
80 {
81     if (m_pageID != other.m_pageID)
82         return false;
83
84     // The following logic must be kept in sync with WebCore::HistoryItem::shouldDoSameDocumentNavigationTo.
85
86     const FrameState& mainFrameState = m_itemState.pageState.mainFrameState;
87     const FrameState& otherMainFrameState = other.m_itemState.pageState.mainFrameState;
88
89     if (mainFrameState.stateObjectData || otherMainFrameState.stateObjectData)
90         return mainFrameState.documentSequenceNumber == otherMainFrameState.documentSequenceNumber;
91
92     WebCore::URL url = WebCore::URL(WebCore::ParsedURLString, mainFrameState.urlString);
93     WebCore::URL otherURL = WebCore::URL(WebCore::ParsedURLString, otherMainFrameState.urlString);
94
95     if ((url.hasFragmentIdentifier() || otherURL.hasFragmentIdentifier()) && equalIgnoringFragmentIdentifier(url, otherURL))
96         return mainFrameState.documentSequenceNumber == otherMainFrameState.documentSequenceNumber;
97
98     return documentTreesAreEqual(mainFrameState, otherMainFrameState);
99 }
100
101 uint64_t WebBackForwardListItem::highestUsedItemID()
102 {
103     return highestItemID;
104 }
105
106 void WebBackForwardListItem::setSuspendedPage(SuspendedPageProxy& page)
107 {
108     m_suspendedPage = &page;
109 }
110
111 } // namespace WebKit