1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef EXTENSIONS_RENDERER_BINDINGS_API_BINDING_JS_UTIL_H_
6 #define EXTENSIONS_RENDERER_BINDINGS_API_BINDING_JS_UTIL_H_
7 
8 #include <string>
9 
10 #include "base/macros.h"
11 #include "gin/wrappable.h"
12 #include "v8/include/v8.h"
13 
14 namespace gin {
15 class Arguments;
16 }
17 
18 namespace extensions {
19 class APIEventHandler;
20 class APIRequestHandler;
21 class APITypeReferenceMap;
22 class ExceptionHandler;
23 
24 // An object that exposes utility methods to the existing JS bindings, such as
25 // sendRequest and registering event argument massagers. If/when we get rid of
26 // some of our JS bindings, we can reduce or remove this class.
27 class APIBindingJSUtil final : public gin::Wrappable<APIBindingJSUtil> {
28  public:
29   APIBindingJSUtil(APITypeReferenceMap* type_refs,
30                    APIRequestHandler* request_handler,
31                    APIEventHandler* event_handler,
32                    ExceptionHandler* exception_handler);
33   ~APIBindingJSUtil() override;
34 
35   static gin::WrapperInfo kWrapperInfo;
36 
37   // gin::Wrappable:
38   gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
39       v8::Isolate* isolate) final;
40 
41  private:
42   // A handler to initiate an API request through the APIRequestHandler. A
43   // replacement for custom bindings that utilize require('sendRequest').
44   void SendRequest(gin::Arguments* arguments,
45                    const std::string& name,
46                    const std::vector<v8::Local<v8::Value>>& request_args,
47                    v8::Local<v8::Value> options);
48 
49   // A handler to register an argument massager for a specific event.
50   // Replacement for event_bindings.registerArgumentMassager.
51   void RegisterEventArgumentMassager(gin::Arguments* arguments,
52                                      const std::string& event_name,
53                                      v8::Local<v8::Function> massager);
54 
55   // A handler to allow custom bindings to create custom extension API event
56   // objects (e.g. foo.onBar).
57   void CreateCustomEvent(gin::Arguments* arguments,
58                          v8::Local<v8::Value> v8_event_name,
59                          bool supports_filters,
60                          bool supports_lazy_listeners);
61 
62   // Creates a new declarative event.
63   void CreateCustomDeclarativeEvent(
64       gin::Arguments* arguments,
65       const std::string& event_name,
66       const std::vector<std::string>& actions_list,
67       const std::vector<std::string>& conditions_list,
68       int webview_instance_id);
69 
70   // Invalidates an event, removing its listeners and preventing any more from
71   // being added.
72   void InvalidateEvent(gin::Arguments* arguments, v8::Local<v8::Object> event);
73 
74   // Sets the last error in the context.
75   void SetLastError(gin::Arguments* arguments, const std::string& error);
76 
77   // Clears the last error in the context.
78   void ClearLastError(gin::Arguments* arguments);
79 
80   // Returns true if there is a set lastError in the given context.
81   void HasLastError(gin::Arguments* arguments);
82 
83   // Sets the lastError in the given context, runs the provided callback, and
84   // then clears the last error.
85   void RunCallbackWithLastError(gin::Arguments* arguments,
86                                 const std::string& error,
87                                 v8::Local<v8::Function> callback);
88 
89   // Handles an exception with the given |message| and |exception| value.
90   void HandleException(gin::Arguments* arguments,
91                        const std::string& message,
92                        v8::Local<v8::Value> exception);
93 
94   // Sets a custom exception handler to be used when an uncaught exception is
95   // found.
96   void SetExceptionHandler(gin::Arguments* arguments,
97                            v8::Local<v8::Function> handler);
98 
99   // Validates a given |value| against the specification for the type with
100   // |type_name|. Throws an error if the validation fails; otherwise returns
101   // undefined.
102   void ValidateType(gin::Arguments* arguments,
103                     const std::string& type_name,
104                     v8::Local<v8::Value> value);
105 
106   // Allows custom bindings to add a signature with the given
107   // |custom_signature_name| to use later in argument validation. The signature
108   // is expected to be an array of expected types, that can be passed to
109   // construct an APISignature.
110   void AddCustomSignature(gin::Arguments* arguments,
111                           const std::string& custom_signature_name,
112                           v8::Local<v8::Value> signature);
113 
114   // Looks up the signature with the given |custom_signature_name| and validates
115   // |arguments_to_validate| against it, throwing an error if the arguments
116   // don't match.
117   void ValidateCustomSignature(gin::Arguments* arguments,
118                                const std::string& custom_signature_name,
119                                v8::Local<v8::Value> arguments_to_validate);
120 
121   // Type references. Guaranteed to outlive this object.
122   APITypeReferenceMap* const type_refs_;
123 
124   // The request handler. Guaranteed to outlive this object.
125   APIRequestHandler* const request_handler_;
126 
127   // The event handler. Guaranteed to outlive this object.
128   APIEventHandler* const event_handler_;
129 
130   // The exception handler. Guaranteed to outlive this object.
131   ExceptionHandler* const exception_handler_;
132 
133   DISALLOW_COPY_AND_ASSIGN(APIBindingJSUtil);
134 };
135 
136 }  // namespace extensions
137 
138 #endif  // EXTENSIONS_RENDERER_BINDINGS_API_BINDING_JS_UTIL_H_
139