diff options
author | erikkay@google.com <erikkay@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-04 20:27:04 +0000 |
---|---|---|
committer | erikkay@google.com <erikkay@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-04 20:27:04 +0000 |
commit | 07c00d99969c6584079c78a2e31cb0d5ad5beda7 (patch) | |
tree | 84243fe741c02a76214c76cf5bfa2bb0fe93f670 | |
parent | 1b1e520d728ae8f53b944322fcfddab929aad70f (diff) | |
download | chromium_src-07c00d99969c6584079c78a2e31cb0d5ad5beda7.zip chromium_src-07c00d99969c6584079c78a2e31cb0d5ad5beda7.tar.gz chromium_src-07c00d99969c6584079c78a2e31cb0d5ad5beda7.tar.bz2 |
Add trivial theming support in extensions.
NOTE: This is not final API. It *will* change. It's purely for testing purposes.
Review URL: http://codereview.chromium.org/40042
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10913 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/version.h | 3 | ||||
-rw-r--r-- | chrome/browser/extensions/extension.cc | 39 | ||||
-rw-r--r-- | chrome/browser/extensions/extension.h | 19 | ||||
-rw-r--r-- | chrome/common/resource_bundle.cc | 46 | ||||
-rw-r--r-- | chrome/common/resource_bundle.h | 9 |
5 files changed, 103 insertions, 13 deletions
diff --git a/base/version.h b/base/version.h index 6e12bb7..7145f05 100644 --- a/base/version.h +++ b/base/version.h @@ -12,7 +12,6 @@ class Version { public: - // The version string must be made up of 1 or more uint16's separated // by '.'. Returns NULL if string is not in this format. // Caller is responsible for freeing the Version object once done. @@ -36,8 +35,6 @@ private: bool InitFromString(const std::string& version_str); std::vector<uint16> components_; - - DISALLOW_COPY_AND_ASSIGN(Version); }; #endif // BASE_VERSION_H_ diff --git a/chrome/browser/extensions/extension.cc b/chrome/browser/extensions/extension.cc index 918268f..44635c5 100644 --- a/chrome/browser/extensions/extension.cc +++ b/chrome/browser/extensions/extension.cc @@ -9,6 +9,7 @@ #include "base/string_util.h" #include "net/base/net_util.h" #include "chrome/common/extensions/user_script.h" +#include "chrome/common/resource_bundle.h" #include "chrome/common/url_constants.h" const char Extension::kManifestFilename[] = "manifest.json"; @@ -24,6 +25,7 @@ const wchar_t* Extension::kRunAtKey = L"run_at"; const wchar_t* Extension::kVersionKey = L"version"; const wchar_t* Extension::kZipHashKey = L"zip_hash"; const wchar_t* Extension::kPluginsDirKey = L"plugins_dir"; +const wchar_t* Extension::kThemeKey = L"theme"; const char* Extension::kRunAtDocumentStartValue = "document_start"; const char* Extension::kRunAtDocumentEndValue = "document_end"; @@ -71,6 +73,19 @@ const char* Extension::kInvalidPluginsDirError = const size_t Extension::kIdSize = 20; // SHA1 (160 bits) == 20 bytes +Extension::Extension(const Extension& rhs) : + path_(rhs.path_), + extension_url_(rhs.extension_url_), + id_(rhs.id_), + version_(new Version(*rhs.version_)), + name_(rhs.name_), + description_(rhs.description_), + content_scripts_(rhs.content_scripts_), + plugins_dir_(rhs.plugins_dir_), + zip_hash_(rhs.zip_hash_), + theme_paths_(rhs.theme_paths_) { +} + const std::string Extension::VersionString() const { return version_->GetString(); } @@ -87,6 +102,14 @@ GURL Extension::GetResourceURL(const GURL& extension_url, return ret_val; } +FilePath Extension::GetThemeResourcePath(const int resource_id) { + std::wstring id = IntToWString(resource_id); + std::string path = theme_paths_[id]; + if (path.size()) + return path_.AppendASCII(path.c_str()); + return FilePath(); +} + // static FilePath Extension::GetResourcePath(const FilePath& extension_path, const std::string& relative_path) { @@ -237,6 +260,22 @@ bool Extension::InitFromValue(const DictionaryValue& source, plugins_dir_ = path_.AppendASCII(plugins_dir); } + if (source.HasKey(kThemeKey)) { + DictionaryValue* dict_value; + if (source.GetDictionary(kThemeKey, &dict_value)) { + DictionaryValue::key_iterator iter = dict_value->begin_keys(); + while (iter != dict_value->end_keys()) { + std::string val; + if (dict_value->GetString(*iter, &val)) { + std::wstring id = *iter; + theme_paths_[id] = val; + } + ++iter; + } + ResourceBundle::GetSharedInstance().SetThemeExtension(*this); + } + } + // Initialize content scripts (optional). if (source.HasKey(kContentScriptsKey)) { ListValue* list_value; diff --git a/chrome/browser/extensions/extension.h b/chrome/browser/extensions/extension.h index 095e7bd..5ca86d3 100644 --- a/chrome/browser/extensions/extension.h +++ b/chrome/browser/extensions/extension.h @@ -21,6 +21,7 @@ class Extension { public: Extension() {} explicit Extension(const FilePath& path); + explicit Extension(const Extension& path); // The format for extension manifests that this code understands. static const unsigned int kExpectedFormatVersion = 1; @@ -40,6 +41,7 @@ class Extension { static const wchar_t* kVersionKey; static const wchar_t* kZipHashKey; static const wchar_t* kPluginsDirKey; + static const wchar_t* kThemeKey; // Some values expected in manifests. static const char* kRunAtDocumentStartValue; @@ -67,7 +69,7 @@ class Extension { // The number of bytes in a legal id. static const size_t kIdSize; - // Creates an absolute url to a resource inside an extension. The + // Returns an absolute url to a resource inside of an extension. The // |extension_url| argument should be the url() from an Extension object. The // |relative_path| can be untrusted user input. The returned URL will either // be invalid() or a child of |extension_url|. @@ -75,7 +77,7 @@ class Extension { static GURL GetResourceURL(const GURL& extension_url, const std::string& relative_path); - // Creates an absolute path to a resource inside an extension. The + // Returns an absolute path to a resource inside of an extension. The // |extension_path| argument should be the path() from an Extension object. // The |relative_path| can be untrusted user input. The returned path will // either be empty or a child of extension_path. @@ -83,6 +85,13 @@ class Extension { static FilePath GetResourcePath(const FilePath& extension_path, const std::string& relative_path); + // Returns an absolute path to a resource inside of an extension if the + // extension has a theme defined with the given |resource_id|. Otherwise + // the path will be empty. Note that this method is not static as it is + // only intended to be called on an extension which has registered itself + // as providing a theme. + FilePath GetThemeResourcePath(const int resource_id); + // The path to the folder the extension is stored in. const FilePath& path() const { return path_; } @@ -152,7 +161,11 @@ class Extension { // will not have this key. std::string zip_hash_; - DISALLOW_COPY_AND_ASSIGN(Extension); + // A map of resource id's to relative file paths. + std::map<const std::wstring, std::string> theme_paths_; + + // We implement copy, but not assign. + void operator=(const Extension&); }; #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_H_ diff --git a/chrome/common/resource_bundle.cc b/chrome/common/resource_bundle.cc index 785dd29..29bb679 100644 --- a/chrome/common/resource_bundle.cc +++ b/chrome/common/resource_bundle.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2009 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. @@ -7,6 +7,8 @@ #include "base/gfx/png_decoder.h" #include "base/logging.h" #include "base/string_piece.h" +#include "net/base/file_stream.h" +#include "net/base/net_errors.h" #include "chrome/common/gfx/chrome_font.h" #include "SkBitmap.h" @@ -43,23 +45,55 @@ ResourceBundle::ResourceBundle() void ResourceBundle::FreeImages() { for (SkImageMap::iterator i = skia_images_.begin(); - i != skia_images_.end(); i++) { + i != skia_images_.end(); i++) { delete i->second; } skia_images_.clear(); } +void ResourceBundle::SetThemeExtension(const Extension& e) { + theme_extension_.reset(new Extension(e)); +} + /* static */ SkBitmap* ResourceBundle::LoadBitmap(DataHandle data_handle, int resource_id) { std::vector<unsigned char> raw_data, png_data; - bool success = LoadResourceBytes(data_handle, resource_id, &raw_data); + bool success = false; + // First check to see if we have a registered theme extension and whether + // it can handle this resource. + // TODO(erikkay): It would be nice to use something less brittle than + // resource_id here. + if (g_shared_instance_->theme_extension_.get()) { + FilePath path = + g_shared_instance_->theme_extension_->GetThemeResourcePath(resource_id); + if (!path.empty()) { + net::FileStream file; + int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ; + if (file.Open(path, flags) == net::OK) { + int64 avail = file.Available(); + if (avail > 0 && avail < INT_MAX) { + size_t size = static_cast<size_t>(avail); + raw_data.resize(size); + char* data = reinterpret_cast<char*>(&(raw_data.front())); + if (file.ReadUntilComplete(data, size) == avail) { + success= true; + } else { + raw_data.resize(0); + } + } + } + } + } + if (!success) + success = LoadResourceBytes(data_handle, resource_id, &raw_data); if (!success) return NULL; // Decode the PNG. int image_width; int image_height; - if (!PNGDecoder::Decode(&raw_data.front(), raw_data.size(), PNGDecoder::FORMAT_BGRA, + if (!PNGDecoder::Decode(&raw_data.front(), raw_data.size(), + PNGDecoder::FORMAT_BGRA, &png_data, &image_width, &image_height)) { NOTREACHED() << "Unable to decode image resource " << resource_id; return NULL; @@ -126,8 +160,8 @@ SkBitmap* ResourceBundle::GetBitmapNamed(int resource_id) { // The placeholder bitmap is bright red so people notice the problem. // This bitmap will be leaked, but this code should never be hit. empty_bitmap = new SkBitmap(); - empty_bitmap->setConfig(SkBitmap::kARGB_8888_Config, 32, 32); - empty_bitmap->allocPixels(); + empty_bitmap->setConfig(SkBitmap::kARGB_8888_Config, 32, 32); + empty_bitmap->allocPixels(); empty_bitmap->eraseARGB(255, 255, 0, 0); } return empty_bitmap; diff --git a/chrome/common/resource_bundle.h b/chrome/common/resource_bundle.h index ac62d9b..30fcbc7 100644 --- a/chrome/common/resource_bundle.h +++ b/chrome/common/resource_bundle.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2009 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. @@ -18,6 +18,7 @@ #include "base/file_path.h" #include "base/lock.h" #include "base/scoped_ptr.h" +#include "chrome/browser/extensions/extension.h" #if defined(OS_LINUX) || defined(OS_MACOSX) namespace base { @@ -28,6 +29,7 @@ namespace base { typedef struct _GdkPixbuf GdkPixbuf; #endif class ChromeFont; +class Extension; class SkBitmap; class StringPiece; @@ -118,6 +120,9 @@ class ResourceBundle { GdkPixbuf* LoadPixbuf(int resource_id); #endif + // Sets an Extension object that can handle theme resource requests. + void SetThemeExtension(const Extension& e); + private: // We define a DataHandle typedef to abstract across how data is stored // across platforms. @@ -183,6 +188,8 @@ class ResourceBundle { static ResourceBundle* g_shared_instance_; + scoped_ptr<Extension> theme_extension_; + DISALLOW_EVIL_CONSTRUCTORS(ResourceBundle); }; |