Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(759)

Side by Side Diff: chrome/browser/dom_ui/history_ui.cc

Issue 12418: Implement History as HTML and add/change a bunch of stuff to make it easier t... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/dom_ui/history_ui.h ('k') | chrome/browser/dom_ui/new_tab_ui.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2006-2008 The Chromium Authors. 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 "chrome/browser/dom_ui/history_ui.h"
6
7 #include "base/message_loop.h"
8 #include "base/string_piece.h"
9 #include "base/thread.h"
10 #include "base/time.h"
11 #include "base/time_format.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/browser_resources.h"
14 #include "chrome/browser/history/history_types.h"
15 #include "chrome/browser/profile.h"
16 #include "chrome/browser/user_metrics.h"
17 #include "chrome/common/jstemplate_builder.h"
18 #include "chrome/common/l10n_util.h"
19 #include "chrome/common/resource_bundle.h"
20 #include "chrome/common/time_format.h"
21
22 #include "chromium_strings.h"
23 #include "generated_resources.h"
24
25 using base::Time;
26
27 // HistoryUI is accessible from chrome://history, and the raw HTML is
28 // accessed from chrome://history.
29 static const std::string kHistoryHost = "history";
30
31 // Maximum number of search results to return in a given search. We should
32 // eventually remove this.
33 static const int kMaxSearchResults = 100;
34
35 ////////////////////////////////////////////////////////////////////////////////
36 //
37 // HistoryHTMLSource
38 //
39 ////////////////////////////////////////////////////////////////////////////////
40
41 HistoryUIHTMLSource::HistoryUIHTMLSource()
42 : DataSource(kHistoryHost, MessageLoop::current()) {
43 }
44
45 void HistoryUIHTMLSource::StartDataRequest(const std::string& path,
46 int request_id) {
47 DictionaryValue localized_strings;
48 localized_strings.SetString(L"title",
49 l10n_util::GetString(IDS_HISTORY_TITLE));
50 localized_strings.SetString(L"loading",
51 l10n_util::GetString(IDS_HISTORY_LOADING));
52 localized_strings.SetString(L"newest",
53 l10n_util::GetString(IDS_HISTORY_NEWEST));
54 localized_strings.SetString(L"newer",
55 l10n_util::GetString(IDS_HISTORY_NEWER));
56 localized_strings.SetString(L"older",
57 l10n_util::GetString(IDS_HISTORY_OLDER));
58 localized_strings.SetString(L"searchresultsfor",
59 l10n_util::GetString(IDS_HISTORY_SEARCHRESULTSFOR));
60 localized_strings.SetString(L"history",
61 l10n_util::GetString(IDS_HISTORY_BROWSERESULTS));
62 localized_strings.SetString(L"cont",
63 l10n_util::GetString(IDS_HISTORY_CONTINUED));
64 localized_strings.SetString(L"searchbutton",
65 l10n_util::GetString(IDS_HISTORY_SEARCH_BUTTON));
66 localized_strings.SetString(L"noresults",
67 l10n_util::GetString(IDS_HISTORY_NO_RESULTS));
68 localized_strings.SetString(L"noitems",
69 l10n_util::GetString(IDS_HISTORY_NO_ITEMS));
70 localized_strings.SetString(L"delete",
71 l10n_util::GetString(IDS_HISTORY_DELETE));
72
73 static const StringPiece history_html(
74 ResourceBundle::GetSharedInstance().GetRawDataResource(
75 IDR_HISTORY_HTML));
76 const std::string full_html = jstemplate_builder::GetTemplateHtml(
77 history_html, &localized_strings, "t");
78
79 scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
80 html_bytes->data.resize(full_html.size());
81 std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
82
83 SendResponse(request_id, html_bytes);
84 }
85
86 ////////////////////////////////////////////////////////////////////////////////
87 //
88 // HistoryHandler
89 //
90 ////////////////////////////////////////////////////////////////////////////////
91 BrowsingHistoryHandler::BrowsingHistoryHandler(DOMUI* dom_ui)
92 : DOMMessageHandler(dom_ui),
93 search_text_() {
94 dom_ui_->RegisterMessageCallback("getHistory",
95 NewCallback(this, &BrowsingHistoryHandler::HandleGetHistory));
96
97 // Create our favicon data source.
98 g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
99 NewRunnableMethod(&chrome_url_data_manager,
100 &ChromeURLDataManager::AddDataSource,
101 new FavIconSource(dom_ui_->get_profile())));
102
103 // Get notifications when history is cleared.
104 NotificationService* service = NotificationService::current();
105 service->AddObserver(this, NOTIFY_HISTORY_URLS_DELETED,
106 Source<Profile>(dom_ui_->get_profile()));
107 }
108
109 BrowsingHistoryHandler::~BrowsingHistoryHandler() {
110 NotificationService* service = NotificationService::current();
111 service->RemoveObserver(this, NOTIFY_HISTORY_URLS_DELETED,
112 Source<Profile>(dom_ui_->get_profile()));
113 }
114
115 void BrowsingHistoryHandler::HandleGetHistory(const Value* value) {
116 // Anything in-flight is invalid.
117 cancelable_consumer_.CancelAllRequests();
118
119 // Get arguments (if any).
120 int month;
121 std::wstring query;
122 ExtractGetHistoryArguments(value, &month, &query);
123
124 // Set our query options.
125 history::QueryOptions options = CreateQueryOptions(month, query);
126
127 // Need to remember the query string for our results.
128 search_text_ = query;
129 HistoryService* hs =
130 dom_ui_->get_profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
131 hs->QueryHistory(search_text_,
132 options,
133 &cancelable_consumer_,
134 NewCallback(this, &BrowsingHistoryHandler::QueryComplete));
135 }
136
137 void BrowsingHistoryHandler::QueryComplete(
138 HistoryService::Handle request_handle,
139 history::QueryResults* results) {
140
141 ListValue results_value;
142 Time midnight_today = Time::Now().LocalMidnight();
143
144 for (size_t i = 0; i < results->size(); ++i) {
145 history::URLResult const &page = (*results)[i];
146 DictionaryValue* page_value = new DictionaryValue();
147 SetURLAndTitle(page_value, page.title(), page.url());
148
149 // Need to pass the time in epoch time (fastest JS conversion).
150 page_value->SetInteger(L"time",
151 static_cast<int>(page.visit_time().ToTimeT()));
152
153 // Until we get some JS i18n infrastructure, we also need to
154 // pass the dates in as strings. This could use some
155 // optimization.
156
157 // Only pass in the strings we need (search results need a shortdate
158 // and snippet, browse results need day and time information).
159 if (search_text_.empty()) {
160 // Figure out the relative date string.
161 std::wstring date_str = TimeFormat::RelativeDate(page.visit_time(),
162 &midnight_today);
163 if (date_str.empty()) {
164 date_str = base::TimeFormatFriendlyDate(page.visit_time());
165 } else {
166 date_str = l10n_util::GetStringF(
167 IDS_HISTORY_DATE_WITH_RELATIVE_TIME,
168 date_str, base::TimeFormatFriendlyDate(page.visit_time()));
169 }
170 page_value->SetString(L"dateRelativeDay", date_str);
171 page_value->SetString(L"dateTimeOfDay",
172 base::TimeFormatTimeOfDay(page.visit_time()));
173 } else {
174 page_value->SetString(L"dateShort",
175 base::TimeFormatShortDate(page.visit_time()));
176 page_value->SetString(L"snippet", page.snippet().text());
177 }
178
179 results_value.Append(page_value);
180 }
181
182 dom_ui_->CallJavascriptFunction(L"historyResult",
183 StringValue(search_text_), results_value);
184 }
185
186 void BrowsingHistoryHandler::ExtractGetHistoryArguments(const Value* value,
187 int* month, std::wstring* query) {
188 *month = 0;
189
190 if (value && value->GetType() == Value::TYPE_LIST) {
191 const ListValue* list_value = static_cast<const ListValue*>(value);
192 Value* list_member;
193
194 // Get search string.
195 if (list_value->Get(0, &list_member) &&
196 list_member->GetType() == Value::TYPE_STRING) {
197 const StringValue* string_value =
198 static_cast<const StringValue*>(list_member);
199 string_value->GetAsString(query);
200 }
201
202 // Get search month.
203 if (list_value->Get(1, &list_member) &&
204 list_member->GetType() == Value::TYPE_STRING) {
205 const StringValue* string_value =
206 static_cast<const StringValue*>(list_member);
207 std::wstring wstring_value;
208 string_value->GetAsString(&wstring_value);
209 *month = _wtoi(wstring_value.c_str());
210 }
211 }
212 }
213
214 history::QueryOptions BrowsingHistoryHandler::CreateQueryOptions(int month,
215 const std::wstring& query) {
216 history::QueryOptions options;
217
218 // Configure the begin point of the search to the start of the
219 // current month.
220 Time::Exploded exploded;
221 Time::Now().LocalMidnight().LocalExplode(&exploded);
222 exploded.day_of_month = 1;
223
224 if (month == 0) {
225 options.begin_time = Time::FromLocalExploded(exploded);
226
227 // Set the end time of this first search to null (which will
228 // show results from the future, should the user's clock have
229 // been set incorrectly).
230 options.end_time = Time();
231 } else {
232 // Set the end-time of this search to the end of the month that is
233 // |depth| months before the search end point. The end time is not
234 // inclusive, so we should feel free to set it to midnight on the
235 // first day of the following month.
236 exploded.month -= month - 1;
237 while (exploded.month < 1) {
238 exploded.month += 12;
239 exploded.year--;
240 }
241 options.end_time = Time::FromLocalExploded(exploded);
242
243 // Set the begin-time of the search to the start of the month
244 // that is |depth| months prior to search_start_.
245 if (exploded.month > 1) {
246 exploded.month--;
247 } else {
248 exploded.month = 12;
249 exploded.year--;
250 }
251 options.begin_time = Time::FromLocalExploded(exploded);
252 }
253
254 // If searching, only show the most recent entry and limit the number of
255 // results returned.
256 if (!query.empty()) {
257 options.max_count = kMaxSearchResults;
258 options.most_recent_visit_only = true;
259 }
260
261 return options;
262 }
263
264 void BrowsingHistoryHandler::Observe(NotificationType type,
265 const NotificationSource& source,
266 const NotificationDetails& details) {
267 if (type != NOTIFY_HISTORY_URLS_DELETED) {
268 NOTREACHED();
269 return;
270 }
271
272 // Some URLs were deleted from history. Reload the most visited list.
273 HandleGetHistory(NULL);
274 }
275
276 ////////////////////////////////////////////////////////////////////////////////
277 //
278 // HistoryUIContents
279 //
280 ////////////////////////////////////////////////////////////////////////////////
281
282 HistoryUI::HistoryUI(DOMUIContents* contents) : DOMUI(contents) {
283 }
284
285 void HistoryUI::Init() {
286 AddMessageHandler(new BrowsingHistoryHandler(this));
287
288 HistoryUIHTMLSource* html_source = new HistoryUIHTMLSource();
289
290 // Set up the chrome://history/ source.
291 g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
292 NewRunnableMethod(&chrome_url_data_manager,
293 &ChromeURLDataManager::AddDataSource,
294 html_source));
295 }
296
297 // static
298 GURL HistoryUI::GetBaseURL() {
299 std::string url = DOMUIContents::GetScheme();
300 url += "://";
301 url += kHistoryHost;
302 return GURL(url);
303 }
OLDNEW
« no previous file with comments | « chrome/browser/dom_ui/history_ui.h ('k') | chrome/browser/dom_ui/new_tab_ui.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698