Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / page / HistoryController.h
1 /*
2  * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #ifndef HistoryController_h
31 #define HistoryController_h
32
33 #include "core/loader/FrameLoaderTypes.h"
34 #include "core/loader/HistoryItem.h"
35 #include "platform/network/ResourceRequest.h"
36 #include "wtf/HashMap.h"
37 #include "wtf/Noncopyable.h"
38 #include "wtf/RefPtr.h"
39 #include "wtf/text/WTFString.h"
40
41 namespace WebCore {
42
43 class Frame;
44 class HistoryEntry;
45 class Page;
46
47
48 // A guide to history state in Blink:
49 //
50 // HistoryController: Owned by Page, is the entry point for interacting with history.
51 //     Handles most of the operations to modify history state, navigate to an existing
52 //     back/forward entry, etc.
53 // HistoryEntry: Represents a single entry in the back/forward list, encapsulating
54 //     all frames in the page it represents. It provides access to each frame's
55 //     state via lookups by frame id or frame name.
56 // HistoryNode: Represents a single frame in a HistoryEntry. Owned by a HistoryEntry. HistoryNodes
57 // form a tree that mirrors the FrameTree in the corresponding page. HistoryNodes represent
58 // the structure of the page, but don't hold any per-frame state except a list of child frames.
59 // HistoryItem (lives in a separate file): The state for a given frame. Can persist across
60 //     navigations. HistoryItem is reference counted, and each HistoryNode holds a reference
61 //     to its single corresponding HistoryItem. Can be referenced by multiple HistoryNodes and
62 //     can therefore exist in multiple HistoryEntry instances.
63 //
64 // Suppose we have the following page, foo.com, which embeds foo.com/a in an iframe:
65 //
66 // HistoryEntry 0:
67 //     HistoryNode 0_0 (HistoryItem A (url: foo.com))
68 //         HistoryNode 0_1: (HistoryItem B (url: foo.com/a))
69 //
70 // Now we navigation the top frame to bar.com, which embeds bar.com/b and bar.com/c in iframes,
71 // and bar.com/b in turn embeds bar.com/d. We will create a new HistoryEntry with a tree
72 // containing 4 new HistoryNodes. The state will be:
73 //
74 // HistoryEntry 1:
75 //     HistoryNode 1_0 (HistoryItem C (url: bar.com))
76 //         HistoryNode 1_1: (HistoryItem D (url: bar.com/b))
77 //             HistoryNode 1_3: (HistoryItem F (url: bar.com/d))
78 //         HistoryNode 1_2: (HistoryItem E (url: bar.com/c))
79 //
80 //
81 // Finally, we navigate the first subframe from bar.com/b to bar.com/e, which embeds bar.com/f.
82 // We will create a new HistoryEntry and new HistoryNode for each frame. Any frame that
83 // navigates (bar.com/e and its child, bar.com/f) will receive a new HistoryItem. However,
84 // 2 frames were not navigated (bar.com and bar.com/c), so those two frames will reuse the
85 // existing HistoryItem:
86 //
87 // HistoryEntry 2:
88 //     HistoryNode 2_0 (HistoryItem C (url: bar.com))  *REUSED*
89 //         HistoryNode 2_1: (HistoryItem G (url: bar.com/e))
90 //            HistoryNode 2_3: (HistoryItem H (url: bar.com/f))
91 //         HistoryNode 2_2: (HistoryItem E (url: bar.com/c)) *REUSED*
92 //
93
94 class HistoryNode {
95 public:
96     static PassOwnPtr<HistoryNode> create(HistoryEntry*, HistoryItem*);
97     ~HistoryNode() { }
98
99     HistoryNode* addChild(PassRefPtr<HistoryItem>);
100     PassOwnPtr<HistoryNode> cloneAndReplace(HistoryEntry*, HistoryItem* newItem, bool clipAtTarget, Frame* targetFrame, Frame* currentFrame);
101     HistoryItem* value() { return m_value.get(); }
102     void updateValue(PassRefPtr<HistoryItem> item) { m_value = item; }
103     const Vector<OwnPtr<HistoryNode> >& children() const { return m_children; }
104     void removeChildren();
105
106 private:
107     HistoryNode(HistoryEntry*, HistoryItem*);
108
109     HistoryEntry* m_entry;
110     Vector<OwnPtr<HistoryNode> > m_children;
111     RefPtr<HistoryItem> m_value;
112
113 };
114
115 class HistoryEntry {
116 public:
117     static PassOwnPtr<HistoryEntry> create(HistoryItem* root);
118     PassOwnPtr<HistoryEntry> cloneAndReplace(HistoryItem* newItem, bool clipAtTarget, Frame* targetFrame, Page*);
119
120     HistoryNode* historyNodeForFrame(Frame*);
121     HistoryItem* itemForFrame(Frame*);
122     HistoryItem* root() const { return m_root->value(); }
123     HistoryNode* rootHistoryNode() const { return m_root.get(); }
124
125 private:
126     friend class HistoryNode;
127
128     HistoryEntry() { }
129     explicit HistoryEntry(HistoryItem* root);
130
131     OwnPtr<HistoryNode> m_root;
132     HashMap<uint64_t, HistoryNode*> m_framesToItems;
133     HashMap<String, HistoryNode*> m_uniqueNamesToItems;
134 };
135
136 class HistoryController {
137     WTF_MAKE_NONCOPYABLE(HistoryController);
138 public:
139     explicit HistoryController(Page*);
140     ~HistoryController();
141
142     // Should only be called by embedder. To request a back/forward
143     // navigation, call FrameLoaderClient::navigateBackForward().
144     void goToItem(HistoryItem*, ResourceRequestCachePolicy);
145
146     void updateBackForwardListForFragmentScroll(Frame*, HistoryItem*);
147     void updateForCommit(Frame*, HistoryItem*, HistoryCommitType);
148
149     PassRefPtr<HistoryItem> currentItemForExport();
150     PassRefPtr<HistoryItem> previousItemForExport();
151     HistoryItem* itemForNewChildFrame(Frame*) const;
152     void removeChildrenForRedirect(Frame*);
153
154     void setDefersLoading(bool);
155
156 private:
157     void goToEntry(PassOwnPtr<HistoryEntry>, ResourceRequestCachePolicy);
158     typedef HashMap<RefPtr<Frame>, RefPtr<HistoryItem> > HistoryFrameLoadSet;
159     void recursiveGoToEntry(Frame*, HistoryFrameLoadSet& sameDocumentLoads, HistoryFrameLoadSet& differentDocumentLoads);
160
161     void updateForInitialLoadInChildFrame(Frame*, HistoryItem*);
162     void createNewBackForwardItem(Frame*, HistoryItem*, bool doClip);
163
164     Page* m_page;
165
166     OwnPtr<HistoryEntry> m_currentEntry;
167     OwnPtr<HistoryEntry> m_previousEntry;
168     OwnPtr<HistoryEntry> m_provisionalEntry;
169
170     bool m_defersLoading;
171     RefPtr<HistoryItem> m_deferredItem;
172     ResourceRequestCachePolicy m_deferredCachePolicy;
173 };
174
175 } // namespace WebCore
176
177 #endif // HistoryController_h