| Index: chrome/browser/ui/webui/fileicon_source.cc
|
| diff --git a/chrome/browser/ui/webui/fileicon_source.cc b/chrome/browser/ui/webui/fileicon_source.cc
|
| index 30ee3dac6131c4397e61fa0a637d1e8922306cbb..17d10c59bd32e28f2d512165cd681cdd11535ea4 100644
|
| --- a/chrome/browser/ui/webui/fileicon_source.cc
|
| +++ b/chrome/browser/ui/webui/fileicon_source.cc
|
| @@ -1,48 +1,93 @@
|
| -// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| +// Copyright (c) 2012 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.
|
|
|
| #include "chrome/browser/ui/webui/fileicon_source.h"
|
|
|
| +#include "base/basictypes.h"
|
| #include "base/callback.h"
|
| #include "base/file_path.h"
|
| #include "base/memory/ref_counted_memory.h"
|
| +#include "base/string_split.h"
|
| #include "base/utf_string_conversions.h"
|
| #include "chrome/browser/browser_process.h"
|
| #include "chrome/common/time_format.h"
|
| +#include "googleurl/src/gurl.h"
|
| #include "grit/generated_resources.h"
|
| #include "net/base/escape.h"
|
| #include "third_party/skia/include/core/SkBitmap.h"
|
| #include "ui/gfx/codec/png_codec.h"
|
| #include "ui/gfx/image/image.h"
|
|
|
| -// The path used in internal URLs to file icon data.
|
| -static const char kFileIconPath[] = "fileicon";
|
| +namespace {
|
|
|
| -FileIconSource::FileIconSource()
|
| - : DataSource(kFileIconPath, MessageLoop::current()) {}
|
| +typedef std::map<std::string, IconLoader::IconSize> QueryIconSizeMap;
|
|
|
| -FileIconSource::~FileIconSource() {
|
| - cancelable_consumer_.CancelAllRequests();
|
| -}
|
| +// The path used in internal URLs to file icon data.
|
| +const char kFileIconPath[] = "fileicon";
|
|
|
| -void FileIconSource::StartDataRequest(const std::string& path,
|
| - bool is_incognito,
|
| - int request_id) {
|
| - std::string escaped_path = net::UnescapeURLComponent(path,
|
| - net::UnescapeRule::SPACES);
|
| +// URL parameter specifying icon size.
|
| +const char kIconSize[] = "iconsize";
|
| +
|
| +// Assuming the url is of the form '/path?query', convert the path portion into
|
| +// a FilePath and return the resulting |file_path| and |query|. The path
|
| +// portion may have been encoded using encodeURIComponent().
|
| +void GetFilePathAndQuery(const std::string& url,
|
| + FilePath* file_path,
|
| + std::string* query) {
|
| + // We receive the url with chrome://fileicon/ stripped but GURL expects it.
|
| + const GURL gurl("chrome://fileicon/" + url);
|
| + std::string path =
|
| + net::UnescapeURLComponent(gurl.path().substr(1),
|
| + (net::UnescapeRule::URL_SPECIAL_CHARS |
|
| + net::UnescapeRule::SPACES));
|
| #if defined(OS_WIN)
|
| // The path we receive has the wrong slashes and escaping for what we need;
|
| // this only appears to matter for getting icons from .exe files.
|
| - std::replace(escaped_path.begin(), escaped_path.end(), '/', '\\');
|
| - FilePath escaped_filepath(UTF8ToWide(escaped_path));
|
| + std::replace(path.begin(), path.end(), '/', '\\');
|
| + *file_path = FilePath(UTF8ToWide(path));
|
| #elif defined(OS_POSIX)
|
| // The correct encoding on Linux may not actually be UTF8.
|
| - FilePath escaped_filepath(escaped_path);
|
| + *file_path = FilePath(path);
|
| #endif
|
| + query->assign(gurl.query());
|
| +}
|
| +
|
| +IconLoader::IconSize SizeStringToIconSize(const std::string& size_string) {
|
| + if (size_string == "small") return IconLoader::SMALL;
|
| + if (size_string == "large") return IconLoader::LARGE;
|
| + // We default to NORMAL if we don't recognize the size_string. Including
|
| + // size_string=="normal".
|
| + return IconLoader::NORMAL;
|
| +}
|
| +
|
| +// Simple parser for data on the query.
|
| +IconLoader::IconSize QueryToIconSize(const std::string& query) {
|
| + typedef std::pair<std::string, std::string> KVPair;
|
| + std::vector<KVPair> parameters;
|
| + base::SplitStringIntoKeyValuePairs(query, '=', '&', ¶meters);
|
| + for (std::vector<KVPair>::const_iterator iter = parameters.begin();
|
| + iter != parameters.end(); ++iter) {
|
| + if (iter->first == kIconSize)
|
| + return SizeStringToIconSize(iter->second);
|
| + }
|
| + return IconLoader::NORMAL;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +FileIconSource::FileIconSource()
|
| + : DataSource(kFileIconPath, MessageLoop::current()) {}
|
| +
|
| +FileIconSource::~FileIconSource() {
|
| + cancelable_consumer_.CancelAllRequests();
|
| +}
|
|
|
| +void FileIconSource::FetchFileIcon(const FilePath& path,
|
| + IconLoader::IconSize icon_size,
|
| + int request_id) {
|
| IconManager* im = g_browser_process->icon_manager();
|
| - gfx::Image* icon = im->LookupIcon(escaped_filepath, IconLoader::NORMAL);
|
| + gfx::Image* icon = im->LookupIcon(path, icon_size);
|
|
|
| if (icon) {
|
| scoped_refptr<RefCountedBytes> icon_data(new RefCountedBytes);
|
| @@ -51,9 +96,8 @@ void FileIconSource::StartDataRequest(const std::string& path,
|
| SendResponse(request_id, icon_data);
|
| } else {
|
| // Icon was not in cache, go fetch it slowly.
|
| - IconManager::Handle h = im->LoadIcon(escaped_filepath,
|
| - IconLoader::NORMAL,
|
| - &cancelable_consumer_,
|
| + IconManager::Handle h = im->LoadIcon(
|
| + path, icon_size, &cancelable_consumer_,
|
| base::Bind(&FileIconSource::OnFileIconDataAvailable,
|
| base::Unretained(this)));
|
|
|
| @@ -62,6 +106,15 @@ void FileIconSource::StartDataRequest(const std::string& path,
|
| }
|
| }
|
|
|
| +void FileIconSource::StartDataRequest(const std::string& url_path,
|
| + bool is_incognito,
|
| + int request_id) {
|
| + std::string query;
|
| + FilePath file_path;
|
| + GetFilePathAndQuery(url_path, &file_path, &query);
|
| + FetchFileIcon(file_path, QueryToIconSize(query), request_id);
|
| +}
|
| +
|
| std::string FileIconSource::GetMimeType(const std::string&) const {
|
| // Rely on image decoder inferring the correct type.
|
| return std::string();
|
|
|