• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef INTERFACE_KITS_JS_NAPI_INPUTMETHODENGINE_INCLUDE_JS_TEXT_INPUT_CLIENT_H
16 #define INTERFACE_KITS_JS_NAPI_INPUTMETHODENGINE_INCLUDE_JS_TEXT_INPUT_CLIENT_H
17 
18 #include "async_call.h"
19 #include "global.h"
20 #include "native_engine/native_engine.h"
21 #include "native_engine/native_value.h"
22 #include "block_queue.h"
23 
24 namespace OHOS {
25 namespace MiscServices {
26 enum class EditorEvent : uint32_t {
27     INSERT_TEXT = 0,
28     DELETE_FORWARD,
29     DELETE_BACKWARD,
30     MOVE_CURSOR,
31     SELECT_BY_RANGE,
32     SELECT_BY_MOVEMENT,
33     SEND_EXTEND_ACTION,
34     GET_FORWARD,
35     GET_BACKWARD,
36     GET_TEXT_INDEX_AT_CURSOR,
37     EVENT_END,
38 };
39 struct EditorEventInfo {
40     std::chrono::system_clock::time_point timestamp{};
41     EditorEvent event{ EditorEvent::EVENT_END };
42     bool operator==(const EditorEventInfo &info) const
43     {
44         return (timestamp == info.timestamp && event == info.event);
45     }
46 };
47 struct SendKeyFunctionContext : public AsyncCall::Context {
48     bool isSendKeyFunction = false;
49     int32_t action = 0;
50     napi_status status = napi_generic_failure;
SendKeyFunctionContextSendKeyFunctionContext51     SendKeyFunctionContext() : Context(nullptr, nullptr){};
SendKeyFunctionContextSendKeyFunctionContext52     SendKeyFunctionContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
53 
operatorSendKeyFunctionContext54     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
55     {
56         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
57         return Context::operator()(env, argc, argv, self);
58     }
59 
operatorSendKeyFunctionContext60     napi_status operator()(napi_env env, napi_value *result) override
61     {
62         if (status != napi_ok) {
63             output_ = nullptr;
64             return status;
65         }
66         return Context::operator()(env, result);
67     }
68 };
69 
70 struct MoveCursorContext : public AsyncCall::Context {
71     int32_t num = 0;
72     EditorEventInfo info;
73     napi_status status = napi_generic_failure;
MoveCursorContextMoveCursorContext74     MoveCursorContext() : Context(nullptr, nullptr){};
MoveCursorContextMoveCursorContext75     MoveCursorContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
76 
operatorMoveCursorContext77     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
78     {
79         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
80         return Context::operator()(env, argc, argv, self);
81     }
operatorMoveCursorContext82     napi_status operator()(napi_env env, napi_value *result) override
83     {
84         if (status != napi_ok) {
85             output_ = nullptr;
86             return status;
87         }
88         return Context::operator()(env, result);
89     }
90 };
91 
92 struct DeleteForwardContext : public AsyncCall::Context {
93     bool isDeleteForward = false;
94     int32_t length = 0;
95     EditorEventInfo info;
96     napi_status status = napi_generic_failure;
DeleteForwardContextDeleteForwardContext97     DeleteForwardContext() : Context(nullptr, nullptr){};
DeleteForwardContextDeleteForwardContext98     DeleteForwardContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
99 
operatorDeleteForwardContext100     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
101     {
102         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
103         return Context::operator()(env, argc, argv, self);
104     }
operatorDeleteForwardContext105     napi_status operator()(napi_env env, napi_value *result) override
106     {
107         if (status != napi_ok) {
108             output_ = nullptr;
109             return status;
110         }
111         return Context::operator()(env, result);
112     }
113 };
114 
115 struct DeleteBackwardContext : public AsyncCall::Context {
116     bool isDeleteBackward = false;
117     int32_t length = 0;
118     EditorEventInfo info;
119     napi_status status = napi_generic_failure;
DeleteBackwardContextDeleteBackwardContext120     DeleteBackwardContext() : Context(nullptr, nullptr){};
DeleteBackwardContextDeleteBackwardContext121     DeleteBackwardContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
122 
operatorDeleteBackwardContext123     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
124     {
125         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
126         return Context::operator()(env, argc, argv, self);
127     }
operatorDeleteBackwardContext128     napi_status operator()(napi_env env, napi_value *result) override
129     {
130         if (status != napi_ok) {
131             output_ = nullptr;
132             return status;
133         }
134         return Context::operator()(env, result);
135     }
136 };
137 
138 struct InsertTextContext : public AsyncCall::Context {
139     bool isInsertText = false;
140     std::string text;
141     EditorEventInfo info;
142     napi_status status = napi_generic_failure;
InsertTextContextInsertTextContext143     InsertTextContext() : Context(nullptr, nullptr){};
InsertTextContextInsertTextContext144     InsertTextContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
145 
operatorInsertTextContext146     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
147     {
148         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
149         return Context::operator()(env, argc, argv, self);
150     }
operatorInsertTextContext151     napi_status operator()(napi_env env, napi_value *result) override
152     {
153         if (status != napi_ok) {
154             output_ = nullptr;
155             return status;
156         }
157         return Context::operator()(env, result);
158     }
159 };
160 
161 struct GetForwardContext : public AsyncCall::Context {
162     int32_t length = 0;
163     std::string text;
164     EditorEventInfo info;
165     napi_status status = napi_generic_failure;
GetForwardContextGetForwardContext166     GetForwardContext() : Context(nullptr, nullptr){};
GetForwardContextGetForwardContext167     GetForwardContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
168 
operatorGetForwardContext169     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
170     {
171         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
172         return Context::operator()(env, argc, argv, self);
173     }
operatorGetForwardContext174     napi_status operator()(napi_env env, napi_value *result) override
175     {
176         if (status != napi_ok) {
177             output_ = nullptr;
178             return status;
179         }
180         return Context::operator()(env, result);
181     }
182 };
183 
184 struct GetBackwardContext : public AsyncCall::Context {
185     int32_t length = 0;
186     std::string text;
187     EditorEventInfo info;
188     napi_status status = napi_generic_failure;
GetBackwardContextGetBackwardContext189     GetBackwardContext() : Context(nullptr, nullptr){};
GetBackwardContextGetBackwardContext190     GetBackwardContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
191 
operatorGetBackwardContext192     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
193     {
194         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
195         return Context::operator()(env, argc, argv, self);
196     }
operatorGetBackwardContext197     napi_status operator()(napi_env env, napi_value *result) override
198     {
199         if (status != napi_ok) {
200             output_ = nullptr;
201             return status;
202         }
203         return Context::operator()(env, result);
204     }
205 };
206 
207 struct GetEditorAttributeContext : public AsyncCall::Context {
208     int32_t inputPattern = 0;
209     int32_t enterKeyType = 0;
210     napi_status status = napi_generic_failure;
GetEditorAttributeContextGetEditorAttributeContext211     GetEditorAttributeContext() : Context(nullptr, nullptr){};
GetEditorAttributeContextGetEditorAttributeContext212     GetEditorAttributeContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
213 
operatorGetEditorAttributeContext214     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
215     {
216         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
217         return Context::operator()(env, argc, argv, self);
218     }
operatorGetEditorAttributeContext219     napi_status operator()(napi_env env, napi_value *result) override
220     {
221         if (status != napi_ok) {
222             output_ = nullptr;
223             return status;
224         }
225         return Context::operator()(env, result);
226     }
227 };
228 
229 struct SelectContext : public AsyncCall::Context {
230     int32_t start = 0;
231     int32_t end = 0;
232     int32_t direction = 0;
233     EditorEventInfo info;
234     napi_status status = napi_generic_failure;
SelectContextSelectContext235     SelectContext() : Context(nullptr, nullptr){};
SelectContextSelectContext236     SelectContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
operatorSelectContext237     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
238     {
239         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
240         return Context::operator()(env, argc, argv, self);
241     }
operatorSelectContext242     napi_status operator()(napi_env env, napi_value *result) override
243     {
244         if (status != napi_ok) {
245             output_ = nullptr;
246             return status;
247         }
248         return Context::operator()(env, result);
249     }
250 };
251 
252 struct GetTextIndexAtCursorContext : public AsyncCall::Context {
253     int32_t index = 0;
254     EditorEventInfo info;
255     napi_status status = napi_generic_failure;
GetTextIndexAtCursorContextGetTextIndexAtCursorContext256     GetTextIndexAtCursorContext() : Context(nullptr, nullptr){};
GetTextIndexAtCursorContextGetTextIndexAtCursorContext257     GetTextIndexAtCursorContext(InputAction input, OutputAction output)
258         : Context(std::move(input), std::move(output)){};
259 
operatorGetTextIndexAtCursorContext260     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
261     {
262         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
263         return Context::operator()(env, argc, argv, self);
264     }
operatorGetTextIndexAtCursorContext265     napi_status operator()(napi_env env, napi_value *result) override
266     {
267         if (status != napi_ok) {
268             output_ = nullptr;
269             return status;
270         }
271         return Context::operator()(env, result);
272     }
273 };
274 
275 struct SendExtendActionContext : public AsyncCall::Context {
276     int32_t action = 0;
277     EditorEventInfo info;
SendExtendActionContextSendExtendActionContext278     SendExtendActionContext() : Context(nullptr, nullptr) {};
SendExtendActionContextSendExtendActionContext279     SendExtendActionContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)) {};
280 
operatorSendExtendActionContext281     napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
282     {
283         CHECK_RETURN(self != nullptr, "self is nullptr", napi_invalid_arg);
284         return Context::operator()(env, argc, argv, self);
285     }
operatorSendExtendActionContext286     napi_status operator()(napi_env env, napi_value *result) override
287     {
288         if (status_ != napi_ok) {
289             output_ = nullptr;
290             return status_;
291         }
292         return Context::operator()(env, result);
293     }
294 };
295 
296 class JsTextInputClientEngine {
297 public:
298     JsTextInputClientEngine() = default;
299     ~JsTextInputClientEngine() = default;
300     static napi_value Init(napi_env env, napi_value info);
301     static napi_value SendKeyFunction(napi_env env, napi_callback_info info);
302     static napi_value DeleteForward(napi_env env, napi_callback_info info);
303     static napi_value DeleteBackward(napi_env env, napi_callback_info info);
304     static napi_value InsertText(napi_env env, napi_callback_info info);
305     static napi_value GetForward(napi_env env, napi_callback_info info);
306     static napi_value GetBackward(napi_env env, napi_callback_info info);
307     static napi_value MoveCursor(napi_env env, napi_callback_info info);
308     static napi_value GetEditorAttribute(napi_env env, napi_callback_info info);
309     static napi_value GetTextIndexAtCursor(napi_env env, napi_callback_info info);
310     static napi_value GetTextInputClientInstance(napi_env env);
311     static napi_value SelectByRange(napi_env env, napi_callback_info info);
312     static napi_value SelectByMovement(napi_env env, napi_callback_info info);
313     static napi_value SendExtendAction(napi_env env, napi_callback_info info);
314     static napi_value InsertTextSync(napi_env env, napi_callback_info info);
315     static napi_value MoveCursorSync(napi_env env, napi_callback_info info);
316     static napi_value GetEditorAttributeSync(napi_env env, napi_callback_info info);
317     static napi_value SelectByRangeSync(napi_env env, napi_callback_info info);
318     static napi_value SelectByMovementSync(napi_env env, napi_callback_info info);
319     static napi_value GetTextIndexAtCursorSync(napi_env env, napi_callback_info info);
320     static napi_value DeleteForwardSync(napi_env env, napi_callback_info info);
321     static napi_value DeleteBackwardSync(napi_env env, napi_callback_info info);
322     static napi_value GetForwardSync(napi_env env, napi_callback_info info);
323     static napi_value GetBackwardSync(napi_env env, napi_callback_info info);
324 
325 private:
326     static napi_status GetSelectRange(napi_env env, napi_value argv, std::shared_ptr<SelectContext> ctxt);
327     static napi_status GetSelectMovement(napi_env env, napi_value argv, std::shared_ptr<SelectContext> ctxt);
328 
329     static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo);
330     static napi_value GetResult(napi_env env, std::string &text);
331     static napi_value GetResultEditorAttribute(
332         napi_env env, std::shared_ptr<GetEditorAttributeContext> getEditorAttribute);
333     static void PrintEditorQueueInfoIfTimeout(int64_t start, const EditorEventInfo &currentInfo);
334 
335     static const std::string TIC_CLASS_NAME;
336     static thread_local napi_ref TICRef_;
337     static constexpr std::int32_t MAX_VALUE_LEN = 4096;
338     static BlockQueue<EditorEventInfo> editorQueue_;
339 };
340 } // namespace MiscServices
341 } // namespace OHOS
342 #endif // INTERFACE_KITS_JS_NAPI_INPUTMETHODENGINE_INCLUDE_JS_TEXT_INPUT_CLIENT_H