| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/dom_ui/new_tab_ui.h" | 7 #include "chrome/browser/dom_ui/new_tab_ui.h" |
| 8 | 8 |
| 9 #include <set> | 9 #include <set> |
| 10 | 10 |
| 11 #include "app/l10n_util.h" | 11 #include "app/l10n_util.h" |
| 12 #include "base/callback.h" | 12 #include "base/callback.h" |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/histogram.h" | 14 #include "base/histogram.h" |
| 15 #include "base/i18n/rtl.h" | 15 #include "base/i18n/rtl.h" |
| 16 #include "base/singleton.h" | 16 #include "base/singleton.h" |
| 17 #include "base/string_number_conversions.h" | 17 #include "base/string_number_conversions.h" |
| 18 #include "base/thread.h" | 18 #include "base/thread.h" |
| 19 #include "base/utf_string_conversions.h" | 19 #include "base/utf_string_conversions.h" |
| 20 #include "chrome/browser/browser.h" | 20 #include "chrome/browser/browser.h" |
| 21 #include "chrome/browser/chrome_thread.h" | 21 #include "chrome/browser/chrome_thread.h" |
| 22 #include "chrome/browser/dom_ui/app_launcher_handler.h" | 22 #include "chrome/browser/dom_ui/app_launcher_handler.h" |
| 23 #include "chrome/browser/dom_ui/dom_ui_theme_source.h" | 23 #include "chrome/browser/dom_ui/dom_ui_theme_source.h" |
| 24 #include "chrome/browser/dom_ui/foreign_session_handler.h" | 24 #include "chrome/browser/dom_ui/foreign_session_handler.h" |
| 25 #include "chrome/browser/dom_ui/most_visited_handler.h" | 25 #include "chrome/browser/dom_ui/most_visited_handler.h" |
| 26 #include "chrome/browser/dom_ui/new_tab_page_sync_handler.h" | 26 #include "chrome/browser/dom_ui/new_tab_page_sync_handler.h" |
| 27 #include "chrome/browser/dom_ui/ntp_resource_cache.h" | 27 #include "chrome/browser/dom_ui/ntp_resource_cache.h" |
| 28 #include "chrome/browser/dom_ui/shown_sections_handler.h" | 28 #include "chrome/browser/dom_ui/shown_sections_handler.h" |
| 29 #include "chrome/browser/dom_ui/tips_handler.h" | 29 #include "chrome/browser/dom_ui/tips_handler.h" |
| 30 #include "chrome/browser/dom_ui/value_helper.h" |
| 30 #include "chrome/browser/metrics/user_metrics.h" | 31 #include "chrome/browser/metrics/user_metrics.h" |
| 31 #include "chrome/browser/themes/browser_theme_provider.h" | 32 #include "chrome/browser/themes/browser_theme_provider.h" |
| 32 #include "chrome/browser/prefs/pref_service.h" | 33 #include "chrome/browser/prefs/pref_service.h" |
| 33 #include "chrome/browser/profile.h" | 34 #include "chrome/browser/profile.h" |
| 34 #include "chrome/browser/renderer_host/render_view_host.h" | 35 #include "chrome/browser/renderer_host/render_view_host.h" |
| 35 #include "chrome/browser/sessions/session_types.h" | 36 #include "chrome/browser/sessions/session_types.h" |
| 36 #include "chrome/browser/sessions/tab_restore_service.h" | 37 #include "chrome/browser/sessions/tab_restore_service.h" |
| 37 #include "chrome/browser/sessions/tab_restore_service_observer.h" | 38 #include "chrome/browser/sessions/tab_restore_service_observer.h" |
| 38 #include "chrome/browser/sync/profile_sync_service.h" | 39 #include "chrome/browser/sync/profile_sync_service.h" |
| 39 #include "chrome/browser/tab_contents/tab_contents.h" | 40 #include "chrome/browser/tab_contents/tab_contents.h" |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 // Observer callback for TabRestoreServiceObserver. Sends data on | 145 // Observer callback for TabRestoreServiceObserver. Sends data on |
| 145 // recently closed tabs to the javascript side of this page to | 146 // recently closed tabs to the javascript side of this page to |
| 146 // display to the user. | 147 // display to the user. |
| 147 virtual void TabRestoreServiceChanged(TabRestoreService* service); | 148 virtual void TabRestoreServiceChanged(TabRestoreService* service); |
| 148 | 149 |
| 149 // Observer callback to notice when our associated TabRestoreService | 150 // Observer callback to notice when our associated TabRestoreService |
| 150 // is destroyed. | 151 // is destroyed. |
| 151 virtual void TabRestoreServiceDestroyed(TabRestoreService* service); | 152 virtual void TabRestoreServiceDestroyed(TabRestoreService* service); |
| 152 | 153 |
| 153 private: | 154 private: |
| 154 // Converts a closed tab to the value sent down to the NTP. Returns true on | |
| 155 // success, false if the value shouldn't be sent down. | |
| 156 bool TabToValue(const TabRestoreService::Tab& tab, | |
| 157 DictionaryValue* dictionary); | |
| 158 | |
| 159 // Converts a closed window to the value sent down to the NTP. Returns true | |
| 160 // on success, false if the value shouldn't be sent down. | |
| 161 bool WindowToValue(const TabRestoreService::Window& window, | |
| 162 DictionaryValue* dictionary); | |
| 163 | |
| 164 // Adds tab to unique_items list if it is not present. Returns false if | |
| 165 // tab was already in the list, true if it was absent. A tab is | |
| 166 // considered unique if no other tab shares both its title and its url. | |
| 167 bool EnsureTabIsUnique(const DictionaryValue* tab, | |
| 168 std::set<std::string>* unique_items); | |
| 169 | |
| 170 // TabRestoreService that we are observing. | 155 // TabRestoreService that we are observing. |
| 171 TabRestoreService* tab_restore_service_; | 156 TabRestoreService* tab_restore_service_; |
| 172 | 157 |
| 173 DISALLOW_COPY_AND_ASSIGN(RecentlyClosedTabsHandler); | 158 DISALLOW_COPY_AND_ASSIGN(RecentlyClosedTabsHandler); |
| 174 }; | 159 }; |
| 175 | 160 |
| 176 void RecentlyClosedTabsHandler::RegisterMessages() { | 161 void RecentlyClosedTabsHandler::RegisterMessages() { |
| 177 dom_ui_->RegisterMessageCallback("getRecentlyClosedTabs", | 162 dom_ui_->RegisterMessageCallback("getRecentlyClosedTabs", |
| 178 NewCallback(this, | 163 NewCallback(this, |
| 179 &RecentlyClosedTabsHandler::HandleGetRecentlyClosedTabs)); | 164 &RecentlyClosedTabsHandler::HandleGetRecentlyClosedTabs)); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 tab_restore_service_->AddObserver(this); | 199 tab_restore_service_->AddObserver(this); |
| 215 } | 200 } |
| 216 } | 201 } |
| 217 | 202 |
| 218 if (tab_restore_service_) | 203 if (tab_restore_service_) |
| 219 TabRestoreServiceChanged(tab_restore_service_); | 204 TabRestoreServiceChanged(tab_restore_service_); |
| 220 } | 205 } |
| 221 | 206 |
| 222 void RecentlyClosedTabsHandler::TabRestoreServiceChanged( | 207 void RecentlyClosedTabsHandler::TabRestoreServiceChanged( |
| 223 TabRestoreService* service) { | 208 TabRestoreService* service) { |
| 224 const TabRestoreService::Entries& entries = service->entries(); | |
| 225 ListValue list_value; | 209 ListValue list_value; |
| 226 std::set<std::string> unique_items; | 210 NewTabUI::AddRecentlyClosedEntries(service->entries(), &list_value); |
| 227 int added_count = 0; | |
| 228 const int max_count = 10; | |
| 229 | 211 |
| 230 // We filter the list of recently closed to only show 'interesting' entries, | |
| 231 // where an interesting entry is either a closed window or a closed tab | |
| 232 // whose selected navigation is not the new tab ui. | |
| 233 for (TabRestoreService::Entries::const_iterator it = entries.begin(); | |
| 234 it != entries.end() && added_count < max_count; ++it) { | |
| 235 TabRestoreService::Entry* entry = *it; | |
| 236 DictionaryValue* value = new DictionaryValue(); | |
| 237 if ((entry->type == TabRestoreService::TAB && | |
| 238 TabToValue(*static_cast<TabRestoreService::Tab*>(entry), value) && | |
| 239 EnsureTabIsUnique(value, &unique_items)) || | |
| 240 (entry->type == TabRestoreService::WINDOW && | |
| 241 WindowToValue(*static_cast<TabRestoreService::Window*>(entry), | |
| 242 value))) { | |
| 243 value->SetInteger("sessionId", entry->id); | |
| 244 list_value.Append(value); | |
| 245 added_count++; | |
| 246 } else { | |
| 247 delete value; | |
| 248 } | |
| 249 } | |
| 250 dom_ui_->CallJavascriptFunction(L"recentlyClosedTabs", list_value); | 212 dom_ui_->CallJavascriptFunction(L"recentlyClosedTabs", list_value); |
| 251 } | 213 } |
| 252 | 214 |
| 253 void RecentlyClosedTabsHandler::TabRestoreServiceDestroyed( | 215 void RecentlyClosedTabsHandler::TabRestoreServiceDestroyed( |
| 254 TabRestoreService* service) { | 216 TabRestoreService* service) { |
| 255 tab_restore_service_ = NULL; | 217 tab_restore_service_ = NULL; |
| 256 } | 218 } |
| 257 | 219 |
| 258 bool RecentlyClosedTabsHandler::TabToValue( | |
| 259 const TabRestoreService::Tab& tab, | |
| 260 DictionaryValue* dictionary) { | |
| 261 if (tab.navigations.empty()) | |
| 262 return false; | |
| 263 | |
| 264 const TabNavigation& current_navigation = | |
| 265 tab.navigations.at(tab.current_navigation_index); | |
| 266 if (current_navigation.virtual_url() == GURL(chrome::kChromeUINewTabURL)) | |
| 267 return false; | |
| 268 | |
| 269 NewTabUI::SetURLTitleAndDirection(dictionary, current_navigation.title(), | |
| 270 current_navigation.virtual_url()); | |
| 271 dictionary->SetString("type", "tab"); | |
| 272 dictionary->SetReal("timestamp", tab.timestamp.ToDoubleT()); | |
| 273 return true; | |
| 274 } | |
| 275 | |
| 276 bool RecentlyClosedTabsHandler::WindowToValue( | |
| 277 const TabRestoreService::Window& window, | |
| 278 DictionaryValue* dictionary) { | |
| 279 if (window.tabs.empty()) { | |
| 280 NOTREACHED(); | |
| 281 return false; | |
| 282 } | |
| 283 | |
| 284 ListValue* tab_values = new ListValue(); | |
| 285 for (size_t i = 0; i < window.tabs.size(); ++i) { | |
| 286 DictionaryValue* tab_value = new DictionaryValue(); | |
| 287 if (TabToValue(window.tabs[i], tab_value)) | |
| 288 tab_values->Append(tab_value); | |
| 289 else | |
| 290 delete tab_value; | |
| 291 } | |
| 292 if (tab_values->GetSize() == 0) { | |
| 293 delete tab_values; | |
| 294 return false; | |
| 295 } | |
| 296 | |
| 297 dictionary->SetString("type", "window"); | |
| 298 dictionary->SetReal("timestamp", window.timestamp.ToDoubleT()); | |
| 299 dictionary->Set("tabs", tab_values); | |
| 300 return true; | |
| 301 } | |
| 302 | |
| 303 bool RecentlyClosedTabsHandler::EnsureTabIsUnique( | |
| 304 const DictionaryValue* tab, | |
| 305 std::set<std::string>* unique_items) { | |
| 306 DCHECK(unique_items); | |
| 307 std::string title; | |
| 308 std::string url; | |
| 309 if (tab->GetString("title", &title) && | |
| 310 tab->GetString("url", &url)) { | |
| 311 // TODO(viettrungluu): this isn't obviously reliable, since different | |
| 312 // combinations of titles/urls may conceivably yield the same string. | |
| 313 std::string unique_key = title + url; | |
| 314 if (unique_items->find(unique_key) != unique_items->end()) | |
| 315 return false; | |
| 316 else | |
| 317 unique_items->insert(unique_key); | |
| 318 } | |
| 319 return true; | |
| 320 } | |
| 321 | |
| 322 | 220 |
| 323 /////////////////////////////////////////////////////////////////////////////// | 221 /////////////////////////////////////////////////////////////////////////////// |
| 324 // MetricsHandler | 222 // MetricsHandler |
| 325 | 223 |
| 326 // Let the page contents record UMA actions. Only use when you can't do it from | 224 // Let the page contents record UMA actions. Only use when you can't do it from |
| 327 // C++. For example, we currently use it to let the NTP log the postion of the | 225 // C++. For example, we currently use it to let the NTP log the postion of the |
| 328 // Most Visited or Bookmark the user clicked on, as we don't get that | 226 // Most Visited or Bookmark the user clicked on, as we don't get that |
| 329 // information through RequestOpenURL. You will need to update the metrics | 227 // information through RequestOpenURL. You will need to update the metrics |
| 330 // dashboard with the action names you use, as our processor won't catch that | 228 // dashboard with the action names you use, as our processor won't catch that |
| 331 // information (treat it as RecordComputedMetrics) | 229 // information (treat it as RecordComputedMetrics) |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 direction = kRTLHtmlTextDirection; | 496 direction = kRTLHtmlTextDirection; |
| 599 } else { | 497 } else { |
| 600 base::i18n::WrapStringWithLTRFormatting(&title_to_set); | 498 base::i18n::WrapStringWithLTRFormatting(&title_to_set); |
| 601 } | 499 } |
| 602 } | 500 } |
| 603 } | 501 } |
| 604 dictionary->SetString("title", title_to_set); | 502 dictionary->SetString("title", title_to_set); |
| 605 dictionary->SetString("direction", direction); | 503 dictionary->SetString("direction", direction); |
| 606 } | 504 } |
| 607 | 505 |
| 506 namespace { |
| 507 |
| 508 bool IsTabUnique(const DictionaryValue* tab, |
| 509 std::set<std::string>* unique_items) { |
| 510 DCHECK(unique_items); |
| 511 std::string title; |
| 512 std::string url; |
| 513 if (tab->GetString("title", &title) && |
| 514 tab->GetString("url", &url)) { |
| 515 // TODO(viettrungluu): this isn't obviously reliable, since different |
| 516 // combinations of titles/urls may conceivably yield the same string. |
| 517 std::string unique_key = title + url; |
| 518 if (unique_items->find(unique_key) != unique_items->end()) |
| 519 return false; |
| 520 else |
| 521 unique_items->insert(unique_key); |
| 522 } |
| 523 return true; |
| 524 } |
| 525 |
| 526 } // namespace |
| 527 |
| 528 // static |
| 529 void NewTabUI::AddRecentlyClosedEntries( |
| 530 const TabRestoreService::Entries& entries, ListValue* entry_list_value) { |
| 531 const int max_count = 10; |
| 532 int added_count = 0; |
| 533 std::set<std::string> unique_items; |
| 534 // We filter the list of recently closed to only show 'interesting' entries, |
| 535 // where an interesting entry is either a closed window or a closed tab |
| 536 // whose selected navigation is not the new tab ui. |
| 537 for (TabRestoreService::Entries::const_iterator it = entries.begin(); |
| 538 it != entries.end() && added_count < max_count; ++it) { |
| 539 TabRestoreService::Entry* entry = *it; |
| 540 scoped_ptr<DictionaryValue> entry_dict(new DictionaryValue()); |
| 541 if ((entry->type == TabRestoreService::TAB && |
| 542 ValueHelper::TabToValue( |
| 543 *static_cast<TabRestoreService::Tab*>(entry), |
| 544 entry_dict.get()) && |
| 545 IsTabUnique(entry_dict.get(), &unique_items)) || |
| 546 (entry->type == TabRestoreService::WINDOW && |
| 547 ValueHelper::WindowToValue( |
| 548 *static_cast<TabRestoreService::Window*>(entry), |
| 549 entry_dict.get()))) { |
| 550 entry_dict->SetInteger("sessionId", entry->id); |
| 551 entry_list_value->Append(entry_dict.release()); |
| 552 added_count++; |
| 553 } |
| 554 } |
| 555 } |
| 556 |
| 608 /////////////////////////////////////////////////////////////////////////////// | 557 /////////////////////////////////////////////////////////////////////////////// |
| 609 // NewTabHTMLSource | 558 // NewTabHTMLSource |
| 610 | 559 |
| 611 bool NewTabUI::NewTabHTMLSource::first_run_ = true; | 560 bool NewTabUI::NewTabHTMLSource::first_run_ = true; |
| 612 | 561 |
| 613 NewTabUI::NewTabHTMLSource::NewTabHTMLSource(Profile* profile) | 562 NewTabUI::NewTabHTMLSource::NewTabHTMLSource(Profile* profile) |
| 614 : DataSource(chrome::kChromeUINewTabHost, MessageLoop::current()), | 563 : DataSource(chrome::kChromeUINewTabHost, MessageLoop::current()), |
| 615 profile_(profile) { | 564 profile_(profile) { |
| 616 } | 565 } |
| 617 | 566 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 629 | 578 |
| 630 scoped_refptr<RefCountedBytes> html_bytes = | 579 scoped_refptr<RefCountedBytes> html_bytes = |
| 631 profile_->GetNTPResourceCache()->GetNewTabHTML(is_off_the_record); | 580 profile_->GetNTPResourceCache()->GetNewTabHTML(is_off_the_record); |
| 632 | 581 |
| 633 SendResponse(request_id, html_bytes); | 582 SendResponse(request_id, html_bytes); |
| 634 } | 583 } |
| 635 | 584 |
| 636 std::string NewTabUI::NewTabHTMLSource::GetMimeType(const std::string&) const { | 585 std::string NewTabUI::NewTabHTMLSource::GetMimeType(const std::string&) const { |
| 637 return "text/html"; | 586 return "text/html"; |
| 638 } | 587 } |
| OLD | NEW |