summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorerikkay@google.com <erikkay@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-04 20:27:04 +0000
committererikkay@google.com <erikkay@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-04 20:27:04 +0000
commit07c00d99969c6584079c78a2e31cb0d5ad5beda7 (patch)
tree84243fe741c02a76214c76cf5bfa2bb0fe93f670
parent1b1e520d728ae8f53b944322fcfddab929aad70f (diff)
downloadchromium_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.h3
-rw-r--r--chrome/browser/extensions/extension.cc39
-rw-r--r--chrome/browser/extensions/extension.h19
-rw-r--r--chrome/common/resource_bundle.cc46
-rw-r--r--chrome/common/resource_bundle.h9
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);
};