diff options
author | tsepez@chromium.org <tsepez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-28 17:35:18 +0000 |
---|---|---|
committer | tsepez@chromium.org <tsepez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-28 17:35:18 +0000 |
commit | be843e26b00f611d3bcf3b2652b8eccf95310346 (patch) | |
tree | a364e6cc8a143e6dfbcc047f35c13ebbddca4dae /chrome/browser | |
parent | e01d28171595bd723e6fd9846a7783c037d882f1 (diff) | |
download | chromium_src-be843e26b00f611d3bcf3b2652b8eccf95310346.zip chromium_src-be843e26b00f611d3bcf3b2652b8eccf95310346.tar.gz chromium_src-be843e26b00f611d3bcf3b2652b8eccf95310346.tar.bz2 |
Apply CSP to chrome: and about: pages
Apply Content Security Policy to the chrome://credits page, and the other pages handled by browser_about_handler.cc while we're at it. Move inline JS out of several html files. Move top-level page generation to the about_handler.cc, with tracked_objects.cc/hisogram.cc generating markup fragments to be included. This keeps this files agnostic to CSP issues. Also fix an output encoding issue in the <title> of some pages.
Review URL: http://codereview.chromium.org/7215034
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@90788 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/browser_about_handler.cc | 432 | ||||
-rw-r--r-- | chrome/browser/browser_resources.grd | 8 | ||||
-rw-r--r-- | chrome/browser/net/predictor_api.cc | 5 | ||||
-rw-r--r-- | chrome/browser/resources/about_credits.js | 38 | ||||
-rw-r--r-- | chrome/browser/resources/about_credits.tmpl | 25 | ||||
-rw-r--r-- | chrome/browser/resources/about_credits_entry.tmpl | 2 | ||||
-rw-r--r-- | chrome/browser/resources/about_memory.html | 85 | ||||
-rw-r--r-- | chrome/browser/resources/about_memory.js | 83 | ||||
-rw-r--r-- | chrome/browser/resources/about_memory_linux.html | 86 | ||||
-rw-r--r-- | chrome/browser/resources/about_memory_mac.html | 85 | ||||
-rw-r--r-- | chrome/browser/resources/about_stats.html | 217 | ||||
-rw-r--r-- | chrome/browser/resources/about_stats.js | 202 | ||||
-rw-r--r-- | chrome/browser/resources/about_version.html | 6 | ||||
-rw-r--r-- | chrome/browser/resources/about_version.js | 14 |
14 files changed, 637 insertions, 651 deletions
diff --git a/chrome/browser/browser_about_handler.cc b/chrome/browser/browser_about_handler.cc index 36605d5..5805599 100644 --- a/chrome/browser/browser_about_handler.cc +++ b/chrome/browser/browser_about_handler.cc @@ -106,7 +106,7 @@ namespace { // 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, @@ -145,7 +145,7 @@ const char* kChromePaths[] = { // 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, @@ -156,7 +156,7 @@ const char* kDebugChromePaths[] = { }; // AboutSource handles these chrome:// paths. -const char *kAboutSourceNames[] = { +const char* const kAboutSourceNames[] = { chrome::kChromeUIChromeURLsHost, chrome::kChromeUICreditsHost, chrome::kChromeUIDNSHost, @@ -183,6 +183,12 @@ const char *kAboutSourceNames[] = { #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"; + class AboutSource : public ChromeURLDataManager::DataSource { public: // Construct a data source for the specified |source_name|. @@ -194,9 +200,7 @@ class AboutSource : public ChromeURLDataManager::DataSource { 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); @@ -359,9 +363,37 @@ class ChromeOSTermsHandler // Individual about handlers --------------------------------------------------- +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' 'unsafe-eval'\">\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) @@ -372,13 +404,13 @@ std::string ChromeURLs() { "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. @@ -397,27 +429,16 @@ std::string WrapWithTR(const std::string& text) { 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. @@ -499,10 +520,9 @@ std::string GetNetworkHtmlInfo(int refresh) { 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>"); @@ -558,7 +578,8 @@ std::string GetNetworkHtmlInfo(int refresh) { } } - output.append("</table></body></html>"); + output.append("</table>"); + AppendFooter(&output); return output; } @@ -586,10 +607,9 @@ std::string GetCryptohomeHtmlInfo(int refresh) { 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>"); @@ -610,9 +630,8 @@ std::string GetCryptohomeHtmlInfo(int refresh) { 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; } @@ -622,8 +641,7 @@ std::string AboutCryptohome(const std::string& query) { return GetCryptohomeHtmlInfo(refresh); } -} // namespace -#endif +#endif // OS_CHROMEOS // AboutDnsHandler bounces the request back to the IO thread to collect // the DNS information. @@ -654,7 +672,10 @@ class AboutDnsHandler : public base::RefCountedThreadSafe<AboutDnsHandler> { 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, @@ -682,7 +703,8 @@ std::string AboutTcmalloc() { 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"); @@ -697,7 +719,7 @@ std::string AboutTcmalloc() { data.append("</pre></td></tr>\n"); } data.append("</table>\n"); - data.append("</body></html>\n"); + AppendFooter(&data); // Reset our collector singleton. outputs->clear(); @@ -726,23 +748,48 @@ std::string AboutHistograms(const std::string& query) { DCHECK(current_synchronizer != NULL); current_synchronizer->FetchRendererHistogramsSynchronously(wait_time); + std::string unescaped_query; + std::string unescaped_title("About Histograms"); + if (!query.empty()) { + 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 @@ -852,8 +899,10 @@ std::string AboutStats(const std::string& query) { } 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>"; @@ -886,22 +935,21 @@ std::string AboutStats(const std::string& query) { } 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)); - - // 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. + // Get about_stats.html/js from resource bundle. + data = ResourceBundle::GetSharedInstance().GetRawDataResource( + (query == kStatsJsPath ? IDR_ABOUT_STATS_JS : IDR_ABOUT_STATS_HTML)). + as_string(); + + 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. + } } } @@ -911,18 +959,16 @@ std::string AboutStats(const std::string& query) { #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; } @@ -945,11 +991,8 @@ void AboutSandboxRow(std::string* data, const std::string& prefix, int name_id, 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>"); @@ -981,12 +1024,20 @@ std::string AboutSandbox() { } data.append("</p>"); - data.append("</body></html>\n"); + AppendFooter(&data); return data; } #endif -std::string AboutVersion(DictionaryValue* localized_strings, Profile* profile) { +std::string AboutVersionStaticContent(const std::string& query) { + return ResourceBundle::GetSharedInstance().GetRawDataResource( + query == kVersionJsPath ? + IDR_ABOUT_VERSION_JS : + IDR_ABOUT_VERSION_HTML).as_string(); +} + +std::string AboutVersionStrings(DictionaryValue* localized_strings, + Profile* profile) { localized_strings->SetString("title", l10n_util::GetStringUTF16(IDS_ABOUT_VERSION_TITLE)); chrome::VersionInfo version_info; @@ -1086,96 +1137,9 @@ std::string AboutVersion(DictionaryValue* localized_strings, Profile* profile) { 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 */); -} - -// AboutSource ----------------------------------------------------------------- - -AboutSource::AboutSource(const std::string& source_name, Profile* profile) - : DataSource(source_name, MessageLoop::current()), - profile_(profile) { -} - -AboutSource::~AboutSource() { -} - -void AboutSource::StartDataRequest(const std::string& path, - bool is_incognito, - int request_id) { - std::string response; - std::string host = source_name(); - if (host == chrome::kChromeUIDNSHost) { - AboutDnsHandler::Start(this, request_id); - return; - } else if (host == chrome::kChromeUIHistogramsHost) { - response = AboutHistograms(path); - } else if (host == chrome::kChromeUIMemoryHost) { - response = GetAboutMemoryRedirectResponse(profile()); - } else if (host == chrome::kChromeUIMemoryRedirectHost) { - AboutMemory(this, request_id); - return; -#ifdef TRACK_ALL_TASK_OBJECTS - } else if (host == chrome::kChromeUITasksHost) { - response = AboutObjects(path); -#endif - } else if (host == chrome::kChromeUIStatsHost) { - response = AboutStats(path); -#if defined(USE_TCMALLOC) - } else if (host == chrome::kChromeUITCMallocHost) { - response = AboutTcmalloc(); -#endif - } else if (host == chrome::kChromeUIVersionHost) { -#if defined(OS_CHROMEOS) - new ChromeOSAboutVersionHandler(this, request_id); - return; -#else - DictionaryValue localized_strings; - localized_strings.SetString("os_version", ""); - response = AboutVersion(&localized_strings, profile_); -#endif - } else if (host == chrome::kChromeUICreditsHost) { - response = ResourceBundle::GetSharedInstance().GetRawDataResource( - IDR_CREDITS_HTML).as_string(); - } else if (host == chrome::kChromeUIChromeURLsHost) { - response = ChromeURLs(); -#if defined(OS_CHROMEOS) - } else if (host == chrome::kChromeUIOSCreditsHost) { - response = ResourceBundle::GetSharedInstance().GetRawDataResource( - IDR_OS_CREDITS_HTML).as_string(); - } else if (host == chrome::kChromeUINetworkHost) { - response = AboutNetwork(path); - } else if (host == chrome::kChromeUICryptohomeHost) { - response = AboutCryptohome(path); -#endif - } else if (host == chrome::kChromeUITermsHost) { -#if defined(OS_CHROMEOS) - ChromeOSTermsHandler::Start(this, request_id); - return; -#else - response = ResourceBundle::GetSharedInstance().GetRawDataResource( - IDR_TERMS_HTML).as_string(); -#endif -#if defined(OS_LINUX) - } else if (host == chrome::kChromeUILinuxProxyConfigHost) { - response = AboutLinuxProxyConfig(); - } else if (host == chrome::kChromeUISandboxHost) { - response = AboutSandbox(); -#endif - } - - FinishDataRequest(response, request_id); -} - -void AboutSource::FinishDataRequest(const std::string& html, int request_id) { - scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes); - html_bytes->data.resize(html.size()); - std::copy(html.begin(), html.end(), html_bytes->data.begin()); - SendResponse(request_id, html_bytes); + std::string data; + jstemplate_builder::AppendJsonJS(localized_strings, &data); + return data; } // AboutMemoryHandler ---------------------------------------------------------- @@ -1299,23 +1263,17 @@ void AboutMemoryHandler::OnDetailsAvailable() { 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) // ChromeOSAboutVersionHandler ----------------------------------------------- -ChromeOSAboutVersionHandler::ChromeOSAboutVersionHandler(AboutSource* source, - int request_id) +ChromeOSAboutVersionHandler::ChromeOSAboutVersionHandler( + AboutSource* source, + int request_id) : source_(source), request_id_(request_id) { loader_.EnablePlatformVersions(true); @@ -1329,8 +1287,8 @@ void ChromeOSAboutVersionHandler::OnVersion( std::string version) { DictionaryValue localized_strings; localized_strings.SetString("os_version", version); - source_->FinishDataRequest(AboutVersion(&localized_strings, - source_->profile()), request_id_); + source_->FinishDataRequest(AboutVersionStrings( + &localized_strings, source_->profile()), request_id_); // CancelableRequestProvider isn't happy when it's deleted and servicing a // task, so we delay the deletion. @@ -1341,6 +1299,106 @@ void ChromeOSAboutVersionHandler::OnVersion( } // namespace +// AboutSource ----------------------------------------------------------------- + +AboutSource::AboutSource(const std::string& source_name, Profile* profile) + : DataSource(source_name, MessageLoop::current()), + profile_(profile) { +} + +AboutSource::~AboutSource() { +} + +void AboutSource::StartDataRequest(const std::string& path, + bool is_incognito, + int request_id) { + std::string response; + std::string host = source_name(); + if (host == chrome::kChromeUIDNSHost) { + AboutDnsHandler::Start(this, request_id); + return; + } else if (host == chrome::kChromeUIHistogramsHost) { + response = AboutHistograms(path); + } else if (host == chrome::kChromeUIMemoryHost) { + response = GetAboutMemoryRedirectResponse(profile()); + } else if (host == chrome::kChromeUIMemoryRedirectHost) { + AboutMemory(path, this, request_id); + return; +#ifdef TRACK_ALL_TASK_OBJECTS + } else if (host == chrome::kChromeUITasksHost) { + response = AboutObjects(path); +#endif + } else if (host == chrome::kChromeUIStatsHost) { + response = AboutStats(path); +#if defined(USE_TCMALLOC) + } else if (host == chrome::kChromeUITCMallocHost) { + response = AboutTcmalloc(); +#endif + } else if (host == chrome::kChromeUIVersionHost) { + if (path == kStringsJsPath) { +#if defined(OS_CHROMEOS) + new ChromeOSAboutVersionHandler(this, request_id); + return; +#else + DictionaryValue localized_strings; + localized_strings.SetString("os_version", ""); + response = AboutVersionStrings(&localized_strings, profile_); +#endif + } else { + response = AboutVersionStaticContent(path); + } + } else if (host == chrome::kChromeUICreditsHost) { + int idr = (path == kCreditsJsPath) ? IDR_CREDITS_JS : IDR_CREDITS_HTML; + response = ResourceBundle::GetSharedInstance().GetRawDataResource( + idr).as_string(); + } else if (host == chrome::kChromeUIChromeURLsHost) { + response = ChromeURLs(); +#if defined(OS_CHROMEOS) + } else if (host == chrome::kChromeUIOSCreditsHost) { + response = ResourceBundle::GetSharedInstance().GetRawDataResource( + IDR_OS_CREDITS_HTML).as_string(); + } else if (host == chrome::kChromeUINetworkHost) { + response = AboutNetwork(path); + } else if (host == chrome::kChromeUICryptohomeHost) { + response = AboutCryptohome(path); +#endif + } else if (host == chrome::kChromeUITermsHost) { +#if defined(OS_CHROMEOS) + ChromeOSTermsHandler::Start(this, request_id); + return; +#else + response = ResourceBundle::GetSharedInstance().GetRawDataResource( + IDR_TERMS_HTML).as_string(); +#endif +#if defined(OS_LINUX) + } else if (host == chrome::kChromeUILinuxProxyConfigHost) { + response = AboutLinuxProxyConfig(); + } else if (host == chrome::kChromeUISandboxHost) { + response = AboutSandbox(); +#endif + } + + FinishDataRequest(response, request_id); +} + +void AboutSource::FinishDataRequest(const std::string& html, int request_id) { + scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes); + html_bytes->data.resize(html.size()); + std::copy(html.begin(), html.end(), html_bytes->data.begin()); + SendResponse(request_id, html_bytes); +} + +std::string AboutSource::GetMimeType(const std::string& path) const { + if (path == kCreditsJsPath || + path == kStatsJsPath || + path == kStringsJsPath || + path == kVersionJsPath || + path == kMemoryJsPath) { + return "application/javascript"; + } + return "text/html"; +} + // ----------------------------------------------------------------------------- bool WillHandleBrowserAboutURL(GURL* url, Profile* profile) { diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 33f4555..5d98247 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd @@ -23,11 +23,15 @@ <if expr="is_win"> <include name="IDR_ABOUT_MEMORY_HTML" file="resources\about_memory.html" flattenhtml="true" type="BINDATA" /> </if> - <include name="IDR_ABOUT_STATS_HTML" file="resources\about_stats.html" flattenhtml="true" type="BINDATA" /> - <include name="IDR_ABOUT_VERSION_HTML" file="resources\about_version.html" flattenhtml="true" type="BINDATA" /> + <include name="IDR_ABOUT_MEMORY_JS" file="resources\about_memory.js" type="BINDATA" /> + <include name="IDR_ABOUT_STATS_HTML" file="resources\about_stats.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> + <include name="IDR_ABOUT_STATS_JS" file="resources\about_stats.js" type="BINDATA" /> + <include name="IDR_ABOUT_VERSION_HTML" file="resources\about_version.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> + <include name="IDR_ABOUT_VERSION_JS" file="resources\about_version.js" type="BINDATA" /> <include name="IDR_BOOKMARKS_MANIFEST" file="resources\bookmark_manager\manifest.json" type="BINDATA" /> <include name="IDR_CRASHES_HTML" file="resources\crashes.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_CREDITS_HTML" file="resources\about_credits.html" flattenhtml="true" type="BINDATA" /> + <include name="IDR_CREDITS_JS" file="resources\about_credits.js" type="BINDATA" /> <include name="IDR_DOWNLOADS_JS" file="resources\downloads.js" type="BINDATA" /> <include name="IDR_DOWNLOADS_HTML" file="resources\downloads.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> <include name="IDR_TASK_MANAGER_HTML" file="resources\task_manager\main.html" flattenhtml="true" type="BINDATA" /> diff --git a/chrome/browser/net/predictor_api.cc b/chrome/browser/net/predictor_api.cc index e60bd1c..682a0ef 100644 --- a/chrome/browser/net/predictor_api.cc +++ b/chrome/browser/net/predictor_api.cc @@ -360,10 +360,6 @@ static base::LazyInstance<OffTheRecordObserver> g_off_the_record_observer( void PredictorGetHtmlInfo(std::string* output) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - output->append("<html><head><title>About DNS</title>" - // We'd like the following no-cache... but it doesn't work. - // "<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">" - "</head><body>"); if (!predictor_enabled || NULL == g_predictor) { output->append("DNS pre-resolution and TCP pre-connection is disabled."); } else { @@ -379,7 +375,6 @@ void PredictorGetHtmlInfo(std::string* output) { g_predictor->GetHtmlInfo(output); } } - output->append("</body></html>"); } void ClearPredictorCache() { diff --git a/chrome/browser/resources/about_credits.js b/chrome/browser/resources/about_credits.js new file mode 100644 index 0000000..c3b7d44 --- /dev/null +++ b/chrome/browser/resources/about_credits.js @@ -0,0 +1,38 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +function $(o) {return document.getElementById(o);} + +function toggle(o) { + var licence = o.nextSibling; + + while (licence.className != 'licence') { + if (!licence) return false; + licence = licence.nextSibling; + } + + if (licence.style && licence.style.display == 'block') { + licence.style.display = 'none'; + o.innerHTML = 'show license'; + } else { + licence.style.display = 'block'; + o.innerHTML = 'hide license'; + } + return false; +} + +document.body.onload = function () { + var links = document.getElementsByTagName("a"); + for (var i = 0; i < links.length; i++) { + if (links[i].className === "show") { + links[i].onclick = function () { return toggle(this); }; + } + } + + $("print-link").onclick = function () { + window.print(); + return false; + } +}; + diff --git a/chrome/browser/resources/about_credits.tmpl b/chrome/browser/resources/about_credits.tmpl index f9cb1970..f531455 100644 --- a/chrome/browser/resources/about_credits.tmpl +++ b/chrome/browser/resources/about_credits.tmpl @@ -2,6 +2,7 @@ <html> <head> <meta charset="utf-8"> +<meta http-equiv="X-WebKit-CSP" content="object-src 'none'; script-src 'self'"> <title>Credits</title> <style> body { @@ -51,33 +52,13 @@ body { margin-top:0px; } </style> -<script> -function $(o) {return document.getElementById(o);} -function toggle(o) { - var licence = o.nextSibling; - - while (licence.className != 'licence') { - if (!licence) return false; - licence = licence.nextSibling; - } - - if (licence.style && licence.style.display == 'block') { - licence.style.display = 'none'; - o.innerHTML = 'show license'; - } else { - licence.style.display = 'block'; - o.innerHTML = 'hide license'; - } - return false; -} -</script> </head> <body> <span class="page-title" style="float:left;">Credits</span> -<a href="javascript:window.print();" style="float:right;">Print</a> +<a id="print-link" href="#" style="float:right;">Print</a> <div style="clear:both; overflow:auto;"><!-- Chromium <3s the following projects --> {{entries}} </div> - +<script src="chrome://credits/credits.js"></script> </body> </html> diff --git a/chrome/browser/resources/about_credits_entry.tmpl b/chrome/browser/resources/about_credits_entry.tmpl index ff0ea45b..d1810cd 100644 --- a/chrome/browser/resources/about_credits_entry.tmpl +++ b/chrome/browser/resources/about_credits_entry.tmpl @@ -1,6 +1,6 @@ <div class="product"> <span class="title">{{name}}</span> -<a class="show" href="#" onclick="return toggle(this);">show license</a> +<a class="show" href="#">show license</a> <span class="homepage"><a href="{{url}}">homepage</a></span> <div class="licence"> <pre>{{license}}</pre> diff --git a/chrome/browser/resources/about_memory.html b/chrome/browser/resources/about_memory.html index 3432d0d..918115f 100644 --- a/chrome/browser/resources/about_memory.html +++ b/chrome/browser/resources/about_memory.html @@ -4,10 +4,10 @@ about:memory template page --> <html id="t"> - <head> - <title>About Memory</title> +<head> + <title>About Memory</title> + <meta http-equiv="X-WebKit-CSP" content="object-src 'none'; script-src chrome://resources 'self' 'unsafe-eval'"> <link rel="stylesheet" href="shared/css/about_memory.css"> - <style> body { font-family: Helvetica, Arial, sans-serif; @@ -34,79 +34,8 @@ table.list#memoryDetails tr.firstRow th:nth-child(3) { border-right: 1px solid #b5c6de; } </style> -<script> -function reload() { - if (document.getElementById('helpTooltip')) - return; - history.go(0); -} - -function formatNumber(str) { - str += ''; - if (str == '0') { - return 'N/A '; - } - var x = str.split('.'); - var x1 = x[0]; - var x2 = x.length > 1 ? '.' + x[1] : ''; - var regex = /(\d+)(\d{3})/; - while (regex.test(x1)) { - x1 = x1.replace(regex, '$1' + ',' + '$2'); - } - return x1; -} - -function addToSum(id, value) { - var target = document.getElementById(id); - var sum = parseInt(target.innerHTML); - sum += parseInt(value); - target.innerHTML = sum; -} - -function handleHelpTooltipMouseOver(event) { - var el = document.createElement('div'); - el.id = 'helpTooltip'; - el.innerHTML = event.toElement.getElementsByTagName('div')[0].innerHTML; - el.style.top = 0; - el.style.left = 0; - el.style.visibility = 'hidden'; - document.body.appendChild(el); - - var width = el.offsetWidth; - var height = el.offsetHeight; - - if (event.pageX - width - 50 + document.body.scrollLeft >= 0 ) { - el.style.left = (event.pageX - width - 20) + 'px'; - } else { - el.style.left = (event.pageX + 20) + 'px'; - } - - - if (event.pageY - height - 50 + document.body.scrollTop >= 0) { - el.style.top = (event.pageY - height - 20) + 'px'; - } else { - el.style.top = (event.pageY + 20) + 'px'; - } - - el.style.visibility = 'visible'; -} - -function handleHelpTooltipMouseOut(event) { - var el = document.getElementById('helpTooltip'); - el.parentNode.removeChild(el); -} - -function enableHelpTooltips() { - var helpEls = document.getElementsByClassName('help'); - - for (var i = 0, helpEl; helpEl = helpEls[i]; i++) { - helpEl.onmouseover = handleHelpTooltipMouseOver; - helpEl.onmouseout = handleHelpTooltipMouseOut; - } -} - -//setInterval("reload()", 10000); -</script> +<script src="chrome://memory-redirect/memory.js"></script> +<script src="chrome://memory-redirect/strings.js"></script> </head> <body> <div id='header'> @@ -424,8 +353,6 @@ function enableHelpTooltips() { </tr> </table> </div> + <script src="chrome://resources/js/jstemplate_compiled.js"></script> </body> -<script> - enableHelpTooltips(); -</script> </html> diff --git a/chrome/browser/resources/about_memory.js b/chrome/browser/resources/about_memory.js new file mode 100644 index 0000000..f12ba47 --- /dev/null +++ b/chrome/browser/resources/about_memory.js @@ -0,0 +1,83 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +function reload() { + if (document.getElementById('helpTooltip')) + return; + history.go(0); +} + +function formatNumber(str) { + str += ''; + if (str == '0') { + return 'N/A '; + } + var x = str.split('.'); + var x1 = x[0]; + var x2 = x.length > 1 ? '.' + x[1] : ''; + var regex = /(\d+)(\d{3})/; + while (regex.test(x1)) { + x1 = x1.replace(regex, '$1' + ',' + '$2'); + } + return x1; +} + +function addToSum(id, value) { + var target = document.getElementById(id); + var sum = parseInt(target.innerHTML); + sum += parseInt(value); + target.innerHTML = sum; +} + +function handleHelpTooltipMouseOver(event) { + var el = document.createElement('div'); + el.id = 'helpTooltip'; + el.innerHTML = event.toElement.getElementsByTagName('div')[0].innerHTML; + el.style.top = 0; + el.style.left = 0; + el.style.visibility = 'hidden'; + document.body.appendChild(el); + + var width = el.offsetWidth; + var height = el.offsetHeight; + + if (event.pageX - width - 50 + document.body.scrollLeft >= 0 ) { + el.style.left = (event.pageX - width - 20) + 'px'; + } else { + el.style.left = (event.pageX + 20) + 'px'; + } + + + if (event.pageY - height - 50 + document.body.scrollTop >= 0) { + el.style.top = (event.pageY - height - 20) + 'px'; + } else { + el.style.top = (event.pageY + 20) + 'px'; + } + + el.style.visibility = 'visible'; +} + +function handleHelpTooltipMouseOut(event) { + var el = document.getElementById('helpTooltip'); + el.parentNode.removeChild(el); +} + +function enableHelpTooltips() { + var helpEls = document.getElementsByClassName('help'); + + for (var i = 0, helpEl; helpEl = helpEls[i]; i++) { + helpEl.onmouseover = handleHelpTooltipMouseOver; + helpEl.onmouseout = handleHelpTooltipMouseOut; + } +} + +document.addEventListener('DOMContentLoaded', function () { + // This is the javascript code that processes the template: + var input = new JsEvalContext(templateData); + var output = document.getElementById('t'); + jstProcess(input, output); + + enableHelpTooltips(); +}); + diff --git a/chrome/browser/resources/about_memory_linux.html b/chrome/browser/resources/about_memory_linux.html index a3cdfe7..bc646a4 100644 --- a/chrome/browser/resources/about_memory_linux.html +++ b/chrome/browser/resources/about_memory_linux.html @@ -4,9 +4,10 @@ about:memory template page --> <html id="t"> - <head> - <title>About Memory</title> - <link rel="stylesheet" href="shared/css/about_memory.css"> +<head> + <title>About Memory</title> + <meta http-equiv="X-WebKit-CSP" content="object-src 'none'; script-src chrome://resources 'self' 'unsafe-eval'"> + <link rel="stylesheet" href="shared/css/about_memory.css"> <style> body { @@ -32,79 +33,8 @@ table.list#memoryDetails tr.firstRow th:nth-child(2) { border-right: 1px solid #b5c6de; } </style> -<script> -function reload() { - if (document.getElementById('helpTooltip')) - return; - history.go(0); -} - -function formatNumber(str) { - str += ''; - if (str == '0') { - return 'N/A '; - } - var x = str.split('.'); - var x1 = x[0]; - var x2 = x.length > 1 ? '.' + x[1] : ''; - var regex = /(\d+)(\d{3})/; - while (regex.test(x1)) { - x1 = x1.replace(regex, '$1' + ',' + '$2'); - } - return x1; -} - -function addToSum(id, value) { - var target = document.getElementById(id); - var sum = parseInt(target.innerHTML); - sum += parseInt(value); - target.innerHTML = sum; -} - -function handleHelpTooltipMouseOver(event) { - var el = document.createElement('div'); - el.id = 'helpTooltip'; - el.innerHTML = event.toElement.getElementsByTagName('div')[0].innerHTML; - el.style.top = 0; - el.style.left = 0; - el.style.visibility = 'hidden'; - document.body.appendChild(el); - - var width = el.offsetWidth; - var height = el.offsetHeight; - - if (event.pageX - width - 50 + document.body.scrollLeft >= 0 ) { - el.style.left = (event.pageX - width - 20) + 'px'; - } else { - el.style.left = (event.pageX + 20) + 'px'; - } - - - if (event.pageY - height - 50 + document.body.scrollTop >= 0) { - el.style.top = (event.pageY - height - 20) + 'px'; - } else { - el.style.top = (event.pageY + 20) + 'px'; - } - - el.style.visibility = 'visible'; -} - -function handleHelpTooltipMouseOut(event) { - var el = document.getElementById('helpTooltip'); - el.parentNode.removeChild(el); -} - -function enableHelpTooltips() { - var helpEls = document.getElementsByClassName('help'); - - for (var i = 0, helpEl; helpEl = helpEls[i]; i++) { - helpEl.onmouseover = handleHelpTooltipMouseOver; - helpEl.onmouseout = handleHelpTooltipMouseOut; - } -} - -//setInterval("reload()", 10000); -</script> +<script src="chrome://memory-redirect/memory.js"></script> +<script src="chrome://memory-redirect/strings.js"></script> </head> <body> <div id='header'> @@ -296,8 +226,6 @@ function enableHelpTooltips() { <div class="otherbrowsers">(The memory usage of our renderer processes is slightly less accurate when they are sandboxed.)</div> </div> + <script src="chrome://resources/js/jstemplate_compiled.js"></script> </body> -<script> - enableHelpTooltips(); -</script> </html> diff --git a/chrome/browser/resources/about_memory_mac.html b/chrome/browser/resources/about_memory_mac.html index 4edc6d3..03324eb 100644 --- a/chrome/browser/resources/about_memory_mac.html +++ b/chrome/browser/resources/about_memory_mac.html @@ -4,10 +4,10 @@ about:memory template page --> <html id="t"> - <head> - <title>About Memory</title> +<head> + <title>About Memory</title> + <meta http-equiv="X-WebKit-CSP" content="object-src 'none'; script-src chrome://resources 'self' 'unsafe-eval'"> <link rel="stylesheet" href="shared/css/about_memory.css"> - <style> body { font-family: Helvetica, sans-serif; @@ -32,79 +32,8 @@ table.list#memoryDetails tr.firstRow th:nth-child(2) { border-right: 1px solid #b5c6de; } </style> -<script> -function reload() { - if (document.getElementById('helpTooltip')) - return; - history.go(0); -} - -function formatNumber(str) { - str += ''; - if (str == '0') { - return 'N/A '; - } - var x = str.split('.'); - var x1 = x[0]; - var x2 = x.length > 1 ? '.' + x[1] : ''; - var regex = /(\d+)(\d{3})/; - while (regex.test(x1)) { - x1 = x1.replace(regex, '$1' + ',' + '$2'); - } - return x1; -} - -function addToSum(id, value) { - var target = document.getElementById(id); - var sum = parseInt(target.innerHTML); - sum += parseInt(value); - target.innerHTML = sum; -} - -function handleHelpTooltipMouseOver(event) { - var el = document.createElement('div'); - el.id = 'helpTooltip'; - el.innerHTML = event.toElement.getElementsByTagName('div')[0].innerHTML; - el.style.top = 0; - el.style.left = 0; - el.style.visibility = 'hidden'; - document.body.appendChild(el); - - var width = el.offsetWidth; - var height = el.offsetHeight; - - if (event.pageX - width - 50 + document.body.scrollLeft >= 0 ) { - el.style.left = (event.pageX - width - 20) + 'px'; - } else { - el.style.left = (event.pageX + 20) + 'px'; - } - - - if (event.pageY - height - 50 + document.body.scrollTop >= 0) { - el.style.top = (event.pageY - height - 20) + 'px'; - } else { - el.style.top = (event.pageY + 20) + 'px'; - } - - el.style.visibility = 'visible'; -} - -function handleHelpTooltipMouseOut(event) { - var el = document.getElementById('helpTooltip'); - el.parentNode.removeChild(el); -} - -function enableHelpTooltips() { - var helpEls = document.getElementsByClassName('help'); - - for (var i = 0, helpEl; helpEl = helpEls[i]; i++) { - helpEl.onmouseover = handleHelpTooltipMouseOver; - helpEl.onmouseout = handleHelpTooltipMouseOut; - } -} - -//setInterval("reload()", 10000); -</script> +<script src="chrome://memory-redirect/memory.js"></script> +<script src="chrome://memory-redirect/strings.js"></script> </head> <body> <div id='header'> @@ -327,8 +256,6 @@ function enableHelpTooltips() { (Note: Due to memory sharing between processes, summing memory usage does not give total memory usage.) </div> </div> + <script src="chrome://resources/js/jstemplate_compiled.js"></script> </body> -<script> - enableHelpTooltips(); -</script> </html> diff --git a/chrome/browser/resources/about_stats.html b/chrome/browser/resources/about_stats.html index 2355709..3f92544 100644 --- a/chrome/browser/resources/about_stats.html +++ b/chrome/browser/resources/about_stats.html @@ -1,9 +1,13 @@ <!DOCTYPE HTML> <html id="t"> - <head> - <title>About Stats</title> - +<head> +<title>About Stats</title> +<!-- X-WebKit-CSP is our development name for Content-Security-Policy. + The 'unsafe-eval' is required for jstemplate_compiled.js. + TODO(tsepez) rename when Content-security-policy is done. +--> +<meta http-equiv="X-WebKit-CSP" content="object-src 'none'; script-src chrome://resources 'self' 'unsafe-eval'"> <style> body { border-top: 10px solid #3B85E3; @@ -70,194 +74,11 @@ h2 { text-transform: lowercase; } </style> -<script> - -/* Counter accessor for Name Node. */ -function getCounterNameFromCounterNode(node) { - return node.childNodes[1]; -} - -/* Counter accessor for Value Node. */ -function getCounterValueFromCounterNode(node) { - return node.childNodes[3]; -} - -/* Counter accessor for Delta Node. */ -function getCounterDeltaFromCounterNode(node) { - return node.childNodes[5]; -} - -/* Timer accessor for Name Node. */ -function getTimerNameFromTimerNode(node) { - return node.childNodes[1]; -} - -/* Timer accessor for Value Node. */ -function getTimerValueFromTimerNode(node) { - return node.childNodes[3]; -} - -/* Timer accessor for Time Node. */ -function getTimerTimeFromTimerNode(node) { - return node.childNodes[5]; -} - -/* Timer accessor for Average Time Node. */ -function getTimerAvgTimeFromTimerNode(node) { - return node.childNodes[7]; -} - -/* Do the filter work. Hide all nodes matching node.*/ -function filterMatching(text, nodelist, functionToGetNameNode) { - var showAll = text.length == 0; - for (var i = 0, node; node = nodelist[i]; i++) { - var name = functionToGetNameNode(node).innerHTML.toLowerCase(); - if (showAll || name.indexOf(text) >= 0) { - node.style.display = "table-row"; - } else { - node.style.display = "none"; - } - } -} - -/* Hides or shows counters based on the user's current filter selection. */ -function doFilter() { - var filter = document.getElementById("filter"); - var text = filter.value.toLowerCase(); - var nodes = document.getElementsByName("counter"); - filterMatching(text, nodes, getCounterNameFromCounterNode); - var nodes = document.getElementsByName("timer"); - filterMatching(text, nodes, getTimerNameFromTimerNode); -} - -/* Colors the counters based on increasing or decreasing value. */ -function doColor() { - var nodes = document.getElementsByName("counter"); - for (var i = 0, node; node = nodes[i]; i++) { - var child = getCounterDeltaFromCounterNode(node); - var delta = child.innerHTML; - if (delta > 0) { - child.style.color = "Green"; - } else if (delta == 0) { - child.style.color = "Black"; - } else { - child.style.color = "Red"; - } - } -} - -/* Counters with no values are null. Remove them. */ -function removeNullValues() { - var nodes = document.getElementsByName("counter"); - for (var i = nodes.length - 1; i >= 0; i--) { - var node = nodes[i]; - var value = getCounterValueFromCounterNode(node).innerHTML; - if (value == "null") { - node.parentNode.removeChild(node); - } - } - var nodes = document.getElementsByName("timer"); - for (var i = 0, node; node = nodes[i]; i++) { - var value_node = getTimerValueFromTimerNode(node); - if (value_node.innerHTML == "null") { - value_node.innerHTML = ""; - } - } -} - -/* Compute the average time for timers */ -function computeTimes() { - var nodes = document.getElementsByName("timer"); - for (var i = 0, node; node = nodes[i]; i++) { - var count = getTimerValueFromTimerNode(node).innerHTML; - if (count.length > 0) { - var time = getTimerTimeFromTimerNode(node).innerHTML; - var avg = getTimerAvgTimeFromTimerNode(node); - avg.innerHTML = Math.round(time / count * 100) / 100; - } - } -} - -/* All the work we do onload. */ -function onLoadWork() { - doColor(); - removeNullValues(); - computeTimes(); - document.getElementById("filter").focus(); -} - -// The function should only be used as the event handler -// on a table cell element. To use it, put it in a <td> element: -// <td onclick="sort('string')" ...> -// -// The function sorts rows after the row with onclick event handler. -// -// type: the data type, 'string', 'number' -function sort_table(type){ - var cell = event.target; - var cnum = cell.cellIndex; - - var row = cell.parentNode; - var start_index = row.rowIndex + 1; - - var tbody = row.parentNode; - var table = tbody.parentNode; - - var rows = new Array(); - - var indexes = new Array(); - // skip the first row - for (var i = start_index; i < table.rows.length; i++) - rows.push(table.rows[i]); - - // a, b are strings - function compare_strings(a,b) { - if (a == b) return 0; - if (a < b) return -1; - return 1; - } - - // a, b are numbers - function compare_numbers(a,b) { - var x = isNaN(a) ? 0 : a; - var y = isNaN(b) ? 0 : b; - return x - y; - } - - var sort_func = undefined; - if (type === 'string') { - sort_func = function(a, b) { - var x = a.cells[cnum].innerText; - var y = b.cells[cnum].innerText; - return compare_strings(x, y); - } ; - - } else if (type === 'number') { - sort_func = function(a, b) { - var x = parseFloat(a.cells[cnum].innerText); - var y = parseFloat(b.cells[cnum].innerText); - return compare_numbers(x, y); - } - } - - rows.sort(sort_func); - - // change tables - if (cell._reverse) { - for (var i = rows.length - 1; i >= 0; i--) - tbody.appendChild(rows[i]); - cell._reverse = false; - } else { - for (var i = 0; i < rows.length; i++) - tbody.appendChild(rows[i]); - cell._reverse = true; - } -} - -</script> +<script src="chrome://stats/stats.js"></script> +<script src="chrome://stats/json.js"></script> </head> -<body onload="onLoadWork()"> - <div style="float: right"> +<body> + <div style="float: right"> <br>Filter: <input id="filter" type="text" value="" onkeyup="doFilter()"> </div> <h1 class="lower">About Stats</h1> @@ -273,9 +94,9 @@ function sort_table(type){ <td class="top value" colspan=2></td> </tr> <tr> - <td class="header2 lower" width="200" onclick="sort_table('string')">name</td> - <td class="header2 lower" onclick="sort_table('number')">value</td> - <td class="header2 lower" onclick="sort_table('number')">delta</td> + <td class="header2 lower" name="string-sort" width="200">name</td> + <td class="header2 lower" name="number-sort">value</td> + <td class="header2 lower" name="number-sort">delta</td> </tr> <tr jsselect="counters" name="counter"> <td class="key" width="200" jscontent="name"></td> @@ -295,10 +116,10 @@ function sort_table(type){ <td class="top value" colspan=3></td> </tr> <tr> - <td class="header2 lower" width="200" onclick="sort_table('string')">name</td> - <td class="header2 lower" onclick="sort_table('number')">count</td> - <td class="header2 lower" onclick="sort_table('number')">time (ms)</td> - <td class="header2 lower" onclick="sort_table('number')">avg time (ms)</td> + <td class="header2 lower" name="string-sort" width="200">name</td> + <td class="header2 lower" name="number-sort">count</td> + <td class="header2 lower" name="number-sort">time (ms)</td> + <td class="header2 lower" name="number-sort">avg time (ms)</td> </tr> <tr jsselect="timers" name="timer"> <td class="key" width="200" jscontent="name"></td> @@ -312,5 +133,7 @@ function sort_table(type){ </tr> </tbody> </table><br/> + <script src="chrome://resources/js/jstemplate_compiled.js"></script> </body> </html> + diff --git a/chrome/browser/resources/about_stats.js b/chrome/browser/resources/about_stats.js new file mode 100644 index 0000000..30b8b96 --- /dev/null +++ b/chrome/browser/resources/about_stats.js @@ -0,0 +1,202 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/* Counter accessor for Name Node. */ +function getCounterNameFromCounterNode(node) { + return node.childNodes[1]; +} + +/* Counter accessor for Value Node. */ +function getCounterValueFromCounterNode(node) { + return node.childNodes[3]; +} + +/* Counter accessor for Delta Node. */ +function getCounterDeltaFromCounterNode(node) { + return node.childNodes[5]; +} + +/* Timer accessor for Name Node. */ +function getTimerNameFromTimerNode(node) { + return node.childNodes[1]; +} + +/* Timer accessor for Value Node. */ +function getTimerValueFromTimerNode(node) { + return node.childNodes[3]; +} + +/* Timer accessor for Time Node. */ +function getTimerTimeFromTimerNode(node) { + return node.childNodes[5]; +} + +/* Timer accessor for Average Time Node. */ +function getTimerAvgTimeFromTimerNode(node) { + return node.childNodes[7]; +} + +/* Do the filter work. Hide all nodes matching node.*/ +function filterMatching(text, nodelist, functionToGetNameNode) { + var showAll = text.length == 0; + for (var i = 0, node; node = nodelist[i]; i++) { + var name = functionToGetNameNode(node).innerHTML.toLowerCase(); + if (showAll || name.indexOf(text) >= 0) { + node.style.display = "table-row"; + } else { + node.style.display = "none"; + } + } +} + +/* Hides or shows counters based on the user's current filter selection. */ +function doFilter() { + var filter = document.getElementById("filter"); + var text = filter.value.toLowerCase(); + var nodes = document.getElementsByName("counter"); + filterMatching(text, nodes, getCounterNameFromCounterNode); + var nodes = document.getElementsByName("timer"); + filterMatching(text, nodes, getTimerNameFromTimerNode); +} + +/* Colors the counters based on increasing or decreasing value. */ +function doColor() { + var nodes = document.getElementsByName("counter"); + for (var i = 0, node; node = nodes[i]; i++) { + var child = getCounterDeltaFromCounterNode(node); + var delta = child.innerHTML; + if (delta > 0) { + child.style.color = "Green"; + } else if (delta == 0) { + child.style.color = "Black"; + } else { + child.style.color = "Red"; + } + } +} + +/* Counters with no values are null. Remove them. */ +function removeNullValues() { + var nodes = document.getElementsByName("counter"); + for (var i = nodes.length - 1; i >= 0; i--) { + var node = nodes[i]; + var value = getCounterValueFromCounterNode(node).innerHTML; + if (value == "null") { + node.parentNode.removeChild(node); + } + } + var nodes = document.getElementsByName("timer"); + for (var i = 0, node; node = nodes[i]; i++) { + var value_node = getTimerValueFromTimerNode(node); + if (value_node.innerHTML == "null") { + value_node.innerHTML = ""; + } + } +} + +/* Compute the average time for timers */ +function computeTimes() { + var nodes = document.getElementsByName("timer"); + for (var i = 0, node; node = nodes[i]; i++) { + var count = getTimerValueFromTimerNode(node).innerHTML; + if (count.length > 0) { + var time = getTimerTimeFromTimerNode(node).innerHTML; + var avg = getTimerAvgTimeFromTimerNode(node); + avg.innerHTML = Math.round(time / count * 100) / 100; + } + } +} + +/* All the work we do onload. */ +function onLoadWork() { + // This is the javascript code that processes the template: + var input = new JsEvalContext(templateData); + var output = document.getElementById('t'); + jstProcess(input, output); + + // Add handlers to dynamically created HTML elements. + var elements = document.getElementsByName("string-sort"); + for (var i = 0; i < elements.length; ++i) + elements[i].onclick = function () { sort_table("string"); }; + + elements = document.getElementsByName("number-sort"); + for (i = 0; i < elements.length; ++i) + elements[i].onclick = function () { sort_table("number"); }; + + doColor(); + removeNullValues(); + computeTimes(); + document.getElementById("filter").focus(); +} + +// The function should only be used as the event handler +// on a table cell element. To use it, put it in a <td> element: +// <td onclick="sort('string')" ...> +// +// The function sorts rows after the row with onclick event handler. +// +// type: the data type, 'string', 'number' +function sort_table(type){ + var cell = event.target; + var cnum = cell.cellIndex; + + var row = cell.parentNode; + var start_index = row.rowIndex + 1; + + var tbody = row.parentNode; + var table = tbody.parentNode; + + var rows = new Array(); + + var indexes = new Array(); + // skip the first row + for (var i = start_index; i < table.rows.length; i++) + rows.push(table.rows[i]); + + // a, b are strings + function compare_strings(a,b) { + if (a == b) return 0; + if (a < b) return -1; + return 1; + } + + // a, b are numbers + function compare_numbers(a,b) { + var x = isNaN(a) ? 0 : a; + var y = isNaN(b) ? 0 : b; + return x - y; + } + + var sort_func = undefined; + if (type === 'string') { + sort_func = function(a, b) { + var x = a.cells[cnum].innerText; + var y = b.cells[cnum].innerText; + return compare_strings(x, y); + } ; + + } else if (type === 'number') { + sort_func = function(a, b) { + var x = parseFloat(a.cells[cnum].innerText); + var y = parseFloat(b.cells[cnum].innerText); + return compare_numbers(x, y); + } + } + + rows.sort(sort_func); + + // change tables + if (cell._reverse) { + for (var i = rows.length - 1; i >= 0; i--) + tbody.appendChild(rows[i]); + cell._reverse = false; + } else { + for (var i = 0; i < rows.length; i++) + tbody.appendChild(rows[i]); + cell._reverse = true; + } +} + +document.addEventListener('DOMContentLoaded', onLoadWork); + diff --git a/chrome/browser/resources/about_version.html b/chrome/browser/resources/about_version.html index 0d091a2..a999b80 100644 --- a/chrome/browser/resources/about_version.html +++ b/chrome/browser/resources/about_version.html @@ -7,6 +7,7 @@ about:version template page <html id="t"> <head> <title i18n-content="title"></title> + <meta http-equiv="X-WebKit-CSP" content="object-src 'none'; script-src chrome://resources 'self' 'unsafe-eval'"> <style> body { font-family:Helvetica,Arial,sans-serif; @@ -61,6 +62,8 @@ about:version template page max-width: 430px; } </style> + <script src="chrome://version/version.js"></script> + <script src="chrome://version/strings.js"></script> </head> <body> @@ -100,6 +103,9 @@ about:version template page </tr> </table> </div> + <script src="chrome://resources/js/i18n_template.js"></script> + <script src="chrome://resources/js/i18n_process.js"></script> + <script src="chrome://resources/js/jstemplate_compiled.js"></script> </body> </html> diff --git a/chrome/browser/resources/about_version.js b/chrome/browser/resources/about_version.js new file mode 100644 index 0000000..30ad114 --- /dev/null +++ b/chrome/browser/resources/about_version.js @@ -0,0 +1,14 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/* All the work we do onload. */ +function onLoadWork() { + // This is the javascript code that processes the template: + var input = new JsEvalContext(templateData); + var output = document.getElementById('t'); + jstProcess(input, output); +} + +document.addEventListener('DOMContentLoaded', onLoadWork); + |