172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/history_ui.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <algorithm> 821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <set> 921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/callback.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/i18n/time_formatting.h" 12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/singleton.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h" 143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string16.h" 153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_piece.h" 173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/time.h" 193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h" 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/values.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/bookmarks/bookmark_model.h" 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/history_types.h" 23dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/metrics/user_metrics.h" 2421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser.h" 264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser_list.h" 27dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/favicon_source.h" 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/jstemplate_builder.h" 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/time_format.h" 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h" 31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h" 32dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h" 33dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents_delegate.h" 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/browser_resources.h" 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/chromium_strings.h" 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h" 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/locale_settings.h" 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/theme_resources.h" 3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "net/base/escape.h" 4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 4172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h" 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Maximum number of search results to return in a given search. We should 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// eventually remove this. 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kMaxSearchResults = 100; 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// HistoryHTMLSource 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHistoryUIHTMLSource::HistoryUIHTMLSource() 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : DataSource(chrome::kChromeUIHistoryHost, MessageLoop::current()) { 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HistoryUIHTMLSource::StartDataRequest(const std::string& path, 58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool is_incognito, 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int request_id) { 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DictionaryValue localized_strings; 613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick localized_strings.SetString("loading", 623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_HISTORY_LOADING)); 633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick localized_strings.SetString("title", 643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_HISTORY_TITLE)); 653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick localized_strings.SetString("loading", 663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_HISTORY_LOADING)); 673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick localized_strings.SetString("newest", 683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_HISTORY_NEWEST)); 693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick localized_strings.SetString("newer", 703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_HISTORY_NEWER)); 713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick localized_strings.SetString("older", 723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_HISTORY_OLDER)); 733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick localized_strings.SetString("searchresultsfor", 743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_HISTORY_SEARCHRESULTSFOR)); 753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick localized_strings.SetString("history", 763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_HISTORY_BROWSERESULTS)); 773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick localized_strings.SetString("cont", 783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_HISTORY_CONTINUED)); 793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick localized_strings.SetString("searchbutton", 803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_HISTORY_SEARCH_BUTTON)); 813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick localized_strings.SetString("noresults", 823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_HISTORY_NO_RESULTS)); 833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick localized_strings.SetString("noitems", 843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_HISTORY_NO_ITEMS)); 853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick localized_strings.SetString("edithistory", 863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_HISTORY_START_EDITING_HISTORY)); 873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick localized_strings.SetString("doneediting", 883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_HISTORY_STOP_EDITING_HISTORY)); 893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick localized_strings.SetString("removeselected", 903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_HISTORY_REMOVE_SELECTED_ITEMS)); 913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick localized_strings.SetString("clearallhistory", 923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_HISTORY_OPEN_CLEAR_BROWSING_DATA_DIALOG)); 933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick localized_strings.SetString("deletewarning", 943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_HISTORY_DELETE_PRIOR_VISITS_WARNING)); 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetFontAndTextDirection(&localized_strings); 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const base::StringPiece history_html( 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ResourceBundle::GetSharedInstance().GetRawDataResource( 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDR_HISTORY_HTML)); 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string full_html = jstemplate_builder::GetI18nTemplateHtml( 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history_html, &localized_strings); 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes); 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch html_bytes->data.resize(full_html.size()); 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin()); 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SendResponse(request_id, html_bytes); 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenstd::string HistoryUIHTMLSource::GetMimeType(const std::string&) const { 11221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return "text/html"; 11321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 11421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// HistoryHandler 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowsingHistoryHandler::BrowsingHistoryHandler() 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : search_text_() { 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochBrowsingHistoryHandler::~BrowsingHistoryHandler() { 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cancelable_search_consumer_.CancelAllRequests(); 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cancelable_delete_consumer_.CancelAllRequests(); 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 12972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenWebUIMessageHandler* BrowsingHistoryHandler::Attach(WebUI* web_ui) { 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create our favicon data source. 13172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen Profile* profile = web_ui->GetProfile(); 13272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen profile->GetChromeURLDataManager()->AddDataSource( 133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen new FaviconSource(profile)); 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 13572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return WebUIMessageHandler::Attach(web_ui); 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowsingHistoryHandler::RegisterMessages() { 13972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen web_ui_->RegisterMessageCallback("getHistory", 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewCallback(this, &BrowsingHistoryHandler::HandleGetHistory)); 14172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen web_ui_->RegisterMessageCallback("searchHistory", 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewCallback(this, &BrowsingHistoryHandler::HandleSearchHistory)); 14372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen web_ui_->RegisterMessageCallback("removeURLsOnOneDay", 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewCallback(this, &BrowsingHistoryHandler::HandleRemoveURLsOnOneDay)); 14572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen web_ui_->RegisterMessageCallback("clearBrowsingData", 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewCallback(this, &BrowsingHistoryHandler::HandleClearBrowsingData)); 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid BrowsingHistoryHandler::HandleGetHistory(const ListValue* args) { 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Anything in-flight is invalid. 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cancelable_search_consumer_.CancelAllRequests(); 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Get arguments (if any). 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int day = 0; 1553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ExtractIntegerValue(args, &day); 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set our query options. 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history::QueryOptions options; 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.begin_time = base::Time::Now().LocalMidnight(); 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.begin_time -= base::TimeDelta::FromDays(day); 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.end_time = base::Time::Now().LocalMidnight(); 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.end_time -= base::TimeDelta::FromDays(day - 1); 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Need to remember the query string for our results. 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch search_text_ = string16(); 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HistoryService* hs = 16872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen web_ui_->GetProfile()->GetHistoryService(Profile::EXPLICIT_ACCESS); 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch hs->QueryHistory(search_text_, 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options, 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &cancelable_search_consumer_, 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewCallback(this, &BrowsingHistoryHandler::QueryComplete)); 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid BrowsingHistoryHandler::HandleSearchHistory(const ListValue* args) { 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Anything in-flight is invalid. 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cancelable_search_consumer_.CancelAllRequests(); 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Get arguments (if any). 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int month = 0; 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch string16 query; 1823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ExtractSearchHistoryArguments(args, &month, &query); 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set the query ranges for the given month. 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history::QueryOptions options = CreateMonthQueryOptions(month); 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // When searching, limit the number of results returned. 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.max_count = kMaxSearchResults; 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Need to remember the query string for our results. 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch search_text_ = query; 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HistoryService* hs = 19372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen web_ui_->GetProfile()->GetHistoryService(Profile::EXPLICIT_ACCESS); 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch hs->QueryHistory(search_text_, 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options, 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &cancelable_search_consumer_, 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewCallback(this, &BrowsingHistoryHandler::QueryComplete)); 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid BrowsingHistoryHandler::HandleRemoveURLsOnOneDay(const ListValue* args) { 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (cancelable_delete_consumer_.HasPendingRequests()) { 202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen web_ui_->CallJavascriptFunction("deleteFailed"); 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Get day to delete data from. 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int visit_time = 0; 2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ExtractIntegerValue(args, &visit_time); 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time::Exploded exploded; 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time::FromTimeT( 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<time_t>(visit_time)).LocalExplode(&exploded); 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch exploded.hour = exploded.minute = exploded.second = exploded.millisecond = 0; 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time begin_time = base::Time::FromLocalExploded(exploded); 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time end_time = begin_time + base::TimeDelta::FromDays(1); 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Get URLs. 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::set<GURL> urls; 2183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (ListValue::const_iterator v = args->begin() + 1; 2193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick v != args->end(); ++v) { 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if ((*v)->GetType() != Value::TYPE_STRING) 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch continue; 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const StringValue* string_value = static_cast<const StringValue*>(*v); 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch string16 string16_value; 2243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!string_value->GetAsString(&string16_value)) 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch continue; 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch urls.insert(GURL(string16_value)); 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HistoryService* hs = 23072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen web_ui_->GetProfile()->GetHistoryService(Profile::EXPLICIT_ACCESS); 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch hs->ExpireHistoryBetween( 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch urls, begin_time, end_time, &cancelable_delete_consumer_, 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NewCallback(this, &BrowsingHistoryHandler::RemoveComplete)); 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid BrowsingHistoryHandler::HandleClearBrowsingData(const ListValue* args) { 2373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // TODO(beng): This is an improper direct dependency on Browser. Route this 2383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // through some sort of delegate. 23972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen Browser* browser = BrowserList::FindBrowserWithProfile(web_ui_->GetProfile()); 2403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (browser) 2413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick browser->OpenClearBrowsingDataDialog(); 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowsingHistoryHandler::QueryComplete( 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HistoryService::Handle request_handle, 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history::QueryResults* results) { 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ListValue results_value; 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time midnight_today = base::Time::Now().LocalMidnight(); 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < results->size(); ++i) { 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history::URLResult const &page = (*results)[i]; 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DictionaryValue* page_value = new DictionaryValue(); 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetURLAndTitle(page_value, page.title(), page.url()); 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Need to pass the time in epoch time (fastest JS conversion). 2573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick page_value->SetInteger("time", 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<int>(page.visit_time().ToTimeT())); 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Until we get some JS i18n infrastructure, we also need to 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // pass the dates in as strings. This could use some 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // optimization. 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Only pass in the strings we need (search results need a shortdate 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // and snippet, browse results need day and time information). 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (search_text_.empty()) { 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Figure out the relative date string. 2683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick string16 date_str = TimeFormat::RelativeDate(page.visit_time(), 2693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick &midnight_today); 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (date_str.empty()) { 27121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen date_str = base::TimeFormatFriendlyDate(page.visit_time()); 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 2733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick date_str = l10n_util::GetStringFUTF16( 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch IDS_HISTORY_DATE_WITH_RELATIVE_TIME, 2753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick date_str, 27621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen base::TimeFormatFriendlyDate(page.visit_time())); 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick page_value->SetString("dateRelativeDay", date_str); 2793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick page_value->SetString("dateTimeOfDay", 28021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen base::TimeFormatTimeOfDay(page.visit_time())); 281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 2823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick page_value->SetString("dateShort", 28321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen base::TimeFormatShortDate(page.visit_time())); 2843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick page_value->SetString("snippet", page.snippet().text()); 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick page_value->SetBoolean("starred", 28772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen web_ui_->GetProfile()->GetBookmarkModel()->IsBookmarked(page.url())); 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch results_value.Append(page_value); 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DictionaryValue info_value; 2923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick info_value.SetString("term", search_text_); 2933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick info_value.SetBoolean("finished", results->reached_beginning()); 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen web_ui_->CallJavascriptFunction("historyResult", info_value, results_value); 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid BrowsingHistoryHandler::RemoveComplete() { 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Some Visits were deleted from history. Reload the list. 300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen web_ui_->CallJavascriptFunction("deleteComplete"); 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid BrowsingHistoryHandler::ExtractSearchHistoryArguments( 3043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const ListValue* args, 3053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int* month, 3063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick string16* query) { 3073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CHECK(args->GetSize() == 2); 3083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick query->clear(); 3093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CHECK(args->GetString(0, query)); 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 3113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick string16 string16_value; 3123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CHECK(args->GetString(1, &string16_value)); 3133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *month = 0; 3143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::StringToInt(string16_value, month); 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochhistory::QueryOptions BrowsingHistoryHandler::CreateMonthQueryOptions( 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int month) { 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch history::QueryOptions options; 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Configure the begin point of the search to the start of the 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // current month. 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time::Exploded exploded; 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Time::Now().LocalMidnight().LocalExplode(&exploded); 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch exploded.day_of_month = 1; 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (month == 0) { 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.begin_time = base::Time::FromLocalExploded(exploded); 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set the end time of this first search to null (which will 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // show results from the future, should the user's clock have 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // been set incorrectly). 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.end_time = base::Time(); 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set the end-time of this search to the end of the month that is 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |depth| months before the search end point. The end time is not 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // inclusive, so we should feel free to set it to midnight on the 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // first day of the following month. 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch exploded.month -= month - 1; 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (exploded.month < 1) { 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch exploded.month += 12; 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch exploded.year--; 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.end_time = base::Time::FromLocalExploded(exploded); 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set the begin-time of the search to the start of the month 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // that is |depth| months prior to search_start_. 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (exploded.month > 1) { 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch exploded.month--; 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch exploded.month = 12; 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch exploded.year--; 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch options.begin_time = base::Time::FromLocalExploded(exploded); 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return options; 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// HistoryUIContents 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//////////////////////////////////////////////////////////////////////////////// 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 36672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenHistoryUI::HistoryUI(TabContents* contents) : WebUI(contents) { 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AddMessageHandler((new BrowsingHistoryHandler())->Attach(this)); 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HistoryUIHTMLSource* html_source = new HistoryUIHTMLSource(); 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Set up the chrome://history/ source. 37272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst GURL HistoryUI::GetHistoryURLWithSearchText(const string16& text) { 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GURL(std::string(chrome::kChromeUIHistoryURL) + "#q=" + 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EscapeQueryParamValue(UTF16ToUTF8(text), true)); 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochRefCountedMemory* HistoryUI::GetFaviconResourceBytes() { 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return ResourceBundle::GetSharedInstance(). 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LoadDataResourceBytes(IDR_HISTORY_FAVICON); 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 386