Commit e354e886 authored by aa@chromium.org's avatar aa@chromium.org

Split extension_base.* out of bindings_utils.*.

BUG=
TEST=

Review URL: http://codereview.chromium.org/7767011

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@98743 0039d316-1c4b-4281-b951-d872f2087c98
parent 1b2ec22e
......@@ -63,6 +63,8 @@
'renderer/extensions/chrome_webstore_bindings.h',
'renderer/extensions/event_bindings.cc',
'renderer/extensions/event_bindings.h',
'renderer/extensions/extension_base.cc',
'renderer/extensions/extension_base.h',
'renderer/extensions/extension_dispatcher.cc',
'renderer/extensions/extension_dispatcher.h',
'renderer/extensions/extension_groups.h',
......
......@@ -4,16 +4,15 @@
#include "chrome/renderer/automation/dom_automation_v8_extension.h"
#include "chrome/renderer/extensions/bindings_utils.h"
#include "chrome/renderer/extensions/extension_base.h"
#include "grit/renderer_resources.h"
using bindings_utils::GetStringResource;
const char* DomAutomationV8Extension::kName = "chrome/domautomation";
v8::Extension* DomAutomationV8Extension::Get() {
static v8::Extension* extension =
new v8::Extension(
kName, GetStringResource(IDR_DOM_AUTOMATION_JS), 0, NULL);
kName, ExtensionBase::GetStringResource(IDR_DOM_AUTOMATION_JS), 0,
NULL);
return extension;
}
......@@ -4,16 +4,10 @@
#include "chrome/renderer/extensions/bindings_utils.h"
#include "base/logging.h"
#include "base/lazy_instance.h"
#include "base/stringprintf.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_set.h"
#include "chrome/renderer/extensions/extension_dispatcher.h"
#include "content/renderer/render_view.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "v8/include/v8.h"
......@@ -33,101 +27,6 @@ struct SingletonData {
static base::LazyInstance<SingletonData> g_singleton_data(
base::LINKER_INITIALIZED);
typedef std::map<int, std::string> StringMap;
static base::LazyInstance<StringMap> g_string_map(base::LINKER_INITIALIZED);
const char* GetStringResource(int resource_id) {
StringMap* strings = g_string_map.Pointer();
StringMap::iterator it = strings->find(resource_id);
if (it == strings->end()) {
it = strings->insert(std::make_pair(
resource_id,
ResourceBundle::GetSharedInstance().GetRawDataResource(
resource_id).as_string())).first;
}
return it->second.c_str();
}
// ExtensionBase
const Extension* ExtensionBase::GetExtensionForCurrentContext() const {
RenderView* renderview = bindings_utils::GetRenderViewForCurrentContext();
if (!renderview)
return NULL; // this can happen as a tab is closing.
GURL url = renderview->webview()->mainFrame()->document().url();
const ExtensionSet* extensions = extension_dispatcher_->extensions();
if (!extensions->ExtensionBindingsAllowed(url))
return NULL;
return extensions->GetByURL(url);
}
bool ExtensionBase::CheckPermissionForCurrentContext(
const std::string& function_name) const {
const ::Extension* extension = GetExtensionForCurrentContext();
if (extension &&
extension_dispatcher_->IsExtensionActive(extension->id()) &&
extension->HasAPIPermission(function_name))
return true;
static const char kMessage[] =
"You do not have permission to use '%s'. Be sure to declare"
" in your manifest what permissions you need.";
std::string error_msg = base::StringPrintf(kMessage, function_name.c_str());
v8::ThrowException(v8::Exception::Error(v8::String::New(error_msg.c_str())));
return false;
}
v8::Handle<v8::FunctionTemplate>
ExtensionBase::GetNativeFunction(v8::Handle<v8::String> name) {
if (name->Equals(v8::String::New("GetChromeHidden"))) {
return v8::FunctionTemplate::New(GetChromeHidden);
}
if (name->Equals(v8::String::New("Print"))) {
return v8::FunctionTemplate::New(Print);
}
return v8::Handle<v8::FunctionTemplate>();
}
v8::Handle<v8::Value> ExtensionBase::GetChromeHidden(
const v8::Arguments& args) {
v8::Local<v8::Context> context = v8::Context::GetCurrent();
v8::Local<v8::Object> global = context->Global();
v8::Local<v8::Value> hidden = global->GetHiddenValue(
v8::String::New(kChromeHidden));
if (hidden.IsEmpty() || hidden->IsUndefined()) {
hidden = v8::Object::New();
global->SetHiddenValue(v8::String::New(kChromeHidden), hidden);
#ifndef NDEBUG
// Tell extension_process_bindings.js to validate callbacks and events
// against their schema definitions in api/extension_api.json.
v8::Local<v8::Object>::Cast(hidden)
->Set(v8::String::New(kValidateCallbacks), v8::True());
#endif
}
DCHECK(hidden->IsObject());
return hidden;
}
v8::Handle<v8::Value> ExtensionBase::Print(const v8::Arguments& args) {
if (args.Length() < 1)
return v8::Undefined();
std::vector<std::string> components;
for (int i = 0; i < args.Length(); ++i)
components.push_back(*v8::String::Utf8Value(args[i]->ToString()));
LOG(ERROR) << JoinString(components, ',');
return v8::Undefined();
}
ContextInfo::ContextInfo(v8::Persistent<v8::Context> context,
const std::string& extension_id,
WebFrame* frame)
......@@ -157,6 +56,28 @@ ContextInfo* GetInfoForCurrentContext() {
return context_iter->get();
}
v8::Handle<v8::Object> GetChromeHiddenForContext(
v8::Handle<v8::Context> context) {
v8::Local<v8::Object> global = context->Global();
v8::Local<v8::Value> hidden = global->GetHiddenValue(
v8::String::New(kChromeHidden));
if (hidden.IsEmpty() || hidden->IsUndefined()) {
hidden = v8::Object::New();
global->SetHiddenValue(v8::String::New(kChromeHidden), hidden);
#ifndef NDEBUG
// Tell extension_process_bindings.js to validate callbacks and events
// against their schema definitions in api/extension_api.json.
v8::Local<v8::Object>::Cast(hidden)
->Set(v8::String::New(kValidateCallbacks), v8::True());
#endif
}
DCHECK(hidden->IsObject());
return v8::Local<v8::Object>::Cast(hidden);
}
PendingRequest::PendingRequest(v8::Persistent<v8::Context> context,
const std::string& name)
: context(context), name(name) {
......
......@@ -8,15 +8,12 @@
#include "base/memory/linked_ptr.h"
#include "base/memory/singleton.h"
#include "base/string_piece.h"
#include "ui/base/resource/resource_bundle.h"
#include "v8/include/v8.h"
#include <list>
#include <map>
#include <string>
class Extension;
class ExtensionDispatcher;
class RenderView;
namespace WebKit {
......@@ -25,59 +22,6 @@ class WebFrame;
namespace bindings_utils {
// This is a base class for chrome extension bindings. Common features that
// are shared by different modules go here.
class ExtensionBase : public v8::Extension {
public:
ExtensionBase(const char* name,
const char* source,
int dep_count,
const char** deps,
ExtensionDispatcher* extension_dispatcher)
: v8::Extension(name, source, dep_count, deps),
extension_dispatcher_(extension_dispatcher) {
}
// Derived classes should call this at the end of their implementation in
// order to expose common native functions, like GetChromeHidden, to the
// v8 extension.
virtual v8::Handle<v8::FunctionTemplate>
GetNativeFunction(v8::Handle<v8::String> name);
// TODO(jstritar): Used for testing http://crbug.com/91582. Remove when done.
ExtensionDispatcher* extension_dispatcher() { return extension_dispatcher_; }
protected:
template<class T>
static T* GetFromArguments(const v8::Arguments& args) {
CHECK(!args.Data().IsEmpty());
T* result = static_cast<T*>(args.Data().As<v8::External>()->Value());
return result;
}
// Note: do not call this function before or during the chromeHidden.onLoad
// event dispatch. The URL might not have been committed yet and might not
// be an extension URL.
const ::Extension* GetExtensionForCurrentContext() const;
// Checks that the current context contains an extension that has permission
// to execute the specified function. If it does not, a v8 exception is thrown
// and the method returns false. Otherwise returns true.
bool CheckPermissionForCurrentContext(const std::string& function_name) const;
// Returns a hidden variable for use by the bindings that is unreachable
// by the page.
static v8::Handle<v8::Value> GetChromeHidden(const v8::Arguments& args);
ExtensionDispatcher* extension_dispatcher_;
private:
// Helper to print from bindings javascript.
static v8::Handle<v8::Value> Print(const v8::Arguments& args);
};
const char* GetStringResource(int resource_id);
// Contains information about a JavaScript context that is hosting extension
// bindings.
struct ContextInfo {
......@@ -113,6 +57,10 @@ ContextList::iterator FindContext(v8::Handle<v8::Context> context);
// Returns the ContextInfo for the current v8 context.
ContextInfo* GetInfoForCurrentContext();
// Returns the 'chromeHidden' object for the specified context.
v8::Handle<v8::Object> GetChromeHiddenForContext(
v8::Handle<v8::Context> context);
// Contains info relevant to a pending API request.
struct PendingRequest {
public :
......
......@@ -15,6 +15,7 @@
#include "chrome/renderer/chrome_render_process_observer.h"
#include "chrome/renderer/extensions/bindings_utils.h"
#include "chrome/renderer/extensions/event_bindings.h"
#include "chrome/renderer/extensions/extension_base.h"
#include "chrome/renderer/extensions/extension_dispatcher.h"
#include "chrome/renderer/extensions/extension_process_bindings.h"
#include "chrome/renderer/extensions/js_only_v8_extensions.h"
......@@ -37,8 +38,6 @@ using bindings_utils::ContextInfo;
using bindings_utils::ContextList;
using bindings_utils::GetContexts;
using bindings_utils::GetInfoForCurrentContext;
using bindings_utils::GetStringResource;
using bindings_utils::ExtensionBase;
using bindings_utils::GetPendingRequestMap;
using bindings_utils::PendingRequestMap;
using WebKit::WebDataSource;
......
......@@ -8,6 +8,7 @@
#include "base/path_service.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/renderer/extensions/bindings_utils.h"
#include "chrome/renderer/extensions/extension_base.h"
#include "chrome/test/base/v8_unit_test.h"
#include "content/common/json_value_serializer.h"
#include "grit/common_resources.h"
......@@ -130,7 +131,7 @@ TEST_F(ExtensionApiJsonValidityTest, Basic) {
// chrome/renderer/resources/extension_process_bindings.js .
TEST_F(ExtensionApiJsonValidityTest, MAYBE_WithV8) {
std::string ext_api_string =
bindings_utils::GetStringResource(IDR_EXTENSION_API_JSON);
ExtensionBase::GetStringResource(IDR_EXTENSION_API_JSON);
// Create a global variable holding the text of extension_api.json .
SetGlobalStringVar("ext_api_json_text", ext_api_string);
......
// 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.
#include "chrome/renderer/extensions/extension_base.h"
#include "base/logging.h"
#include "base/lazy_instance.h"
#include "base/stringprintf.h"
#include "base/string_util.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_set.h"
#include "chrome/renderer/extensions/bindings_utils.h"
#include "chrome/renderer/extensions/extension_dispatcher.h"
#include "content/renderer/render_view.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "ui/base/resource/resource_bundle.h"
#include "v8/include/v8.h"
using WebKit::WebFrame;
using WebKit::WebView;
namespace {
typedef std::map<int, std::string> StringMap;
static base::LazyInstance<StringMap> g_string_map(base::LINKER_INITIALIZED);
}
// static
const char* ExtensionBase::GetStringResource(int resource_id) {
StringMap* strings = g_string_map.Pointer();
StringMap::iterator it = strings->find(resource_id);
if (it == strings->end()) {
it = strings->insert(std::make_pair(
resource_id,
ResourceBundle::GetSharedInstance().GetRawDataResource(
resource_id).as_string())).first;
}
return it->second.c_str();
}
const Extension* ExtensionBase::GetExtensionForCurrentContext() const {
RenderView* renderview = bindings_utils::GetRenderViewForCurrentContext();
if (!renderview)
return NULL; // this can happen as a tab is closing.
GURL url = renderview->webview()->mainFrame()->document().url();
const ExtensionSet* extensions = extension_dispatcher_->extensions();
if (!extensions->ExtensionBindingsAllowed(url))
return NULL;
return extensions->GetByURL(url);
}
bool ExtensionBase::CheckPermissionForCurrentContext(
const std::string& function_name) const {
const ::Extension* extension = GetExtensionForCurrentContext();
if (extension &&
extension_dispatcher_->IsExtensionActive(extension->id()) &&
extension->HasAPIPermission(function_name))
return true;
static const char kMessage[] =
"You do not have permission to use '%s'. Be sure to declare"
" in your manifest what permissions you need.";
std::string error_msg = base::StringPrintf(kMessage, function_name.c_str());
v8::ThrowException(v8::Exception::Error(v8::String::New(error_msg.c_str())));
return false;
}
v8::Handle<v8::FunctionTemplate>
ExtensionBase::GetNativeFunction(v8::Handle<v8::String> name) {
if (name->Equals(v8::String::New("GetChromeHidden"))) {
return v8::FunctionTemplate::New(GetChromeHidden);
}
if (name->Equals(v8::String::New("Print"))) {
return v8::FunctionTemplate::New(Print);
}
return v8::Handle<v8::FunctionTemplate>();
}
v8::Handle<v8::Value> ExtensionBase::GetChromeHidden(
const v8::Arguments& args) {
return bindings_utils::GetChromeHiddenForContext(v8::Context::GetCurrent());
}
v8::Handle<v8::Value> ExtensionBase::Print(const v8::Arguments& args) {
if (args.Length() < 1)
return v8::Undefined();
std::vector<std::string> components;
for (int i = 0; i < args.Length(); ++i)
components.push_back(*v8::String::Utf8Value(args[i]->ToString()));
LOG(ERROR) << JoinString(components, ',');
return v8::Undefined();
}
// 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.
#ifndef CHROME_RENDERER_EXTENSIONS_EXTENSION_BASE_H_
#define CHROME_RENDERER_EXTENSIONS_EXTENSION_BASE_H_
#pragma once
#include "base/logging.h"
#include "v8/include/v8.h"
#include <string>
class Extension;
class ExtensionDispatcher;
class RenderView;
namespace WebKit {
class WebFrame;
}
// This is a base class for chrome extension bindings. Common features that
// are shared by different modules go here.
class ExtensionBase : public v8::Extension {
public:
static const char* GetStringResource(int resource_id);
ExtensionBase(const char* name,
const char* source,
int dep_count,
const char** deps,
ExtensionDispatcher* extension_dispatcher)
: v8::Extension(name, source, dep_count, deps),
extension_dispatcher_(extension_dispatcher) {
}
// Derived classes should call this at the end of their implementation in
// order to expose common native functions, like GetChromeHidden, to the
// v8 extension.
virtual v8::Handle<v8::FunctionTemplate>
GetNativeFunction(v8::Handle<v8::String> name);
// TODO(jstritar): Used for testing http://crbug.com/91582. Remove when done.
ExtensionDispatcher* extension_dispatcher() { return extension_dispatcher_; }
protected:
template<class T>
static T* GetFromArguments(const v8::Arguments& args) {
CHECK(!args.Data().IsEmpty());
T* result = static_cast<T*>(args.Data().As<v8::External>()->Value());
return result;
}
// Note: do not call this function before or during the chromeHidden.onLoad
// event dispatch. The URL might not have been committed yet and might not
// be an extension URL.
const ::Extension* GetExtensionForCurrentContext() const;
// Checks that the current context contains an extension that has permission
// to execute the specified function. If it does not, a v8 exception is thrown
// and the method returns false. Otherwise returns true.
bool CheckPermissionForCurrentContext(const std::string& function_name) const;
// Returns a hidden variable for use by the bindings that is unreachable
// by the page.
static v8::Handle<v8::Value> GetChromeHidden(const v8::Arguments& args);
ExtensionDispatcher* extension_dispatcher_;
private:
// Helper to print from bindings javascript.
static v8::Handle<v8::Value> Print(const v8::Arguments& args);
};
#endif // CHROME_RENDERER_EXTENSIONS_EXTENSION_BASE_H_
......@@ -25,6 +25,7 @@
#include "chrome/renderer/chrome_render_process_observer.h"
#include "chrome/renderer/extensions/bindings_utils.h"
#include "chrome/renderer/extensions/event_bindings.h"
#include "chrome/renderer/extensions/extension_base.h"
#include "chrome/renderer/extensions/extension_dispatcher.h"
#include "chrome/renderer/extensions/extension_helper.h"
#include "chrome/renderer/extensions/js_only_v8_extensions.h"
......@@ -41,11 +42,9 @@
#include "third_party/skia/include/core/SkColor.h"
#include "webkit/glue/webkit_glue.h"
using bindings_utils::GetStringResource;
using bindings_utils::GetPendingRequestMap;
using bindings_utils::PendingRequest;
using bindings_utils::PendingRequestMap;
using bindings_utils::ExtensionBase;
using WebKit::WebFrame;
using WebKit::WebView;
......
......@@ -4,25 +4,23 @@
#include "chrome/renderer/extensions/js_only_v8_extensions.h"
#include "chrome/renderer/extensions/bindings_utils.h"
#include "chrome/renderer/extensions/extension_base.h"
#include "grit/renderer_resources.h"
using bindings_utils::GetStringResource;
// JsonSchemaJsV8Extension
const char* JsonSchemaJsV8Extension::kName = "chrome/jsonschema";
v8::Extension* JsonSchemaJsV8Extension::Get() {
static v8::Extension* extension =
new bindings_utils::ExtensionBase(
kName, GetStringResource(IDR_JSON_SCHEMA_JS), 0, NULL, NULL);
static v8::Extension* extension = new ExtensionBase(
kName, ExtensionBase::GetStringResource(IDR_JSON_SCHEMA_JS), 0, NULL,
NULL);
return extension;
}
// ExtensionApiTestV8Extension
const char* ExtensionApiTestV8Extension::kName = "chrome/extensionapitest";
v8::Extension* ExtensionApiTestV8Extension::Get() {
static v8::Extension* extension =
new bindings_utils::ExtensionBase(
kName, GetStringResource(IDR_EXTENSION_APITEST_JS), 0, NULL, NULL);
static v8::Extension* extension = new ExtensionBase(
kName, ExtensionBase::GetStringResource(IDR_EXTENSION_APITEST_JS), 0,
NULL, NULL);
return extension;
}
......@@ -14,14 +14,12 @@
#include "chrome/common/url_constants.h"
#include "chrome/renderer/extensions/bindings_utils.h"
#include "chrome/renderer/extensions/event_bindings.h"
#include "chrome/renderer/extensions/extension_base.h"
#include "chrome/renderer/extensions/extension_dispatcher.h"
#include "content/renderer/render_thread.h"
#include "content/renderer/render_view.h"
#include "grit/renderer_resources.h"
using bindings_utils::GetStringResource;
using bindings_utils::ExtensionBase;
// Message passing API example (in a content script):
// var extension =
// new chrome.Extension('00123456789abcdef0123456789abcdef0123456');
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment