| 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..a6ee6ed2fea1779c4d2460f29cc51d7d29927b11 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,
|
| @@ -221,8 +236,8 @@ APIBindingHooks::RequestResult APIBindingHooks::HandleRequest(
|
|
|
| v8::Local<v8::Function> pre_validate_hook =
|
| hook_interface->GetPreValidationHook(method_name, isolate);
|
| + v8::TryCatch try_catch(isolate);
|
| if (!pre_validate_hook.IsEmpty()) {
|
| - v8::TryCatch try_catch(isolate);
|
| // TODO(devlin): What to do with the result of this function call? Can it
|
| // only fail in the case we've already thrown?
|
| UpdateArguments(pre_validate_hook, context, arguments);
|
| @@ -232,10 +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()) {
|
| - v8::TryCatch try_catch(isolate);
|
| + // 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.
|
| std::vector<v8::Local<v8::Value>> parsed_v8_args;
|
| std::string error;
|
| bool success = signature->ParseArgumentsToV8(context, *arguments, type_refs,
|
| @@ -246,21 +268,31 @@ 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()) {
|
| + 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::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(
|
|
|