Chromium Code Reviews| Index: extensions/renderer/api_binding_hooks.cc |
| diff --git a/extensions/renderer/api_binding_hooks.cc b/extensions/renderer/api_binding_hooks.cc |
| index c4bc12c42ccd07ca1ad15c64c43003480d421830..79d8037b2ede9dd9e1fbb794ec7e4a7a5f17282c 100644 |
| --- a/extensions/renderer/api_binding_hooks.cc |
| +++ b/extensions/renderer/api_binding_hooks.cc |
| @@ -33,12 +33,15 @@ class JSHookInterface final : public gin::Wrappable<JSHookInterface> { |
| return Wrappable<JSHookInterface>::GetObjectTemplateBuilder(isolate) |
| .SetMethod("setHandleRequest", &JSHookInterface::SetHandleRequest) |
| .SetMethod("setUpdateArgumentsPreValidate", |
| - &JSHookInterface::SetUpdateArgumentsPreValidate); |
| + &JSHookInterface::SetUpdateArgumentsPreValidate) |
| + .SetMethod("setUpdateArgumentsPostValidate", |
| + &JSHookInterface::SetUpdateArgumentsPostValidate); |
| } |
| void ClearHooks() { |
| handle_request_hooks_.clear(); |
| pre_validation_hooks_.clear(); |
| + post_validation_hooks_.clear(); |
| } |
| v8::Local<v8::Function> GetHandleRequestHook(const std::string& method_name, |
| @@ -51,6 +54,11 @@ class JSHookInterface final : public gin::Wrappable<JSHookInterface> { |
| return GetHookFromMap(pre_validation_hooks_, method_name, isolate); |
| } |
| + v8::Local<v8::Function> GetPostValidationHook(const std::string& method_name, |
| + v8::Isolate* isolate) const { |
| + return GetHookFromMap(post_validation_hooks_, method_name, isolate); |
| + } |
| + |
| private: |
| using JSHooks = std::map<std::string, v8::Global<v8::Function>>; |
| @@ -92,10 +100,17 @@ class JSHookInterface final : public gin::Wrappable<JSHookInterface> { |
| AddHookToMap(&pre_validation_hooks_, isolate, method_name, hook); |
| } |
| + void SetUpdateArgumentsPostValidate(v8::Isolate* isolate, |
| + const std::string& method_name, |
| + v8::Local<v8::Function> hook) { |
| + AddHookToMap(&post_validation_hooks_, isolate, method_name, hook); |
| + } |
| + |
| std::string api_name_; |
| JSHooks handle_request_hooks_; |
| JSHooks pre_validation_hooks_; |
| + JSHooks post_validation_hooks_; |
| DISALLOW_COPY_AND_ASSIGN(JSHookInterface); |
| }; |
| @@ -185,7 +200,7 @@ void APIBindingHooks::RegisterJsSource(v8::Global<v8::String> source, |
| js_resource_name_ = std::move(resource_name); |
| } |
| -APIBindingHooks::RequestResult APIBindingHooks::HandleRequest( |
| +APIBindingHooks::RequestResult APIBindingHooks::RunHooks( |
| const std::string& api_name, |
| const std::string& method_name, |
| v8::Local<v8::Context> context, |
| @@ -232,9 +247,17 @@ APIBindingHooks::RequestResult APIBindingHooks::HandleRequest( |
| } |
| } |
| + v8::Local<v8::Function> post_validate_hook = |
| + hook_interface->GetPostValidationHook(method_name, isolate); |
| v8::Local<v8::Function> handle_request = |
| hook_interface->GetHandleRequestHook(method_name, isolate); |
| - if (!handle_request.IsEmpty()) { |
| + // If both the post validation hook and the handle request hook are empty, |
| + // we're done... |
| + if (post_validate_hook.IsEmpty() && handle_request.IsEmpty()) |
| + return RequestResult(RequestResult::NOT_HANDLED); |
| + |
| + { |
| + // ... otherwise, we have to validate the arguments. |
| v8::TryCatch try_catch(isolate); |
| std::vector<v8::Local<v8::Value>> parsed_v8_args; |
| std::string error; |
| @@ -246,21 +269,33 @@ APIBindingHooks::RequestResult APIBindingHooks::HandleRequest( |
| } |
| if (!success) |
| return RequestResult(RequestResult::INVALID_INVOCATION); |
| + arguments->swap(parsed_v8_args); |
| + } |
| - v8::Global<v8::Value> global_result = |
| - run_js_.Run(handle_request, context, parsed_v8_args.size(), |
| - parsed_v8_args.data()); |
| + if (!post_validate_hook.IsEmpty()) { |
| + v8::TryCatch try_catch(isolate); |
|
jbroman
2017/01/11 20:01:48
nit: A thought here: I don't see any place here wh
Devlin
2017/01/13 17:11:58
Done.
|
| + UpdateArguments(post_validate_hook, context, arguments); |
| if (try_catch.HasCaught()) { |
| try_catch.ReThrow(); |
| return RequestResult(RequestResult::THROWN); |
| } |
| - RequestResult result(RequestResult::HANDLED); |
| - if (!global_result.IsEmpty()) |
| - result.return_value = global_result.Get(isolate); |
| - return result; |
| } |
| - return RequestResult(RequestResult::NOT_HANDLED); |
| + if (handle_request.IsEmpty()) |
| + return RequestResult(RequestResult::NOT_HANDLED); |
| + |
| + v8::TryCatch try_catch(isolate); |
| + v8::Global<v8::Value> global_result = |
| + run_js_.Run(handle_request, context, arguments->size(), |
| + arguments->data()); |
| + if (try_catch.HasCaught()) { |
| + try_catch.ReThrow(); |
| + return RequestResult(RequestResult::THROWN); |
| + } |
| + RequestResult result(RequestResult::HANDLED); |
| + if (!global_result.IsEmpty()) |
| + result.return_value = global_result.Get(isolate); |
| + return result; |
| } |
| void APIBindingHooks::InitializeInContext( |