[M47_2526] Chromium upversion to m47_2526 branch
[platform/framework/web/chromium-efl.git] / tizen_src / ewk / efl_integration / private / ewk_back_forward_list_private.cc
1 // Copyright 2014 Samsung Electronics. 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 #include "ewk_back_forward_list_private.h"
6
7 #include "content/public/browser/notification_service.h"
8 #include "content/public/browser/notification_types.h"
9 #include "content/public/browser/navigation_details.h"
10
11 _Ewk_Back_Forward_List::_Ewk_Back_Forward_List(content::NavigationController &controller)
12     : navigation_controller_(controller) {
13   notification_registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_CHANGED,
14       content::NotificationService::AllBrowserContextsAndSources());
15 #if !defined(EWK_BRINGUP)
16 // [M47_2526] content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED was removed
17 //            FIXME: http://web.sec.samsung.net/bugzilla/show_bug.cgi?id=14512
18   notification_registrar_.Add(this,
19       content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED,
20       content::NotificationService::AllBrowserContextsAndSources());
21 #endif
22   notification_registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
23       content::NotificationService::AllBrowserContextsAndSources());
24 }
25
26 int _Ewk_Back_Forward_List::GetCurrentIndex() const {
27   return navigation_controller_.GetCurrentEntryIndex();
28 }
29
30 int _Ewk_Back_Forward_List::GetLength() const {
31   return navigation_controller_.GetEntryCount();
32 }
33
34 int _Ewk_Back_Forward_List::GetBackListLength() const {
35   int current = navigation_controller_.GetCurrentEntryIndex();
36   return current < 0 ? 0 : current;
37 }
38
39 int _Ewk_Back_Forward_List::GetForwardListLength() const {
40   int current = navigation_controller_.GetCurrentEntryIndex();
41   return navigation_controller_.GetEntryCount() - current - 1;
42 }
43
44 back_forward_list::Item* _Ewk_Back_Forward_List::GetItemAtIndex(int index) const {
45   index += navigation_controller_.GetCurrentEntryIndex();
46   int count = navigation_controller_.GetEntryCount();
47   if (index < 0 || index >= count) {
48     return NULL;
49   }
50   return FindOrCreateItem(index);
51 }
52
53 void _Ewk_Back_Forward_List::NewPageCommited(int prev_entry_index,
54                                       content::NavigationEntry* new_entry) {
55   int current = prev_entry_index + 1;
56   if (current != navigation_controller_.GetCurrentEntryIndex()) {
57     return;
58   }
59
60   // When user went back several pages and now loaded
61   // some new page (so new entry is commited) then all forward items
62   // were deleted, so we have to do the same in our cache.
63   for (unsigned i = current; i < indexes_.size(); ++i) {
64     content::NavigationEntry* entry = indexes_[i];
65     indexes_[i] = NULL;
66     if (entry) {
67       cache_.erase(entry);
68     }
69   }
70
71   InsertEntryToIndexes(current, new_entry);
72   cache_[new_entry] = scoped_refptr<_Ewk_Back_Forward_List_Item>(new _Ewk_Back_Forward_List_Item(new_entry));
73 }
74
75 void _Ewk_Back_Forward_List::UpdateItemWithEntry(
76     const content::NavigationEntry* entry) {
77   if (entry) {
78     CacheMap::iterator it = cache_.find(entry);
79     if (it != cache_.end()) {
80       it->second->Update(entry);
81     }
82   }
83 }
84
85 void _Ewk_Back_Forward_List::ClearCache() {
86   indexes_.clear();
87   cache_.clear();
88 }
89
90 void _Ewk_Back_Forward_List::Observe(int type,
91                                      const content::NotificationSource &source,
92                                      const content::NotificationDetails &details) {
93   switch (static_cast<content::NotificationType>(type)) {
94     case content::NOTIFICATION_NAV_ENTRY_COMMITTED: {
95       content::Details<content::LoadCommittedDetails> d = details;
96       NewPageCommited(d->previous_entry_index, d->entry);
97       break;
98     }
99     case content::NOTIFICATION_NAV_ENTRY_CHANGED: {
100       content::Details<content::EntryChangedDetails> d = details;
101       const content::NavigationEntry* entry = d->changed_entry;
102       UpdateItemWithEntry(entry);
103       break;
104     }
105 #if !defined(EWK_BRINGUP)
106 // [M47_2526] content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED was removed
107 //            FIXME: http://web.sec.samsung.net/bugzilla/show_bug.cgi?id=14512
108     case content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED: {
109       content::Details<std::pair<content::NavigationEntry*, bool> > d = details;
110       const content::NavigationEntry* entry = d->first;
111       UpdateItemWithEntry(entry);
112       break;
113     }
114 #endif
115     default: {
116       return;
117     }
118   }
119 }
120
121 _Ewk_Back_Forward_List_Item* _Ewk_Back_Forward_List::FindOrCreateItem(int index) const {
122   content::NavigationEntry* entry =
123       navigation_controller_.GetEntryAtIndex(index);
124
125   if (!entry) {
126     return NULL;
127   }
128
129   _Ewk_Back_Forward_List_Item* item = NULL;
130   CacheMap::iterator it = cache_.find(entry);
131   if (it != cache_.end()) {
132     // item already in cache
133     item = it->second.get();
134   } else {
135     // need to create new item
136     item = new _Ewk_Back_Forward_List_Item(entry);
137     cache_[entry] = scoped_refptr<_Ewk_Back_Forward_List_Item>(item);
138   }
139
140   InsertEntryToIndexes(index, entry);
141
142   return item;
143 }
144
145 void _Ewk_Back_Forward_List::InsertEntryToIndexes(
146     unsigned index, content::NavigationEntry* entry) const {
147   if (index == indexes_.size()) {
148     indexes_.push_back(entry);
149     return;
150   }
151
152   if (index > indexes_.size()) {
153     indexes_.resize(index + 1, NULL);
154   }
155   indexes_[index] = entry;
156 }