1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 /* 6 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. 8 * (http://www.torchmobile.com/) 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 20 * its contributors may be used to endorse or promote products derived 21 * from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #ifndef CONTENT_RENDERER_HISTORY_CONTROLLER_H_ 36 #define CONTENT_RENDERER_HISTORY_CONTROLLER_H_ 37 38 #include "base/containers/hash_tables.h" 39 #include "base/memory/scoped_ptr.h" 40 #include "base/memory/scoped_vector.h" 41 #include "content/common/content_export.h" 42 #include "content/renderer/history_entry.h" 43 #include "third_party/WebKit/public/platform/WebURLRequest.h" 44 #include "third_party/WebKit/public/web/WebHistoryCommitType.h" 45 #include "third_party/WebKit/public/web/WebHistoryItem.h" 46 47 namespace blink { 48 class WebFrame; 49 } 50 51 namespace content { 52 class RenderFrameImpl; 53 class RenderViewImpl; 54 55 // A guide to history state in the renderer: 56 // 57 // HistoryController: Owned by RenderView, is the entry point for interacting 58 // with history. Handles most of the operations to modify history state, 59 // navigate to an existing back/forward entry, etc. 60 // 61 // HistoryEntry: Represents a single entry in the back/forward list, 62 // encapsulating all frames in the page it represents. It provides access 63 // to each frame's state via lookups by frame id or frame name. 64 // HistoryNode: Represents a single frame in a HistoryEntry. Owned by a 65 // HistoryEntry. HistoryNodes form a tree that mirrors the frame tree in 66 // the corresponding page. 67 // HistoryNodes represent the structure of the page, but don't hold any 68 // per-frame state except a list of child frames. 69 // WebHistoryItem (lives in blink): The state for a given frame. Can persist 70 // across navigations. WebHistoryItem is reference counted, and each 71 // HistoryNode holds a reference to its single corresponding 72 // WebHistoryItem. Can be referenced by multiple HistoryNodes and can 73 // therefore exist in multiple HistoryEntry instances. 74 // 75 // Suppose we have the following page, foo.com, which embeds foo.com/a in an 76 // iframe: 77 // 78 // HistoryEntry 0: 79 // HistoryNode 0_0 (WebHistoryItem A (url: foo.com)) 80 // HistoryNode 0_1: (WebHistoryItem B (url: foo.com/a)) 81 // 82 // Now we navigate the top frame to bar.com, which embeds bar.com/b and 83 // bar.com/c in iframes, and bar.com/b in turn embeds bar.com/d. We will 84 // create a new HistoryEntry with a tree containing 4 new HistoryNodes. The 85 // state will be: 86 // 87 // HistoryEntry 1: 88 // HistoryNode 1_0 (WebHistoryItem C (url: bar.com)) 89 // HistoryNode 1_1: (WebHistoryItem D (url: bar.com/b)) 90 // HistoryNode 1_3: (WebHistoryItem F (url: bar.com/d)) 91 // HistoryNode 1_2: (WebHistoryItem E (url: bar.com/c)) 92 // 93 // 94 // Finally, we navigate the first subframe from bar.com/b to bar.com/e, which 95 // embeds bar.com/f. We will create a new HistoryEntry and new HistoryNode for 96 // each frame. Any frame that navigates (bar.com/e and its child, bar.com/f) 97 // will receive a new WebHistoryItem. However, 2 frames were not navigated 98 // (bar.com and bar.com/c), so those two frames will reuse the existing 99 // WebHistoryItem: 100 // 101 // HistoryEntry 2: 102 // HistoryNode 2_0 (WebHistoryItem C (url: bar.com)) *REUSED* 103 // HistoryNode 2_1: (WebHistoryItem G (url: bar.com/e)) 104 // HistoryNode 2_3: (WebHistoryItem H (url: bar.com/f)) 105 // HistoryNode 2_2: (WebHistoryItem E (url: bar.com/c)) *REUSED* 106 // 107 class CONTENT_EXPORT HistoryController { 108 public: 109 explicit HistoryController(RenderViewImpl* render_view); 110 ~HistoryController(); 111 112 void GoToEntry(scoped_ptr<HistoryEntry> entry, 113 blink::WebURLRequest::CachePolicy cache_policy); 114 115 void UpdateForCommit(RenderFrameImpl* frame, 116 const blink::WebHistoryItem& item, 117 blink::WebHistoryCommitType commit_type, 118 bool navigation_within_page); 119 120 HistoryEntry* GetCurrentEntry(); 121 blink::WebHistoryItem GetItemForNewChildFrame(RenderFrameImpl* frame) const; 122 void RemoveChildrenForRedirect(RenderFrameImpl* frame); 123 124 private: 125 typedef std::vector<std::pair<blink::WebFrame*, blink::WebHistoryItem> > 126 HistoryFrameLoadVector; 127 void RecursiveGoToEntry(blink::WebFrame* frame, 128 HistoryFrameLoadVector& sameDocumentLoads, 129 HistoryFrameLoadVector& differentDocumentLoads); 130 131 void UpdateForInitialLoadInChildFrame(RenderFrameImpl* frame, 132 const blink::WebHistoryItem& item); 133 void CreateNewBackForwardItem(RenderFrameImpl* frame, 134 const blink::WebHistoryItem& item, 135 bool clone_children_of_target); 136 137 RenderViewImpl* render_view_; 138 139 scoped_ptr<HistoryEntry> current_entry_; 140 scoped_ptr<HistoryEntry> provisional_entry_; 141 142 DISALLOW_COPY_AND_ASSIGN(HistoryController); 143 }; 144 145 } // namespace content 146 147 #endif // CONTENT_RENDERER_HISTORY_CONTROLLER_H_ 148