summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authortsepez@chromium.org <tsepez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-28 17:35:18 +0000
committertsepez@chromium.org <tsepez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-28 17:35:18 +0000
commitbe843e26b00f611d3bcf3b2652b8eccf95310346 (patch)
treea364e6cc8a143e6dfbcc047f35c13ebbddca4dae /chrome/browser
parente01d28171595bd723e6fd9846a7783c037d882f1 (diff)
downloadchromium_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.cc432
-rw-r--r--chrome/browser/browser_resources.grd8
-rw-r--r--chrome/browser/net/predictor_api.cc5
-rw-r--r--chrome/browser/resources/about_credits.js38
-rw-r--r--chrome/browser/resources/about_credits.tmpl25
-rw-r--r--chrome/browser/resources/about_credits_entry.tmpl2
-rw-r--r--chrome/browser/resources/about_memory.html85
-rw-r--r--chrome/browser/resources/about_memory.js83
-rw-r--r--chrome/browser/resources/about_memory_linux.html86
-rw-r--r--chrome/browser/resources/about_memory_mac.html85
-rw-r--r--chrome/browser/resources/about_stats.html217
-rw-r--r--chrome/browser/resources/about_stats.js202
-rw-r--r--chrome/browser/resources/about_version.html6
-rw-r--r--chrome/browser/resources/about_version.js14
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
- + "/&lt;secs&gt;)");
+ output->append("(To auto-refresh this page: about:");
+ output->append(name);
+ output->append("/&lt;secs&gt;)");
}
- 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);
+