Home | History | Annotate | Download | only in renderer
      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