| Index: chrome/browser/ui/webui/settings/md_settings_ui.cc
|
| diff --git a/chrome/browser/ui/webui/settings/md_settings_ui.cc b/chrome/browser/ui/webui/settings/md_settings_ui.cc
|
| index 6e30deb2b5c5ed387ff911bb5cb9a4026e44fe40..4e0581289d4b152d1c67cf5b5bf55e5d368feb6d 100644
|
| --- a/chrome/browser/ui/webui/settings/md_settings_ui.cc
|
| +++ b/chrome/browser/ui/webui/settings/md_settings_ui.cc
|
| @@ -6,9 +6,14 @@
|
|
|
| #include <stddef.h>
|
|
|
| -#include <string>
|
| +#include <vector>
|
|
|
| +#include "base/bind.h"
|
| #include "base/metrics/histogram_macros.h"
|
| +#include "base/strings/string_piece.h"
|
| +#include "base/strings/string_split.h"
|
| +#include "base/strings/string_util.h"
|
| +#include "base/strings/stringprintf.h"
|
| #include "chrome/browser/profiles/profile.h"
|
| #include "chrome/browser/ui/webui/settings/about_handler.h"
|
| #include "chrome/browser/ui/webui/settings/appearance_handler.h"
|
| @@ -32,9 +37,13 @@
|
| #include "chrome/common/url_constants.h"
|
| #include "content/public/browser/web_contents.h"
|
| #include "content/public/browser/web_ui.h"
|
| -#include "content/public/browser/web_ui_data_source.h"
|
| +
|
| +// TODO(dbeam): make content/public interface for this.
|
| +#include "content/browser/webui/shared_resources_data_source.h"
|
| +
|
| #include "grit/settings_resources.h"
|
| #include "grit/settings_resources_map.h"
|
| +#include "ui/base/resource/resource_bundle.h"
|
|
|
| #if defined(OS_CHROMEOS)
|
| #include "ash/common/system/chromeos/palette/palette_utils.h"
|
| @@ -58,11 +67,15 @@
|
| #include "chrome/browser/ui/webui/settings/native_certificates_handler.h"
|
| #endif // defined(USE_NSS_CERTS)
|
|
|
| +#include "third_party/re2/src/re2/re2.h"
|
| +
|
| namespace settings {
|
|
|
| MdSettingsUI::MdSettingsUI(content::WebUI* web_ui, const GURL& url)
|
| : content::WebUIController(web_ui),
|
| - WebContentsObserver(web_ui->GetWebContents()) {
|
| + WebContentsObserver(web_ui->GetWebContents()),
|
| + html_source_(nullptr) {
|
| + // weak_ptr_factory_(this) {
|
| Profile* profile = Profile::FromWebUI(web_ui);
|
| AddSettingsPageUIHandler(new AppearanceHandler(web_ui));
|
|
|
| @@ -108,40 +121,154 @@ MdSettingsUI::MdSettingsUI(content::WebUI* web_ui, const GURL& url)
|
| CHECK(url.GetOrigin() == GURL(chrome::kChromeUISettingsURL).GetOrigin() ||
|
| url.GetOrigin() == GURL(chrome::kChromeUIMdSettingsURL).GetOrigin());
|
|
|
| - content::WebUIDataSource* html_source =
|
| - content::WebUIDataSource::Create(url.host());
|
| + html_source_ = content::WebUIDataSource::Create(url.host());
|
| + html_source_->SetRequestFilter(
|
| + base::Bind(&MdSettingsUI::RequestFilter, base::Unretained(this)));
|
|
|
| #if defined(OS_CHROMEOS)
|
| chromeos::settings::EasyUnlockSettingsHandler* easy_unlock_handler =
|
| - chromeos::settings::EasyUnlockSettingsHandler::Create(html_source,
|
| + chromeos::settings::EasyUnlockSettingsHandler::Create(html_source_,
|
| profile);
|
| if (easy_unlock_handler)
|
| AddSettingsPageUIHandler(easy_unlock_handler);
|
|
|
| - html_source->AddBoolean("noteAllowed", ash::IsPaletteEnabled());
|
| - html_source->AddBoolean("quickUnlockEnabled",
|
| - chromeos::IsQuickUnlockEnabled());
|
| + html_source_->AddBoolean("noteAllowed", ash::IsPaletteEnabled());
|
| + html_source_->AddBoolean("quickUnlockEnabled",
|
| + chromeos::IsQuickUnlockEnabled());
|
| #endif
|
|
|
| - AddSettingsPageUIHandler(AboutHandler::Create(html_source, profile));
|
| - AddSettingsPageUIHandler(ResetSettingsHandler::Create(html_source, profile));
|
| + AddSettingsPageUIHandler(AboutHandler::Create(html_source_, profile));
|
| + AddSettingsPageUIHandler(ResetSettingsHandler::Create(html_source_, profile));
|
|
|
| // Add all settings resources.
|
| for (size_t i = 0; i < kSettingsResourcesSize; ++i) {
|
| - html_source->AddResourcePath(kSettingsResources[i].name,
|
| - kSettingsResources[i].value);
|
| + html_source_->AddResourcePath(kSettingsResources[i].name,
|
| + kSettingsResources[i].value);
|
| }
|
|
|
| - AddLocalizedStrings(html_source, profile);
|
| - html_source->SetDefaultResource(IDR_SETTINGS_SETTINGS_HTML);
|
| + AddLocalizedStrings(html_source_, profile);
|
| + html_source_->SetDefaultResource(IDR_SETTINGS_SETTINGS_HTML);
|
| +
|
| + base::TimeTicks then = base::TimeTicks::Now();
|
| +
|
| + std::vector<GURL> urls;
|
| + GatherPreloadUrls(GURL("chrome://md-settings/settings.html"), &urls);
|
| +
|
| + for (const GURL& url : urls) {
|
| + const std::string spec = url.spec();
|
| +
|
| + std::string rel;
|
| + std::string as;
|
| + if (base::EndsWith(spec, ".js", base::CompareCase::INSENSITIVE_ASCII)) {
|
| + rel = "preload";
|
| + as = " as=\"script\"";
|
| + } else if (base::EndsWith(spec, ".css",
|
| + base::CompareCase::INSENSITIVE_ASCII)) {
|
| + rel = "preload";
|
| + as = " as=\"style\"";
|
| + } else if (base::EndsWith(spec, ".html",
|
| + base::CompareCase::INSENSITIVE_ASCII)) {
|
| + continue;
|
| + rel = "import";
|
| + // as="document" doesn't work yet.
|
| + }
|
| +
|
| + preloads_.append(base::StringPrintf(
|
| + "<link rel=\"%s\" href=\"%s\"%s>\n",
|
| + rel.c_str(), spec.c_str(), as.c_str()));
|
| + }
|
| +
|
| + LOG(ERROR) << "time gathering: " << (base::TimeTicks::Now() - then).InMilliseconds();
|
|
|
| content::WebUIDataSource::Add(web_ui->GetWebContents()->GetBrowserContext(),
|
| - html_source);
|
| + html_source_);
|
| }
|
|
|
| MdSettingsUI::~MdSettingsUI() {
|
| }
|
|
|
| +bool MdSettingsUI::RequestFilter(
|
| + const std::string& path,
|
| + const content::WebUIDataSource::GotDataCallback& callback) {
|
| + if (!path.empty())
|
| + return false;
|
| +
|
| + base::StringPiece settings_html =
|
| + ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
|
| + IDR_SETTINGS_SETTINGS_HTML);
|
| +
|
| + std::string preloads_placeholder("<!-- preloads -->");
|
| + size_t preloads_start = settings_html.find(preloads_placeholder);
|
| +
|
| + std::string response;
|
| + settings_html.substr(0, preloads_start).AppendToString(&response);
|
| + response.append(preloads_);
|
| + settings_html.substr(preloads_start + preloads_placeholder.size())
|
| + .AppendToString(&response);
|
| +
|
| + callback.Run(base::RefCountedString::TakeString(&response));
|
| + return true;
|
| +}
|
| +
|
| +void MdSettingsUI::GatherPreloadUrls(const GURL& url, std::vector<GURL>* urls) {
|
| + CHECK(url.SchemeIs(content::kChromeUIScheme) &&
|
| + (url.host() == content::kChromeUIResourcesHost ||
|
| + url.host() == chrome::kChromeUISettingsHost ||
|
| + url.host() == chrome::kChromeUIMdSettingsHost));
|
| +
|
| + std::string path = url.path();
|
| + CHECK(!path.empty());
|
| +
|
| + if (path[0] == '/')
|
| + path.erase(0, 1);
|
| +
|
| + int idr = -1;
|
| +
|
| + if (url.host() == content::kChromeUIResourcesHost) {
|
| + const auto& map = content::SharedResourcesDataSource::GetResourcesMap();
|
| + auto it = map.find(path);
|
| + if (it != map.end())
|
| + idr = it->second;
|
| + } else {
|
| + const auto& map = html_source_->path_to_idr_map();
|
| + auto it = map.find(path);
|
| + if (it != map.end())
|
| + idr = it->second;
|
| + }
|
| +
|
| + if (idr == -1) {
|
| + LOG(ERROR) << "@@ unknown url: " << url << ", path: " << path << " @@";
|
| + return;
|
| + }
|
| +
|
| + std::string resource = ui::ResourceBundle::GetSharedInstance()
|
| + .GetRawDataResource(idr).as_string();
|
| +
|
| + re2::StringPiece re2_resource(resource);
|
| +
|
| + re2::RE2 regex(
|
| + "<link[^>]+?rel=\"import\"[^>]+?href=\"([^\"]+)\"|"
|
| + "<link[^>]+?rel=\"stylesheet\"[^>]+?href=\"([^\"]+)\"|"
|
| + "<script[^>]+?src=\"([^\"]+)");
|
| +
|
| + re2::StringPiece html, css, js;
|
| +
|
| + while (re2::RE2::FindAndConsume(&re2_resource, regex, &html, &css, &js)) {
|
| + CHECK_EQ(html.empty() + css.empty() + js.empty(), 2);
|
| +
|
| + std::string new_path = html.as_string() + css.as_string() + js.as_string();
|
| + CHECK(!new_path.empty());
|
| +
|
| + GURL new_url = url.Resolve(new_path);
|
| +
|
| + if (std::find(urls->begin(), urls->end(), new_url) != urls->end())
|
| + continue;
|
| +
|
| + urls->push_back(new_url);
|
| + GatherPreloadUrls(new_url, urls);
|
| + }
|
| +}
|
| +
|
| void MdSettingsUI::AddSettingsPageUIHandler(SettingsPageUIHandler* handler) {
|
| DCHECK(handler);
|
| handlers_.insert(handler);
|
|
|