| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "build/build_config.h" | 5 #include "build/build_config.h" |
| 6 | 6 |
| 7 #include "chrome/browser/ui/toolbar/back_forward_menu_model.h" | 7 #include "chrome/browser/ui/toolbar/back_forward_menu_model.h" |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "content/public/browser/user_metrics.h" | 22 #include "content/public/browser/user_metrics.h" |
| 23 #include "grit/generated_resources.h" | 23 #include "grit/generated_resources.h" |
| 24 #include "grit/theme_resources.h" | 24 #include "grit/theme_resources.h" |
| 25 #include "grit/theme_resources_standard.h" | 25 #include "grit/theme_resources_standard.h" |
| 26 #include "net/base/registry_controlled_domain.h" | 26 #include "net/base/registry_controlled_domain.h" |
| 27 #include "ui/base/l10n/l10n_util.h" | 27 #include "ui/base/l10n/l10n_util.h" |
| 28 #include "ui/base/resource/resource_bundle.h" | 28 #include "ui/base/resource/resource_bundle.h" |
| 29 #include "ui/base/text/text_elider.h" | 29 #include "ui/base/text/text_elider.h" |
| 30 #include "ui/gfx/codec/png_codec.h" | 30 #include "ui/gfx/codec/png_codec.h" |
| 31 | 31 |
| 32 using content::NavigationEntry; |
| 32 using content::UserMetricsAction; | 33 using content::UserMetricsAction; |
| 33 | 34 |
| 34 const int BackForwardMenuModel::kMaxHistoryItems = 12; | 35 const int BackForwardMenuModel::kMaxHistoryItems = 12; |
| 35 const int BackForwardMenuModel::kMaxChapterStops = 5; | 36 const int BackForwardMenuModel::kMaxChapterStops = 5; |
| 36 static const int kMaxWidth = 700; | 37 static const int kMaxWidth = 700; |
| 37 | 38 |
| 38 BackForwardMenuModel::BackForwardMenuModel(Browser* browser, | 39 BackForwardMenuModel::BackForwardMenuModel(Browser* browser, |
| 39 ModelType model_type) | 40 ModelType model_type) |
| 40 : browser_(browser), | 41 : browser_(browser), |
| 41 test_tab_contents_(NULL), | 42 test_tab_contents_(NULL), |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 // Return label "Show Full History" for the last item of the menu. | 84 // Return label "Show Full History" for the last item of the menu. |
| 84 if (index == GetItemCount() - 1) | 85 if (index == GetItemCount() - 1) |
| 85 return l10n_util::GetStringUTF16(IDS_SHOWFULLHISTORY_LINK); | 86 return l10n_util::GetStringUTF16(IDS_SHOWFULLHISTORY_LINK); |
| 86 | 87 |
| 87 // Return an empty string for a separator. | 88 // Return an empty string for a separator. |
| 88 if (IsSeparator(index)) | 89 if (IsSeparator(index)) |
| 89 return string16(); | 90 return string16(); |
| 90 | 91 |
| 91 // Return the entry title, escaping any '&' characters and eliding it if it's | 92 // Return the entry title, escaping any '&' characters and eliding it if it's |
| 92 // super long. | 93 // super long. |
| 93 content::NavigationEntry* entry = GetNavigationEntry(index); | 94 NavigationEntry* entry = GetNavigationEntry(index); |
| 94 Profile* profile = | 95 Profile* profile = |
| 95 Profile::FromBrowserContext(GetTabContents()->GetBrowserContext()); | 96 Profile::FromBrowserContext(GetTabContents()->GetBrowserContext()); |
| 96 string16 menu_text(entry->GetTitleForDisplay( | 97 string16 menu_text(entry->GetTitleForDisplay( |
| 97 profile->GetPrefs()->GetString(prefs::kAcceptLanguages))); | 98 profile->GetPrefs()->GetString(prefs::kAcceptLanguages))); |
| 98 menu_text = | 99 menu_text = |
| 99 ui::ElideText(menu_text, gfx::Font(), kMaxWidth, ui::ELIDE_AT_END); | 100 ui::ElideText(menu_text, gfx::Font(), kMaxWidth, ui::ELIDE_AT_END); |
| 100 | 101 |
| 101 #if !defined(OS_MACOSX) | 102 #if !defined(OS_MACOSX) |
| 102 for (size_t i = menu_text.find('&'); i != string16::npos; | 103 for (size_t i = menu_text.find('&'); i != string16::npos; |
| 103 i = menu_text.find('&', i + 2)) { | 104 i = menu_text.find('&', i + 2)) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 128 } | 129 } |
| 129 | 130 |
| 130 bool BackForwardMenuModel::GetIconAt(int index, SkBitmap* icon) { | 131 bool BackForwardMenuModel::GetIconAt(int index, SkBitmap* icon) { |
| 131 if (!ItemHasIcon(index)) | 132 if (!ItemHasIcon(index)) |
| 132 return false; | 133 return false; |
| 133 | 134 |
| 134 if (index == GetItemCount() - 1) { | 135 if (index == GetItemCount() - 1) { |
| 135 *icon = *ResourceBundle::GetSharedInstance().GetBitmapNamed( | 136 *icon = *ResourceBundle::GetSharedInstance().GetBitmapNamed( |
| 136 IDR_HISTORY_FAVICON); | 137 IDR_HISTORY_FAVICON); |
| 137 } else { | 138 } else { |
| 138 content::NavigationEntry* entry = GetNavigationEntry(index); | 139 NavigationEntry* entry = GetNavigationEntry(index); |
| 139 *icon = entry->GetFavicon().bitmap; | 140 *icon = entry->GetFavicon().bitmap; |
| 140 if (!entry->GetFavicon().valid && menu_model_delegate()) { | 141 if (!entry->GetFavicon().valid && menu_model_delegate()) { |
| 141 FetchFavicon(entry); | 142 FetchFavicon(entry); |
| 142 } | 143 } |
| 143 } | 144 } |
| 144 | 145 |
| 145 return true; | 146 return true; |
| 146 } | 147 } |
| 147 | 148 |
| 148 ui::ButtonMenuItemModel* BackForwardMenuModel::GetButtonMenuItemAt( | 149 ui::ButtonMenuItemModel* BackForwardMenuModel::GetButtonMenuItemAt( |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 | 217 |
| 217 // Look to see if we have reached the separator for the history items. | 218 // Look to see if we have reached the separator for the history items. |
| 218 return index == history_items; | 219 return index == history_items; |
| 219 } | 220 } |
| 220 | 221 |
| 221 void BackForwardMenuModel::SetMenuModelDelegate( | 222 void BackForwardMenuModel::SetMenuModelDelegate( |
| 222 ui::MenuModelDelegate* menu_model_delegate) { | 223 ui::MenuModelDelegate* menu_model_delegate) { |
| 223 menu_model_delegate_ = menu_model_delegate; | 224 menu_model_delegate_ = menu_model_delegate; |
| 224 } | 225 } |
| 225 | 226 |
| 226 void BackForwardMenuModel::FetchFavicon(content::NavigationEntry* entry) { | 227 void BackForwardMenuModel::FetchFavicon(NavigationEntry* entry) { |
| 227 // If the favicon has already been requested for this menu, don't do | 228 // If the favicon has already been requested for this menu, don't do |
| 228 // anything. | 229 // anything. |
| 229 if (requested_favicons_.find(entry->GetUniqueID()) != | 230 if (requested_favicons_.find(entry->GetUniqueID()) != |
| 230 requested_favicons_.end()) { | 231 requested_favicons_.end()) { |
| 231 return; | 232 return; |
| 232 } | 233 } |
| 233 requested_favicons_.insert(entry->GetUniqueID()); | 234 requested_favicons_.insert(entry->GetUniqueID()); |
| 234 FaviconService* favicon_service = | 235 FaviconService* favicon_service = |
| 235 browser_->profile()->GetFaviconService(Profile::EXPLICIT_ACCESS); | 236 browser_->profile()->GetFaviconService(Profile::EXPLICIT_ACCESS); |
| 236 if (!favicon_service) | 237 if (!favicon_service) |
| 237 return; | 238 return; |
| 238 FaviconService::Handle handle = favicon_service->GetFaviconForURL( | 239 FaviconService::Handle handle = favicon_service->GetFaviconForURL( |
| 239 entry->GetURL(), history::FAVICON, &load_consumer_, | 240 entry->GetURL(), history::FAVICON, &load_consumer_, |
| 240 base::Bind(&BackForwardMenuModel::OnFavIconDataAvailable, | 241 base::Bind(&BackForwardMenuModel::OnFavIconDataAvailable, |
| 241 base::Unretained(this))); | 242 base::Unretained(this))); |
| 242 load_consumer_.SetClientData(favicon_service, handle, entry->GetUniqueID()); | 243 load_consumer_.SetClientData(favicon_service, handle, entry->GetUniqueID()); |
| 243 } | 244 } |
| 244 | 245 |
| 245 void BackForwardMenuModel::OnFavIconDataAvailable( | 246 void BackForwardMenuModel::OnFavIconDataAvailable( |
| 246 FaviconService::Handle handle, | 247 FaviconService::Handle handle, |
| 247 history::FaviconData favicon) { | 248 history::FaviconData favicon) { |
| 248 if (favicon.is_valid()) { | 249 if (favicon.is_valid()) { |
| 249 int unique_id = load_consumer_.GetClientDataForCurrentRequest(); | 250 int unique_id = load_consumer_.GetClientDataForCurrentRequest(); |
| 250 // Find the current model_index for the unique_id. | 251 // Find the current model_index for the unique_id. |
| 251 content::NavigationEntry* entry = NULL; | 252 NavigationEntry* entry = NULL; |
| 252 int model_index = -1; | 253 int model_index = -1; |
| 253 for (int i = 0; i < GetItemCount() - 1; i++) { | 254 for (int i = 0; i < GetItemCount() - 1; i++) { |
| 254 if (IsSeparator(i)) | 255 if (IsSeparator(i)) |
| 255 continue; | 256 continue; |
| 256 if (GetNavigationEntry(i)->GetUniqueID() == unique_id) { | 257 if (GetNavigationEntry(i)->GetUniqueID() == unique_id) { |
| 257 model_index = i; | 258 model_index = i; |
| 258 entry = GetNavigationEntry(i); | 259 entry = GetNavigationEntry(i); |
| 259 break; | 260 break; |
| 260 } | 261 } |
| 261 } | 262 } |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 if (forward) { | 342 if (forward) { |
| 342 if (start_from < max_count - 1) { | 343 if (start_from < max_count - 1) { |
| 343 // We want to advance over the current chapter stop, so we add one. | 344 // We want to advance over the current chapter stop, so we add one. |
| 344 // We don't need to do this when direction is backwards. | 345 // We don't need to do this when direction is backwards. |
| 345 start_from++; | 346 start_from++; |
| 346 } else { | 347 } else { |
| 347 return -1; | 348 return -1; |
| 348 } | 349 } |
| 349 } | 350 } |
| 350 | 351 |
| 351 content::NavigationEntry* start_entry = | 352 NavigationEntry* start_entry = controller.GetEntryAtIndex(start_from); |
| 352 controller.GetEntryAtIndex(start_from); | |
| 353 const GURL& url = start_entry->GetURL(); | 353 const GURL& url = start_entry->GetURL(); |
| 354 | 354 |
| 355 if (!forward) { | 355 if (!forward) { |
| 356 // When going backwards we return the first entry we find that has a | 356 // When going backwards we return the first entry we find that has a |
| 357 // different domain. | 357 // different domain. |
| 358 for (int i = start_from - 1; i >= 0; --i) { | 358 for (int i = start_from - 1; i >= 0; --i) { |
| 359 if (!net::RegistryControlledDomainService::SameDomainOrHost(url, | 359 if (!net::RegistryControlledDomainService::SameDomainOrHost(url, |
| 360 controller.GetEntryAtIndex(i)->GetURL())) | 360 controller.GetEntryAtIndex(i)->GetURL())) |
| 361 return i; | 361 return i; |
| 362 } | 362 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 return -1; // This is beyond the last chapter stop so we abort. | 433 return -1; // This is beyond the last chapter stop so we abort. |
| 434 | 434 |
| 435 // This menu item is a chapter stop located between the two separators. | 435 // This menu item is a chapter stop located between the two separators. |
| 436 index = FindChapterStop(history_items, | 436 index = FindChapterStop(history_items, |
| 437 model_type_ == FORWARD_MENU, | 437 model_type_ == FORWARD_MENU, |
| 438 index - history_items - 1); | 438 index - history_items - 1); |
| 439 | 439 |
| 440 return index; | 440 return index; |
| 441 } | 441 } |
| 442 | 442 |
| 443 content::NavigationEntry* BackForwardMenuModel::GetNavigationEntry( | 443 NavigationEntry* BackForwardMenuModel::GetNavigationEntry(int index) const { |
| 444 int index) const { | |
| 445 int controller_index = MenuIndexToNavEntryIndex(index); | 444 int controller_index = MenuIndexToNavEntryIndex(index); |
| 446 NavigationController& controller = GetTabContents()->GetController(); | 445 NavigationController& controller = GetTabContents()->GetController(); |
| 447 if (controller_index >= 0 && controller_index < controller.entry_count()) | 446 if (controller_index >= 0 && controller_index < controller.entry_count()) |
| 448 return controller.GetEntryAtIndex(controller_index); | 447 return controller.GetEntryAtIndex(controller_index); |
| 449 | 448 |
| 450 NOTREACHED(); | 449 NOTREACHED(); |
| 451 return NULL; | 450 return NULL; |
| 452 } | 451 } |
| 453 | 452 |
| 454 std::string BackForwardMenuModel::BuildActionName( | 453 std::string BackForwardMenuModel::BuildActionName( |
| 455 const std::string& action, int index) const { | 454 const std::string& action, int index) const { |
| 456 DCHECK(!action.empty()); | 455 DCHECK(!action.empty()); |
| 457 DCHECK(index >= -1); | 456 DCHECK(index >= -1); |
| 458 std::string metric_string; | 457 std::string metric_string; |
| 459 if (model_type_ == FORWARD_MENU) | 458 if (model_type_ == FORWARD_MENU) |
| 460 metric_string += "ForwardMenu_"; | 459 metric_string += "ForwardMenu_"; |
| 461 else | 460 else |
| 462 metric_string += "BackMenu_"; | 461 metric_string += "BackMenu_"; |
| 463 metric_string += action; | 462 metric_string += action; |
| 464 if (index != -1) { | 463 if (index != -1) { |
| 465 // +1 is for historical reasons (indices used to start at 1). | 464 // +1 is for historical reasons (indices used to start at 1). |
| 466 metric_string += base::IntToString(index + 1); | 465 metric_string += base::IntToString(index + 1); |
| 467 } | 466 } |
| 468 return metric_string; | 467 return metric_string; |
| 469 } | 468 } |
| OLD | NEW |