Chromium Code Reviews| Index: chrome/browser/browser_about_handler.cc |
| =================================================================== |
| --- chrome/browser/browser_about_handler.cc (revision 90144) |
| +++ chrome/browser/browser_about_handler.cc (working copy) |
| @@ -107,7 +107,7 @@ |
| // Add paths here to be included in chrome://chrome-urls/. |
| // These paths will also be suggested by BuiltinProvider. |
| -const char* kChromePaths[] = { |
| +const char* const kChromePaths[] = { |
| chrome::kChromeUIAppCacheInternalsHost, |
| chrome::kChromeUIBlobInternalsHost, |
| chrome::kChromeUIChromeURLsHost, |
| @@ -146,7 +146,7 @@ |
| // Debug paths, presented without links in chrome://about. |
| // These paths will not be suggested by BuiltinProvider. |
| -const char* kDebugChromePaths[] = { |
| +const char* const kDebugChromePaths[] = { |
| chrome::kChromeUICrashHost, |
| chrome::kChromeUIKillHost, |
| chrome::kChromeUIHangHost, |
| @@ -157,7 +157,7 @@ |
| }; |
| // AboutSource handles these chrome:// paths. |
| -const char *kAboutSourceNames[] = { |
| +const char* const kAboutSourceNames[] = { |
| chrome::kChromeUIChromeURLsHost, |
| chrome::kChromeUICreditsHost, |
| chrome::kChromeUIDNSHost, |
| @@ -184,6 +184,14 @@ |
| #endif |
| }; |
| +const char kCreditsJsPath[] = "credits.js"; |
| +const char kMemoryJsPath[] = "memory.js"; |
| +const char kStatsJsPath[] = "stats.js"; |
| +const char kStringsJsPath[] = "strings.js"; |
| +const char kVersionJsPath[] = "version.js"; |
| + |
| +} // namespace |
| + |
| class AboutSource : public ChromeURLDataManager::DataSource { |
| public: |
| // Construct a data source for the specified |source_name|. |
| @@ -195,9 +203,7 @@ |
| bool is_incognito, |
| int request_id) OVERRIDE; |
| - virtual std::string GetMimeType(const std::string&) const OVERRIDE { |
| - return "text/html"; |
| - } |
| + virtual std::string GetMimeType(const std::string& path) const OVERRIDE; |
| // Send the response data. |
| void FinishDataRequest(const std::string& html, int request_id); |
| @@ -212,6 +218,8 @@ |
| DISALLOW_COPY_AND_ASSIGN(AboutSource); |
| }; |
| +namespace { |
| + |
| // Register a data source for a known source name. Safe to call multiple times. |
| // |name| may be an unkown host (e.g. "chrome://foo/"); only handle known hosts. |
| void InitializeAboutDataSource(const std::string& name, Profile* profile) { |
| @@ -360,9 +368,39 @@ |
| // Individual about handlers --------------------------------------------------- |
| +namespace { |
| + |
| +void AppendHeader(std::string* output, int refresh, |
| + const std::string& unescaped_title) { |
| + output->append("<!DOCTYPE HTML>\n<html>\n<head>\n"); |
| + if (!unescaped_title.empty()) { |
| + output->append("<title>"); |
| + output->append(EscapeForHTML(unescaped_title)); |
| + output->append("</title>\n"); |
| + } |
| + output->append( |
| + "<meta charset=\"utf-8\">\n<meta http-equiv=\"X-WebKit-CSP\" " |
| + "content=\"object-src 'none'; script-src 'self'\">\n"); |
| + if (refresh > 0) { |
| + output->append("<meta http-equiv=\"refresh\" content=\""); |
| + output->append(base::IntToString(refresh)); |
| + output->append("\"/>\n"); |
| + } |
| +} |
| + |
| +void AppendBody(std::string *output) { |
| + output->append("</head>\n<body>\n"); |
| +} |
| + |
| +void AppendFooter(std::string *output) { |
| + output->append("</body>\n</html>\n"); |
| +} |
| + |
| std::string ChromeURLs() { |
| - std::string html("<html><head><title>Chrome URLs</title></head>\n" |
| - "<body><h2>List of Chrome URLs</h2>\n<ul>"); |
| + std::string html; |
| + AppendHeader(&html, 0, "Chrome URLs"); |
| + AppendBody(&html); |
| + html += "<h2>List of Chrome URLs</h2>\n<ul>\n"; |
| std::vector<std::string> paths(ChromePaths()); |
| for (std::vector<std::string>::const_iterator i = paths.begin(); |
| i != paths.end(); ++i) |
| @@ -373,13 +411,13 @@ |
| "them into the address bar if you need them.</p>\n<ul>"; |
| for (size_t i = 0; i < arraysize(kDebugChromePaths); i++) |
| html += "<li>chrome://" + std::string(kDebugChromePaths[i]) + "</li>\n"; |
| - html += "</ul>\n</body></html>"; |
| + html += "</ul>\n"; |
| + AppendFooter(&html); |
| return html; |
| } |
| #if defined(OS_CHROMEOS) |
| -namespace { |
| // Html output helper functions |
| // TODO(stevenjb): L10N this. |
| @@ -398,27 +436,16 @@ |
| return "<tr>" + text + "</tr>"; |
| } |
| -std::string AboutHeader(int refresh, const std::string& name) { |
| - std::string output; |
| - output.append("<head>"); |
| - output.append("<title>About " + name + "</title>"); |
| - if (refresh > 0) |
| - output.append("<meta http-equiv=\"refresh\" content=\"" + |
| - base::IntToString(refresh) + "\"/>"); |
| - output.append("</head>"); |
| - return output; |
| -} |
| - |
| -std::string AboutRefresh(int refresh, const std::string& name) { |
| - std::string output; |
| +void AppendRefresh(std::string *output, int refresh, const std::string& name) { |
| if (refresh > 0) { |
| - output.append("(Auto-refreshing page every " + |
| - base::IntToString(refresh) + "s)"); |
| + output->append("(Auto-refreshing page every "); |
| + output->append(base::IntToString(refresh)); |
| + output->append("s)"); |
| } else { |
| - output.append("(To auto-refresh this page: about:" + name |
| - + "/<secs>)"); |
| + output->append("(To auto-refresh this page: about:"); |
| + output->append(name); |
| + output->append("/<secs>)"); |
| } |
| - return output; |
| } |
| // Helper function to create an Html table header for a Network. |
| @@ -500,10 +527,9 @@ |
| chromeos::NetworkLibrary* cros = |
| chromeos::CrosLibrary::Get()->GetNetworkLibrary(); |
| std::string output; |
| - output.append("<html>"); |
| - output.append(AboutHeader(refresh, "Network")); |
| - output.append("<body>"); |
| - output.append(AboutRefresh(refresh, "network")); |
| + AppendHeader(&output, refresh, "About Network"); |
| + AppendBody(&output); |
| + AppendRefresh(&output, refresh, "network"); |
| if (cros->ethernet_enabled()) { |
| output.append("<h3>Ethernet:</h3><table border=1>"); |
| @@ -559,7 +585,8 @@ |
| } |
| } |
| - output.append("</table></body></html>"); |
| + output.append("</table>"); |
| + AppendFooter(&output); |
| return output; |
| } |
| @@ -587,10 +614,9 @@ |
| chromeos::CryptohomeLibrary* cryptohome = |
| chromeos::CrosLibrary::Get()->GetCryptohomeLibrary(); |
| std::string output; |
| - output.append("<html>"); |
| - output.append(AboutHeader(refresh, "Cryptohome")); |
| - output.append("<body>"); |
| - output.append(AboutRefresh(refresh, "cryptohome")); |
| + AppendHeader(&output, refresh, "About Cryptohome"); |
| + AppendBody(&output); |
| + AppendRefresh(&output, refresh, "cryptohome"); |
| output.append("<h3>CryptohomeLibrary:</h3>"); |
| output.append("<table>"); |
| @@ -611,9 +637,8 @@ |
| output.append(AddStringRow("token_name", token_name)); |
| output.append(AddStringRow("user_pin", std::string(user_pin.length(), '*'))); |
| output.append("</table>"); |
| + AppendFooter(&output); |
| - output.append("</body>"); |
| - output.append("</html>"); |
| return output; |
| } |
| @@ -623,8 +648,9 @@ |
| return GetCryptohomeHtmlInfo(refresh); |
| } |
| +#endif // OS_CHROMEOS |
| + |
| } // namespace |
| -#endif |
| // AboutDnsHandler bounces the request back to the IO thread to collect |
| // the DNS information. |
| @@ -655,7 +681,10 @@ |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| std::string data; |
| + AppendHeader(&data, 0, "About DNS"); |
| + AppendBody(&data); |
| chrome_browser_net::PredictorGetHtmlInfo(&data); |
| + AppendFooter(&data); |
| BrowserThread::PostTask( |
| BrowserThread::UI, FROM_HERE, |
| @@ -683,7 +712,8 @@ |
| AboutTcmallocOutputs::GetInstance()->outputs(); |
| // Display any stats for which we sent off requests the last time. |
| - data.append("<html><head><title>About tcmalloc</title></head><body>\n"); |
| + AppendHeader(&data, 0, "About tcmalloc"); |
| + AppendBody(&data); |
| data.append("<p>Stats as of last page load;"); |
| data.append("reload to get stats as of this page load.</p>\n"); |
| data.append("<table width=\"100%\">\n"); |
| @@ -698,7 +728,7 @@ |
| data.append("</pre></td></tr>\n"); |
| } |
| data.append("</table>\n"); |
| - data.append("</body></html>\n"); |
| + AppendFooter(&data); |
| // Reset our collector singleton. |
| outputs->clear(); |
| @@ -727,23 +757,49 @@ |
| DCHECK(current_synchronizer != NULL); |
| current_synchronizer->FetchRendererHistogramsSynchronously(wait_time); |
| + std::string unescaped_query; |
| + std::string unescaped_title("About Histograms"); |
| + if (!query.empty()) |
|
Evan Martin
2011/06/24 18:05:32
curly on same line as if
|
| + { |
| + unescaped_query = UnescapeURLComponent(query, UnescapeRule::NORMAL); |
| + unescaped_title += " - " + unescaped_query; |
| + } |
| + |
| std::string data; |
| - base::StatisticsRecorder::WriteHTMLGraph(query, &data); |
| + AppendHeader(&data, 0, unescaped_title); |
| + AppendBody(&data); |
| + base::StatisticsRecorder::WriteHTMLGraph(unescaped_query, &data); |
| + AppendFooter(&data); |
| return data; |
| } |
| -void AboutMemory(AboutSource* source, int request_id) { |
| - // The AboutMemoryHandler cleans itself up, but |StartFetch()| will want the |
| - // refcount to be greater than 0. |
| - scoped_refptr<AboutMemoryHandler> |
| - handler(new AboutMemoryHandler(source, request_id)); |
| - handler->StartFetch(); |
| +void AboutMemory(const std::string& path, AboutSource* source, int request_id) { |
| + if (path == kStringsJsPath) { |
| + // The AboutMemoryHandler cleans itself up, but |StartFetch()| will want the |
| + // refcount to be greater than 0. |
| + scoped_refptr<AboutMemoryHandler> |
| + handler(new AboutMemoryHandler(source, request_id)); |
| + handler->StartFetch(); |
| + } else { |
| + source->FinishDataRequest( |
| + ResourceBundle::GetSharedInstance().GetRawDataResource( |
| + path == kMemoryJsPath ? IDR_ABOUT_MEMORY_JS : |
| + IDR_ABOUT_MEMORY_HTML).as_string(), request_id); |
| + } |
| } |
| #ifdef TRACK_ALL_TASK_OBJECTS |
| static std::string AboutObjects(const std::string& query) { |
| + std::string unescaped_title("About Histograms"); |
| + if (!query.empty()) { |
| + unescaped_title += " - "; |
| + unescaped_title += UnescapeURLComponent(query, UnescapeRule::NORMAL); |
| + } |
| std::string data; |
| + AppendHeader(&data, 0, unescaped_title); |
| + AppendBody(&data); |
| tracked_objects::ThreadData::WriteHTML(query, &data); |
| + AppendFooter(&data); |
| return data; |
| } |
| #endif // TRACK_ALL_TASK_OBJECTS |
| @@ -853,8 +909,10 @@ |
| } |
| std::string data; |
| - if (query == "json") { |
| + if (query == "json" || query == kStringsJsPath) { |
| base::JSONWriter::WriteWithOptionalEscape(&root, true, false, &data); |
| + if (query == kStringsJsPath) |
| + data = "var templateData = " + data + ";"; |
| } else if (query == "raw") { |
| // Dump the raw counters which have changed in text format. |
| data = "<pre>"; |
| @@ -887,22 +945,21 @@ |
| } |
| data.append("</pre>"); |
| } else { |
| - // Get about_stats.html and process a pretty page. |
| - static const base::StringPiece stats_html( |
| - ResourceBundle::GetSharedInstance().GetRawDataResource( |
| - IDR_ABOUT_STATS_HTML)); |
| + // Get about_stats.html/js from resource bundle. |
| + data = ResourceBundle::GetSharedInstance().GetRawDataResource( |
| + (query == kStatsJsPath ? IDR_ABOUT_STATS_JS : IDR_ABOUT_STATS_HTML)). |
| + as_string(); |
| - // Create jstemplate and return. |
| - data = jstemplate_builder::GetTemplateHtml( |
| - stats_html, &root, "t" /* template root node id */); |
| - |
| - // Clear the timer list since we stored the data in the timers list as well. |
| - for (int index = static_cast<int>(timers->GetSize())-1; index >= 0; |
| - index--) { |
| - Value* value; |
| - timers->Remove(index, &value); |
| - // We don't care about the value pointer; it's still tracked |
| - // on the counters list. |
| + if (query != kStatsJsPath) { |
| + // Clear the timer list since we stored the data in the timers list |
| + // as well. |
| + for (int index = static_cast<int>(timers->GetSize())-1; index >= 0; |
| + index--) { |
| + Value* value; |
| + timers->Remove(index, &value); |
| + // We don't care about the value pointer; it's still tracked |
| + // on the counters list. |
| + } |
| } |
| } |
| @@ -912,18 +969,16 @@ |
| #if defined(OS_LINUX) |
| std::string AboutLinuxProxyConfig() { |
| std::string data; |
| - data.append("<!DOCTYPE HTML>\n"); |
| - data.append("<html><head><meta charset=\"utf-8\"><title>"); |
| - data.append(l10n_util::GetStringUTF8(IDS_ABOUT_LINUX_PROXY_CONFIG_TITLE)); |
| - data.append("</title>"); |
| + AppendHeader(&data, 0, |
| + l10n_util::GetStringUTF8(IDS_ABOUT_LINUX_PROXY_CONFIG_TITLE)); |
| data.append("<style>body { max-width: 70ex; padding: 2ex 5ex; }</style>"); |
| - data.append("</head><body>\n"); |
| + AppendBody(&data); |
| FilePath binary = CommandLine::ForCurrentProcess()->GetProgram(); |
| data.append(l10n_util::GetStringFUTF8( |
| - IDS_ABOUT_LINUX_PROXY_CONFIG_BODY, |
| - l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), |
| - ASCIIToUTF16(binary.BaseName().value()))); |
| - data.append("</body></html>\n"); |
| + IDS_ABOUT_LINUX_PROXY_CONFIG_BODY, |
| + l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), |
| + ASCIIToUTF16(binary.BaseName().value()))); |
| + AppendFooter(&data); |
| return data; |
| } |
| @@ -946,11 +1001,8 @@ |
| std::string AboutSandbox() { |
| std::string data; |
| - data.append("<!DOCTYPE HTML>\n"); |
| - data.append("<html><head><meta charset=\"utf-8\"><title>"); |
| - data.append(l10n_util::GetStringUTF8(IDS_ABOUT_SANDBOX_TITLE)); |
| - data.append("</title>"); |
| - data.append("</head><body>\n"); |
| + AppendHeader(&data, 0, l10n_util::GetStringUTF8(IDS_ABOUT_SANDBOX_TITLE)); |
| + AppendBody(&data); |
| data.append("<h1>"); |
| data.append(l10n_util::GetStringUTF8(IDS_ABOUT_SANDBOX_TITLE)); |
| data.append("</h1>"); |
| @@ -982,12 +1034,21 @@ |
| } |
| data.append("</p>"); |
| - data.append("</body></html>\n"); |
| + AppendFooter(&data); |
| return data; |
| } |
| #endif |
| -std::string AboutVersion(DictionaryValue* localized_strings, Profile* profile) { |
| +std::string AboutVersion(const std::string& query, |
| + DictionaryValue* localized_strings, |
| + Profile* profile) { |
| + if (query != kStringsJsPath) { |
| + int idr = (query == kVersionJsPath) ? |
| + IDR_ABOUT_VERSION_JS : IDR_ABOUT_VERSION_HTML; |
| + return ResourceBundle::GetSharedInstance().GetRawDataResource( |
| + idr).as_string(); |
| + } |
| + |
| localized_strings->SetString("title", |
| l10n_util::GetStringUTF16(IDS_ABOUT_VERSION_TITLE)); |
| chrome::VersionInfo version_info; |
| @@ -1087,14 +1148,13 @@ |
| l10n_util::GetStringUTF16(IDS_ABOUT_VERSION_PATH_NOTFOUND)); |
| } |
| - base::StringPiece version_html( |
| - ResourceBundle::GetSharedInstance().GetRawDataResource( |
| - IDR_ABOUT_VERSION_HTML)); |
| - |
| - return jstemplate_builder::GetTemplatesHtml( |
| - version_html, localized_strings, "t" /* template root node id */); |
| + std::string data; |
| + jstemplate_builder::AppendJsonJS(localized_strings, &data); |
| + return data; |
| } |
| +} // namespace |
| + |
| // AboutSource ----------------------------------------------------------------- |
| AboutSource::AboutSource(const std::string& source_name, Profile* profile) |
| @@ -1118,7 +1178,7 @@ |
| } else if (host == chrome::kChromeUIMemoryHost) { |
| response = GetAboutMemoryRedirectResponse(profile()); |
| } else if (host == chrome::kChromeUIMemoryRedirectHost) { |
| - AboutMemory(this, request_id); |
| + AboutMemory(path, this, request_id); |
| return; |
| #ifdef TRACK_ALL_TASK_OBJECTS |
| } else if (host == chrome::kChromeUITasksHost) { |
| @@ -1137,11 +1197,12 @@ |
| #else |
| DictionaryValue localized_strings; |
| localized_strings.SetString("os_version", ""); |
| - response = AboutVersion(&localized_strings, profile_); |
| + response = AboutVersion(path, &localized_strings, profile_); |
| #endif |
| } else if (host == chrome::kChromeUICreditsHost) { |
| + int idr = (path == kCreditsJsPath) ? IDR_CREDITS_JS : IDR_CREDITS_HTML; |
| response = ResourceBundle::GetSharedInstance().GetRawDataResource( |
| - IDR_CREDITS_HTML).as_string(); |
| + idr).as_string(); |
| } else if (host == chrome::kChromeUIChromeURLsHost) { |
| response = ChromeURLs(); |
| #if defined(OS_CHROMEOS) |
| @@ -1179,6 +1240,19 @@ |
| SendResponse(request_id, html_bytes); |
| } |
| +std::string AboutSource::GetMimeType(const std::string& path) const OVERRIDE { |
| + if (path == kCreditsJsPath || |
| + path == kStatsJsPath || |
| + path == kStringsJsPath || |
| + path == kVersionJsPath || |
| + path == kMemoryJsPath) { |
| + return "application/javascript"; |
| + } |
| + return "text/html"; |
| +} |
| + |
| +namespace { |
| + |
| // AboutMemoryHandler ---------------------------------------------------------- |
| // Helper for AboutMemory to bind results from a ProcessMetrics object |
| @@ -1300,16 +1374,9 @@ |
| root.SetBoolean("show_other_browsers", |
| browser_defaults::kShowOtherBrowsersInAboutMemory); |
| - // Get about_memory.html |
| - static const base::StringPiece memory_html( |
| - ResourceBundle::GetSharedInstance().GetRawDataResource( |
| - IDR_ABOUT_MEMORY_HTML)); |
| - |
| - // Create jstemplate and return. |
| - std::string template_html = jstemplate_builder::GetTemplateHtml( |
| - memory_html, &root, "t" /* template root node id */); |
| - |
| - source_->FinishDataRequest(template_html, request_id_); |
| + std::string data; |
| + jstemplate_builder::AppendJsonJS(&root, &data); |
| + source_->FinishDataRequest(data, request_id_); |
| } |
| #if defined(OS_CHROMEOS) |