diff options
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/dom_ui/history_ui.cc | 97 | ||||
-rw-r--r-- | chrome/browser/dom_ui/history_ui.h | 31 | ||||
-rw-r--r-- | chrome/browser/resources/history.html | 102 |
3 files changed, 182 insertions, 48 deletions
diff --git a/chrome/browser/dom_ui/history_ui.cc b/chrome/browser/dom_ui/history_ui.cc index ed6f3b2..0062cf0 100644 --- a/chrome/browser/dom_ui/history_ui.cc +++ b/chrome/browser/dom_ui/history_ui.cc @@ -25,6 +25,7 @@ #include "generated_resources.h" using base::Time; +using base::TimeDelta; // HistoryUI is accessible from chrome-ui://history. static const char kHistoryHost[] = "history"; @@ -68,8 +69,10 @@ void HistoryUIHTMLSource::StartDataRequest(const std::string& path, l10n_util::GetString(IDS_HISTORY_NO_RESULTS)); localized_strings.SetString(L"noitems", l10n_util::GetString(IDS_HISTORY_NO_ITEMS)); - localized_strings.SetString(L"delete", - l10n_util::GetString(IDS_HISTORY_DELETE)); + localized_strings.SetString(L"deleteday", + l10n_util::GetString(IDS_HISTORY_DELETE_PRIOR_VISITS_LINK)); + localized_strings.SetString(L"deletedaywarning", + l10n_util::GetString(IDS_HISTORY_DELETE_PRIOR_VISITS_WARNING)); static const StringPiece history_html( ResourceBundle::GetSharedInstance().GetRawDataResource( @@ -91,9 +94,14 @@ void HistoryUIHTMLSource::StartDataRequest(const std::string& path, //////////////////////////////////////////////////////////////////////////////// BrowsingHistoryHandler::BrowsingHistoryHandler(DOMUI* dom_ui) : DOMMessageHandler(dom_ui), + remover_(NULL), search_text_() { dom_ui_->RegisterMessageCallback("getHistory", NewCallback(this, &BrowsingHistoryHandler::HandleGetHistory)); + dom_ui_->RegisterMessageCallback("searchHistory", + NewCallback(this, &BrowsingHistoryHandler::HandleSearchHistory)); + dom_ui_->RegisterMessageCallback("deleteDay", + NewCallback(this, &BrowsingHistoryHandler::HandleDeleteDay)); // Create our favicon data source. g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE, @@ -111,6 +119,9 @@ BrowsingHistoryHandler::~BrowsingHistoryHandler() { NotificationService* service = NotificationService::current(); service->RemoveObserver(this, NotificationType::HISTORY_URLS_DELETED, Source<Profile>(dom_ui_->get_profile())); + + if (remover_) + remover_->RemoveObserver(this); } void BrowsingHistoryHandler::HandleGetHistory(const Value* value) { @@ -118,23 +129,82 @@ void BrowsingHistoryHandler::HandleGetHistory(const Value* value) { cancelable_consumer_.CancelAllRequests(); // Get arguments (if any). - int month; - std::wstring query; - ExtractGetHistoryArguments(value, &month, &query); + int day = 0; + ExtractIntegerValue(value, &day); // Set our query options. - history::QueryOptions options = CreateQueryOptions(month, query); + history::QueryOptions options; + options.begin_time = Time::Now().LocalMidnight(); + options.begin_time -= TimeDelta::FromDays(day); + options.end_time = Time::Now().LocalMidnight(); + options.end_time -= TimeDelta::FromDays(day - 1); + + // Need to remember the query string for our results. + search_text_ = std::wstring(); + + HistoryService* hs = + dom_ui_->get_profile()->GetHistoryService(Profile::EXPLICIT_ACCESS); + hs->QueryHistory(search_text_, + options, + &cancelable_consumer_, + NewCallback(this, &BrowsingHistoryHandler::QueryComplete)); +} + +void BrowsingHistoryHandler::HandleSearchHistory(const Value* value) { + // Anything in-flight is invalid. + cancelable_consumer_.CancelAllRequests(); + + // Get arguments (if any). + int month = 0; + std::wstring query; + ExtractSearchHistoryArguments(value, &month, &query); + + // Set the query ranges for the given month. + history::QueryOptions options = CreateMonthQueryOptions(month); + + // When searching, limit the number of results returned and only show the + // most recent matches. + options.max_count = kMaxSearchResults; + options.most_recent_visit_only = true; // Need to remember the query string for our results. search_text_ = query; HistoryService* hs = - dom_ui_->get_profile()->GetHistoryService(Profile::EXPLICIT_ACCESS); + dom_ui_->get_profile()->GetHistoryService(Profile::EXPLICIT_ACCESS); hs->QueryHistory(search_text_, options, &cancelable_consumer_, NewCallback(this, &BrowsingHistoryHandler::QueryComplete)); } +void BrowsingHistoryHandler::HandleDeleteDay(const Value* value) { + // Anything in-flight is invalid. + cancelable_consumer_.CancelAllRequests(); + + // Get time. + Time time; + bool success = Time::FromString(ExtractStringValue(value).c_str(), &time); + DCHECK(success); + + Time begin_time = time.LocalMidnight(); + Time end_time = begin_time + TimeDelta::FromDays(1); + + if (!remover_) { + remover_ = new BrowsingDataRemover(dom_ui_->get_profile(), + begin_time, + end_time); + remover_->AddObserver(this); + } + + remover_->Remove(BrowsingDataRemover::REMOVE_HISTORY | + BrowsingDataRemover::REMOVE_COOKIES | + BrowsingDataRemover::REMOVE_CACHE); +} + +void BrowsingHistoryHandler::OnBrowsingDataRemoverDone() { + dom_ui_->CallJavascriptFunction(L"deleteComplete"); +} + void BrowsingHistoryHandler::QueryComplete( HistoryService::Handle request_handle, history::QueryResults* results) { @@ -184,7 +254,7 @@ void BrowsingHistoryHandler::QueryComplete( StringValue(search_text_), results_value); } -void BrowsingHistoryHandler::ExtractGetHistoryArguments(const Value* value, +void BrowsingHistoryHandler::ExtractSearchHistoryArguments(const Value* value, int* month, std::wstring* query) { *month = 0; @@ -212,8 +282,8 @@ void BrowsingHistoryHandler::ExtractGetHistoryArguments(const Value* value, } } -history::QueryOptions BrowsingHistoryHandler::CreateQueryOptions(int month, - const std::wstring& query) { +history::QueryOptions BrowsingHistoryHandler::CreateMonthQueryOptions( + int month) { history::QueryOptions options; // Configure the begin point of the search to the start of the @@ -252,13 +322,6 @@ history::QueryOptions BrowsingHistoryHandler::CreateQueryOptions(int month, options.begin_time = Time::FromLocalExploded(exploded); } - // If searching, only show the most recent entry and limit the number of - // results returned. - if (!query.empty()) { - options.max_count = kMaxSearchResults; - options.most_recent_visit_only = true; - } - return options; } diff --git a/chrome/browser/dom_ui/history_ui.h b/chrome/browser/dom_ui/history_ui.h index 742cf81..96efd3e 100644 --- a/chrome/browser/dom_ui/history_ui.h +++ b/chrome/browser/dom_ui/history_ui.h @@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_DOM_UI_HISTORY_UI_H__ #define CHROME_BROWSER_DOM_UI_HISTORY_UI_H__ +#include "chrome/browser/browsing_data_remover.h" #include "chrome/browser/dom_ui/chrome_url_data_manager.h" #include "chrome/browser/dom_ui/dom_ui.h" #include "chrome/browser/dom_ui/dom_ui_contents.h" @@ -28,7 +29,8 @@ class HistoryUIHTMLSource : public ChromeURLDataManager::DataSource { // The handler for Javascript messages related to the "history" view. class BrowsingHistoryHandler : public DOMMessageHandler, - public NotificationObserver { + public NotificationObserver, + public BrowsingDataRemover::Observer { public: explicit BrowsingHistoryHandler(DOMUI* dom_ui_); virtual ~BrowsingHistoryHandler(); @@ -36,28 +38,39 @@ class BrowsingHistoryHandler : public DOMMessageHandler, // Callback for the "getHistory" message. void HandleGetHistory(const Value* value); + // Callback for the "searchHistory" message. + void HandleSearchHistory(const Value* value); + + // Callback for the "deleteDay" message. + void HandleDeleteDay(const Value* value); + // NotificationObserver implementation. virtual void Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details); + // BrowsingDataRemover observer implementation. + void OnBrowsingDataRemoverDone(); + private: - // Callback from the history system when the most visited list is available. + // Callback from the history system when the history list is available. void QueryComplete(HistoryService::Handle request_handle, history::QueryResults* results); - // Extract the arguments from the call to HandleGetHistory. - void ExtractGetHistoryArguments(const Value* value, - int* month, - std::wstring* query); + // Extract the arguments from the call to HandleSearchHistory. + void ExtractSearchHistoryArguments(const Value* value, + int* month, + std::wstring* query); - // Get the query options for a given month and query. - history::QueryOptions CreateQueryOptions(int month, - const std::wstring& query); + // Figure out the query options for a month-wide query. + history::QueryOptions CreateMonthQueryOptions(int month); // Current search text. std::wstring search_text_; + // Browsing history remover + BrowsingDataRemover* remover_; + // Our consumer for the history service. CancelableRequestConsumerT<PageUsageData*, NULL> cancelable_consumer_; diff --git a/chrome/browser/resources/history.html b/chrome/browser/resources/history.html index b299fac..6bc8d5c 100644 --- a/chrome/browser/resources/history.html +++ b/chrome/browser/resources/history.html @@ -6,8 +6,8 @@ <script type="text/javascript"> /////////////////////////////////////////////////////////////////////////////// // Globals: -var RESULTS_PER_PAGE = 60; -var MAX_SEARCH_DEPTH = 18; +var RESULTS_PER_PAGE = 150; +var MAX_SEARCH_DEPTH_MONTHS = 18; // Amount of time between pageviews that we consider a 'break' in browsing, // measured in milliseconds. @@ -174,8 +174,8 @@ Page.getHighlightedText_ = function(str, opt_highlight ) { * @param {string} str The source string * @return {string} The escaped string */ -Page.pregQuote_ = function(str) {
- return str.replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1");
+Page.pregQuote_ = function(str) { + return str.replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1"); } /////////////////////////////////////////////////////////////////////////////// @@ -218,6 +218,18 @@ HistoryModel.prototype.setSearchText = function(searchText, opt_page) { } /** + * Reload our model with the current parameters. + */ +HistoryModel.prototype.reload = function() { + var search = this.searchText_; + var page = this.requestedPage_; + this.clearModel_(); + this.searchText_ = search; + this.requestedPage_ = page; + this.getSearchResults_(); +} + +/** * @return {String} The current search text. */ HistoryModel.prototype.getSearchText = function() { @@ -308,7 +320,7 @@ HistoryModel.prototype.getNumberedRange = function(start, end) { HistoryModel.prototype.clearModel_ = function() { this.inFlight_ = false; // Whether a query is inflight. this.searchText_ = ''; - this.searchMonth_ = 0; + this.searchDepth_ = 0; this.pages_ = []; // Date-sorted list of pages. // The page that the view wants to see - we only fetch slightly past this @@ -325,7 +337,7 @@ HistoryModel.prototype.clearModel_ = function() { * we're ready to show something. */ HistoryModel.prototype.updateSearch_ = function() { - if (this.searchMonth_ >= MAX_SEARCH_DEPTH) { + if (this.searchText_ && this.searchDepth_ >= MAX_SEARCH_DEPTH_MONTHS) { // We have maxed out. There will be no more data. this.complete_ = true; this.view_.onModelReady(); @@ -333,7 +345,7 @@ HistoryModel.prototype.updateSearch_ = function() { // If we can't fill the requested page, ask for more data unless a request // is still in-flight. if (!this.canFillPage_(this.requestedPage_) && !this.inFlight_) { - this.getSearchResults_(this.searchMonth_ + 1); + this.getSearchResults_(this.searchDepth_ + 1); } // If we have any data for the requested page, show it. @@ -344,16 +356,26 @@ HistoryModel.prototype.updateSearch_ = function() { } /** - * Get search results for a selected month. Our history system is optimized - * for queries that don't cross month boundaries. + * Get search results for a selected depth. Our history system is optimized + * for queries that don't cross month boundaries, but an entire month's + * worth of data is huge. When we're in browse mode (searchText is empty) + * we request the data a day at a time. When we're searching, a month is + * used. * * TODO: Fix this for when the user's clock goes across month boundaries. - * @param {number} opt_month How many months back to do the search. + * @param {number} opt_day How many days back to do the search. */ -HistoryModel.prototype.getSearchResults_ = function(opt_month) { - this.searchMonth_ = opt_month || 0; - chrome.send('getHistory', - [this.searchText_, String(this.searchMonth_)]); +HistoryModel.prototype.getSearchResults_ = function(depth) { + this.searchDepth_ = depth || 0; + + if (this.searchText_ == "") { + chrome.send('getHistory', + [String(this.searchDepth_)]); + } else { + chrome.send('searchHistory', + [this.searchText_, String(this.searchDepth_)]); + } + this.inFlight_ = true; } @@ -409,6 +431,13 @@ HistoryView.prototype.setSearch = function(term, opt_page) { } /** + * Reload the current view. + */ +HistoryView.prototype.reload = function() { + this.model_.reload(); +} + +/** * Switch to a specified page. * @param {string} term The string to search for. * @param {number} opt_page The page we wish to view. @@ -457,14 +486,21 @@ HistoryView.prototype.displayResults_ = function() { for (var i = 0, page; page = results[i]; i++) { // Break across day boundaries and insert gaps for browsing pauses. var thisTime = page.time.getTime(); - if (page.continued && i == 0) { - output.push('<div class="day">' + page.dateRelativeDay + ' ' + - localStrings.getString('cont') + '</div>'); - } else if (!page.continued) { - output.push('<div class="day">' + page.dateRelativeDay + '</div>'); + + if ((i == 0 && page.continued) || !page.continued) { + output.push('<div class="day">' + page.dateRelativeDay); + + if (i == 0 && page.continued) + output.push(' ' + localStrings.getString('cont')); + + output.push('<a href="#" class="delete-day" ' + + 'onclick="return deleteDay(\'' + + page.time.toString() + '\');">' + + localStrings.getString("deleteday") + '</a>'); + output.push('</div>'); } else if (lastTime - thisTime > BROWSING_GAP_TIME) { output.push('<div class="gap"></div>'); - } + } lastTime = thisTime; // Draw entry. @@ -472,7 +508,6 @@ HistoryView.prototype.displayResults_ = function() { } } this.resultDiv_.innerHTML = output.join(""); - this.displaySummaryBar_(); this.displayNavBar_(); } @@ -655,6 +690,16 @@ function setPage(page) { } } +/** + * Delete a day from history. + * @param {number} time A time from the day we wish to delete. + */ +function deleteDay(time) { + if (confirm(localStrings.getString("deletedaywarning"))) + chrome.send("deleteDay", [time.toString()]); + return false; +} + /////////////////////////////////////////////////////////////////////////////// // Chrome callbacks: /** @@ -663,6 +708,13 @@ function setPage(page) { function historyResult(term, results) { historyModel.addResults(term, results); } + +/** + * Our history system calls this function when a deletion has finished. + */ +function deleteComplete() { + historyView.reload(); +} </script> <style type="text/css"> body { @@ -698,6 +750,11 @@ body { .day { margin-top:18px; margin-left:3px; + width:750px; +} +.delete-day { + width:200px; + float:right; } .gap { margin-left:18px; @@ -783,7 +840,8 @@ html[dir='rtl'] .entry .title a { <span id="cont" jscontent="cont">(cont.)</span> <span id="noresults" jscontent="noresults">No results</span> <span id="noitems" jscontent="noitems">No items</span> - <span id="delete" jscontent="delete">delete</span> + <span id="deleteday" jscontent="deleteday">Delete history for this day</span> + <span id="deletedaywarning" jscontent="deletedaywarning">Are you sure you want to delete this day?</span> </div> </body> </html>
\ No newline at end of file |