Index: chrome/renderer/extensions/dispatcher.cc |
diff --git a/chrome/renderer/extensions/dispatcher.cc b/chrome/renderer/extensions/dispatcher.cc |
index a1fd9c5d3ef5f6f757ece3a37bf72c679fb7da49..bf6560f8da027476e862aa9a36cb729fbbcd32b2 100644 |
--- a/chrome/renderer/extensions/dispatcher.cc |
+++ b/chrome/renderer/extensions/dispatcher.cc |
@@ -726,64 +726,95 @@ void Dispatcher::RegisterSchemaGeneratedBindings( |
for (std::set<std::string>::iterator it = apis.begin(); |
it != apis.end(); ++it) { |
const std::string& api_name = *it; |
- if (!context->IsAnyFeatureAvailableToContext(api_name)) |
+ if (!context->IsAnyFeatureAvailableToContext(api_name)) { |
+ RemoveAPIBindingIfPresent(api_name, context); |
continue; |
+ } |
Feature* feature = |
BaseFeatureProvider::GetByName("api")->GetFeature(api_name); |
if (feature && feature->IsInternal()) |
continue; |
- std::vector<std::string> split; |
- base::SplitString(api_name, '.', &split); |
- |
- v8::Handle<v8::Object> bind_object = |
- GetOrCreateChrome(context->v8_context()); |
- |
- // Check if this API has an ancestor. If the API's ancestor is available and |
- // the API is not available, don't install the bindings for this API. If |
- // the API is available and its ancestor is not, delete the ancestor and |
- // install the bindings for the API. This is to prevent loading the ancestor |
- // API schema if it will not be needed. |
- // |
- // For example: |
- // If app is available and app.window is not, just install app. |
- // If app.window is available and app is not, delete app and install |
- // app.window on a new object so app does not have to be loaded. |
- std::string ancestor_name; |
- bool only_ancestor_available = false; |
- for (size_t i = 0; i < split.size() - 1; ++i) { |
- ancestor_name += (i ? ".": "") + split[i]; |
- if (!ancestor_name.empty() && |
- context->GetAvailability(ancestor_name).is_available() && |
- !context->GetAvailability(api_name).is_available()) { |
- only_ancestor_available = true; |
- break; |
- } |
- bind_object = GetOrCreateObject(bind_object, split[i]); |
- } |
- if (only_ancestor_available) |
- continue; |
+ RegisterBinding(api_name, module_system, context); |
+ } |
+} |
- if (lazy_bindings_map_.find(api_name) != lazy_bindings_map_.end()) { |
- InstallBindings(module_system, context->v8_context(), api_name); |
- } else if (!source_map_.Contains(api_name)) { |
- module_system->RegisterNativeHandler( |
- api_name, |
- scoped_ptr<NativeHandler>(new BindingGeneratingNativeHandler( |
- module_system, |
- api_name, |
- "binding"))); |
- module_system->SetNativeLazyField(bind_object, |
- split.back(), |
- api_name, |
- "binding"); |
- } else { |
- module_system->SetLazyField(bind_object, |
- split.back(), |
- api_name, |
- "binding"); |
+void Dispatcher::RemoveAPIBindingIfPresent(const std::string& api_name, |
not at google - send to devlin
2013/05/31 16:35:00
Maybe DeregisterBinding as a parallel to RegisterB
cduvall
2013/06/05 03:05:56
Done.
|
+ ChromeV8Context* context) { |
+ std::string bind_name; |
+ v8::Handle<v8::Object> bind_object = |
+ GetBindObject(api_name, &bind_name, context); |
+ if (bind_object->HasRealNamedProperty(v8::String::New(bind_name.c_str()))) { |
+ bind_object->Delete(v8::String::New(bind_name.c_str())); |
not at google - send to devlin
2013/05/31 16:35:00
save a reference to the v8::String::New here.
cduvall
2013/06/05 03:05:56
Done.
|
+ } |
not at google - send to devlin
2013/05/31 16:35:00
no {}
cduvall
2013/06/05 03:05:56
Done.
|
+} |
+ |
+v8::Handle<v8::Object> Dispatcher::GetBindObject(const std::string& api_name, |
+ std::string* bind_name, |
not at google - send to devlin
2013/05/31 16:35:00
this is really GetOrCreateBindObject, though maybe
cduvall
2013/06/05 03:05:56
Done.
|
+ ChromeV8Context* context) { |
+ v8::HandleScope handle_scope; |
+ std::vector<std::string> split; |
+ base::SplitString(api_name, '.', &split); |
+ |
+ v8::Handle<v8::Object> bind_object = GetOrCreateChrome(context->v8_context()); |
not at google - send to devlin
2013/05/31 16:35:00
I think you'll need to move this to after the avai
cduvall
2013/06/05 03:05:56
Done.
|
+ |
+ // Check if this API has an ancestor. If the API's ancestor is available and |
+ // the API is not available, don't install the bindings for this API. If |
+ // the API is available and its ancestor is not, delete the ancestor and |
+ // install the bindings for the API. This is to prevent loading the ancestor |
+ // API schema if it will not be needed. |
+ // |
+ // For example: |
+ // If app is available and app.window is not, just install app. |
+ // If app.window is available and app is not, delete app and install |
+ // app.window on a new object so app does not have to be loaded. |
+ std::string ancestor_name; |
+ bool only_ancestor_available = false; |
+ for (size_t i = 0; i < split.size() - 1; ++i) { |
+ ancestor_name += (i ? ".": "") + split[i]; |
+ if (!ancestor_name.empty() && |
+ context->GetAvailability(ancestor_name).is_available() && |
+ !context->GetAvailability(api_name).is_available()) { |
+ only_ancestor_available = true; |
+ break; |
} |
+ bind_object = GetOrCreateObject(bind_object, split[i]); |
+ } |
+ if (only_ancestor_available) |
+ return handle_scope.Close(v8::Handle<v8::Object>()); |
+ if (bind_name) |
+ *bind_name = split.back(); |
+ return handle_scope.Close(bind_object); |
+} |
+ |
+void Dispatcher::RegisterBinding(const std::string& api_name, |
+ ModuleSystem* module_system, |
+ ChromeV8Context* context) { |
+ std::string bind_name; |
+ v8::Handle<v8::Object> bind_object = |
+ GetBindObject(api_name, &bind_name, context); |
+ if (bind_object.IsEmpty()) |
+ return; |
+ |
+ if (lazy_bindings_map_.find(api_name) != lazy_bindings_map_.end()) { |
+ InstallBindings(module_system, context->v8_context(), api_name); |
+ } else if (!source_map_.Contains(api_name)) { |
+ module_system->RegisterNativeHandler( |
+ api_name, |
+ scoped_ptr<NativeHandler>(new BindingGeneratingNativeHandler( |
+ module_system, |
+ api_name, |
+ "binding"))); |
+ module_system->SetNativeLazyField(bind_object, |
+ bind_name, |
+ api_name, |
+ "binding"); |
+ } else { |
+ module_system->SetLazyField(bind_object, |
+ bind_name, |
+ api_name, |
+ "binding"); |
} |
} |
@@ -1253,6 +1284,16 @@ void Dispatcher::AddOrRemoveOriginPermissions( |
} |
} |
+void Dispatcher::RefreshSchemaGeneratedBindings() { |
+ v8::HandleScope handle_scope; |
+ CHECK(v8_context_set().size()); |
+ // TODO(cduvall): This is wrong. Not sure what to do. |
cduvall
2013/05/31 03:06:34
I'm not sure how to get the right context to regis
not at google - send to devlin
2013/05/31 16:35:00
Ah right, yeah. So what you want is this:
https:/
cduvall
2013/06/05 03:05:56
So I added in the v8_context_set_.ForEach(), but I
not at google - send to devlin
2013/06/05 19:03:44
It may be the lack of an is_valid check in ChromeV
cduvall
2013/06/05 23:27:59
Looks like the is_valid() check didn't fix the pro
|
+ ChromeV8Context* context = *v8_context_set().GetAll().begin(); |
+ context->v8_context()->Enter(); |
+ RegisterSchemaGeneratedBindings(context->module_system(), context); |
+ context->v8_context()->Exit(); |
not at google - send to devlin
2013/05/31 16:35:00
use v8::Context::Scope here, and move into Registe
cduvall
2013/06/05 03:05:56
Done.
|
+} |
+ |
void Dispatcher::OnUpdatePermissions(int reason_id, |
const std::string& extension_id, |
const APIPermissionSet& apis, |
@@ -1281,6 +1322,7 @@ void Dispatcher::OnUpdatePermissions(int reason_id, |
PermissionsData::SetActivePermissions(extension, new_active); |
AddOrRemoveOriginPermissions(reason, extension, explicit_hosts); |
+ RefreshSchemaGeneratedBindings(); |
} |
void Dispatcher::OnUpdateTabSpecificPermissions( |