1 /*
2  * Copyright (c) 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 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_native_rich_editor_bridge.h"
16 #include "bridge/declarative_frontend/engine/jsi/nativeModule/arkts_utils.h"
17 #include "bridge/declarative_frontend/jsview/js_richeditor.h"
18 #include "bridge/declarative_frontend/engine/jsi/jsi_types.h"
19 #include "bridge/declarative_frontend/jsview/js_utils.h"
20 #include "core/common/ace_application_info.h"
21 #include "core/components/common/layout/constants.h"
22 #include "core/components/common/properties/text_style_parser.h"
23 #include "core/components_ng/pattern/rich_editor/selection_info.h"
24 #include "core/components_ng/pattern/rich_editor/rich_editor_event_hub.h"
25 namespace OHOS::Ace::NG {
26 namespace {
27 constexpr int NUM_0 = 0;
28 constexpr int NUM_1 = 1;
29 constexpr int NUM_2 = 2;
30 constexpr int NUM_3 = 3;
31 constexpr int NUM_4 = 4;
32 constexpr int NUM_5 = 5;
33 constexpr int NUM_6 = 6;
34 const std::vector<std::string> TEXT_DETECT_TYPES = { "phoneNum", "url", "email", "location", "datetime" };
35 }
36 
SetEnableDataDetector(ArkUIRuntimeCallInfo * runtimeCallInfo)37 ArkUINativeModuleValue RichEditorBridge::SetEnableDataDetector(ArkUIRuntimeCallInfo* runtimeCallInfo)
38 {
39     EcmaVM* vm = runtimeCallInfo->GetVM();
40     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
41     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
42     Local<JSValueRef> enableDataDetectorArg = runtimeCallInfo->GetCallArgRef(NUM_1);
43     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
44     if (enableDataDetectorArg->IsNull() || enableDataDetectorArg->IsUndefined() ||
45         !enableDataDetectorArg->IsBoolean()) {
46         GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorEnableDataDetector(nativeNode);
47         return panda::JSValueRef::Undefined(vm);
48     }
49     uint32_t enableDataDetector = enableDataDetectorArg->Uint32Value(vm);
50     GetArkUINodeModifiers()->getRichEditorModifier()->setRichEditorEnableDataDetector(nativeNode, enableDataDetector);
51     return panda::JSValueRef::Undefined(vm);
52 }
53 
ResetEnableDataDetector(ArkUIRuntimeCallInfo * runtimeCallInfo)54 ArkUINativeModuleValue RichEditorBridge::ResetEnableDataDetector(ArkUIRuntimeCallInfo* runtimeCallInfo)
55 {
56     EcmaVM* vm = runtimeCallInfo->GetVM();
57     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
58     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
59     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
60     GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorEnableDataDetector(nativeNode);
61     return panda::JSValueRef::Undefined(vm);
62 }
63 
CreateParagraphStyle(EcmaVM * vm,const TextStyleResult & textStyleResult)64 Local<panda::ObjectRef> CreateParagraphStyle(EcmaVM *vm, const TextStyleResult& textStyleResult)
65 {
66     auto leadingMarginArray = panda::ArrayRef::New(vm);
67     panda::ArrayRef::SetValueAt(vm, leadingMarginArray, NUM_0,
68         panda::StringRef::NewFromUtf8(vm, textStyleResult.leadingMarginSize[NUM_0].c_str()));
69     panda::ArrayRef::SetValueAt(vm, leadingMarginArray, NUM_1,
70         panda::StringRef::NewFromUtf8(vm, textStyleResult.leadingMarginSize[NUM_1].c_str()));
71     const char* keys[] = { "textAlign", "leadingMargin" };
72     Local<JSValueRef> values[] = { panda::NumberRef::New(vm, textStyleResult.textAlign), leadingMarginArray };
73     auto returnObject = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
74     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
75         returnObject->Set(vm, panda::StringRef::NewFromUtf8(vm, "wordBreak"),
76             panda::NumberRef::New(vm, textStyleResult.wordBreak));
77         returnObject->Set(vm, panda::StringRef::NewFromUtf8(vm, "lineBreakStrategy"),
78             panda::NumberRef::New(vm, textStyleResult.lineBreakStrategy));
79     }
80     return returnObject;
81 }
82 
SetDataDetectorConfig(ArkUIRuntimeCallInfo * runtimeCallInfo)83 ArkUINativeModuleValue RichEditorBridge::SetDataDetectorConfig(ArkUIRuntimeCallInfo* runtimeCallInfo)
84 {
85     EcmaVM* vm = runtimeCallInfo->GetVM();
86     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
87     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
88     Local<JSValueRef> typesArg = runtimeCallInfo->GetCallArgRef(NUM_1);
89     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(NUM_2);
90     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
91     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
92     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
93     if (!typesArg->IsArray(vm)) {
94         GetArkUINodeModifiers()->getRichEditorModifier()->
95             resetRichEditorDataDetectorConfigWithEvent(nativeNode);
96         return panda::JSValueRef::Undefined(vm);
97     }
98 
99     struct ArkUITextDetectConfigStruct arkUITextDetectConfig;
100     std::string types;
101     auto array = panda::Local<panda::ArrayRef>(typesArg);
102     for (size_t i = 0; i < array->Length(vm); i++) {
103         auto value = panda::ArrayRef::GetValueAt(vm, array, i);
104         auto index = value->Int32Value(vm);
105         if (index < 0 || index >= static_cast<int32_t>(TEXT_DETECT_TYPES.size())) {
106             return panda::JSValueRef::Undefined(vm);
107         }
108         if (i != 0) {
109             types.append(",");
110         }
111         types.append(TEXT_DETECT_TYPES[index]);
112     }
113     arkUITextDetectConfig.types = types.c_str();
114     std::function<void(const std::string&)> callback;
115     if (callbackArg->IsFunction(vm)) {
116         panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
117         callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)](const std::string& info) {
118             panda::LocalScope pandaScope(vm);
119             panda::TryCatch trycatch(vm);
120             PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
121             panda::Local<panda::JSValueRef> params[NUM_1] = {
122                 panda::StringRef::NewFromUtf8(vm, info.c_str()) };
123             func->Call(vm, func.ToLocal(), params, NUM_1);
124         };
125         arkUITextDetectConfig.onResult = reinterpret_cast<void*>(&callback);
126     }
127     ParseAIEntityColor(runtimeCallInfo, arkUITextDetectConfig);
128     GetArkUINodeModifiers()->getRichEditorModifier()->
129         setRichEditorDataDetectorConfigWithEvent(nativeNode, &arkUITextDetectConfig);
130     return panda::JSValueRef::Undefined(vm);
131 }
132 
ParseAIEntityColor(ArkUIRuntimeCallInfo * runtimeCallInfo,struct ArkUITextDetectConfigStruct & arkUITextDetectConfig)133 void RichEditorBridge::ParseAIEntityColor(
134     ArkUIRuntimeCallInfo* runtimeCallInfo, struct ArkUITextDetectConfigStruct& arkUITextDetectConfig)
135 {
136     EcmaVM* vm = runtimeCallInfo->GetVM();
137     CHECK_NULL_VOID(vm);
138     TextDetectConfig textDetectConfig;
139     Local<JSValueRef> entityColorArg = runtimeCallInfo->GetCallArgRef(NUM_3);
140     ArkTSUtils::ParseJsColorAlpha(vm, entityColorArg, textDetectConfig.entityColor);
141     arkUITextDetectConfig.entityColor = textDetectConfig.entityColor.GetValue();
142 
143     Local<JSValueRef> entityDecorationTypeArg = runtimeCallInfo->GetCallArgRef(NUM_4);
144     Local<JSValueRef> entityDecorationColorArg = runtimeCallInfo->GetCallArgRef(NUM_5);
145     Local<JSValueRef> entityDecorationStyleArg = runtimeCallInfo->GetCallArgRef(NUM_6);
146     arkUITextDetectConfig.entityDecorationType = static_cast<int32_t>(textDetectConfig.entityDecorationType);
147     arkUITextDetectConfig.entityDecorationColor = arkUITextDetectConfig.entityColor;
148     arkUITextDetectConfig.entityDecorationStyle = static_cast<int32_t>(textDetectConfig.entityDecorationStyle);
149 
150     if (entityDecorationTypeArg->IsInt()) {
151         arkUITextDetectConfig.entityDecorationType = entityDecorationTypeArg->Int32Value(vm);
152     }
153     if (ArkTSUtils::ParseJsColorAlpha(vm, entityDecorationColorArg, textDetectConfig.entityDecorationColor)) {
154         arkUITextDetectConfig.entityDecorationColor = textDetectConfig.entityDecorationColor.GetValue();
155     }
156     if (entityDecorationStyleArg->IsInt()) {
157         arkUITextDetectConfig.entityDecorationStyle = entityDecorationStyleArg->Int32Value(vm);
158     }
159 }
160 
ResetDataDetectorConfig(ArkUIRuntimeCallInfo * runtimeCallInfo)161 ArkUINativeModuleValue RichEditorBridge::ResetDataDetectorConfig(ArkUIRuntimeCallInfo* runtimeCallInfo)
162 {
163     EcmaVM* vm = runtimeCallInfo->GetVM();
164     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
165     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
166     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
167     GetArkUINodeModifiers()->getRichEditorModifier()->
168         resetRichEditorDataDetectorConfigWithEvent(nativeNode);
169     return panda::JSValueRef::Undefined(vm);
170 }
171 
CreateAbstractSpanResult(EcmaVM * vm,RichEditorAbstractSpanResult & event)172 Local<panda::ObjectRef> CreateAbstractSpanResult(EcmaVM *vm, RichEditorAbstractSpanResult& event)
173 {
174     const char* spanPositionObjKeys[] = { "spanRange", "spanIndex" };
175     auto spanRange = panda::ArrayRef::New(vm);
176     panda::ArrayRef::SetValueAt(vm, spanRange, NUM_0, panda::NumberRef::New(vm, event.GetSpanRangeStart()));
177     panda::ArrayRef::SetValueAt(vm, spanRange, NUM_1, panda::NumberRef::New(vm, event.GetSpanRangeEnd()));
178     Local<JSValueRef> spanPositionObjValues[] = { spanRange, panda::NumberRef::New(vm, event.GetSpanIndex()) };
179     auto spanPositionObj = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(spanPositionObjKeys),
180         spanPositionObjKeys, spanPositionObjValues);
181     const char* decorationObjKeys[] = { "type", "color" };
182     Local<JSValueRef> decorationObjValues[] = {
183         panda::NumberRef::New(vm, static_cast<int32_t>(event.GetTextDecoration())),
184         panda::StringRef::NewFromUtf8(vm, event.GetColor().c_str())
185     };
186     auto decorationObj = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(decorationObjKeys),
187         decorationObjKeys, decorationObjValues);
188 
189     const char* textStyleObjKeys[] = { "fontColor", "fontFeature", "fontSize", "lineHeight",
190         "letterSpacing", "fontStyle", "fontWeight", "fontFamily", "decoration"};
191     Local<JSValueRef> textStyleObjValues[] = {
192         panda::StringRef::NewFromUtf8(vm, event.GetFontColor().c_str()),
193         panda::StringRef::NewFromUtf8(vm, UnParseFontFeatureSetting(event.GetFontFeatures()).c_str()),
194         panda::NumberRef::New(vm, event.GetFontSize()),
195         panda::NumberRef::New(vm, event.GetTextStyle().lineHeight),
196         panda::NumberRef::New(vm, event.GetTextStyle().letterSpacing),
197         panda::NumberRef::New(vm, static_cast<int32_t>(event.GetFontStyle())),
198         panda::NumberRef::New(vm, event.GetFontWeight()),
199         panda::StringRef::NewFromUtf8(vm, event.GetFontFamily().c_str()), decorationObj
200     };
201     auto textStyleObj = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(textStyleObjKeys),
202         textStyleObjKeys, textStyleObjValues);
203     auto offsetInSpan = panda::ArrayRef::New(vm);
204     panda::ArrayRef::SetValueAt(vm, offsetInSpan, NUM_0, panda::NumberRef::New(vm, event.OffsetInSpan()));
205     panda::ArrayRef::SetValueAt(vm, offsetInSpan, NUM_1,
206         panda::NumberRef::New(vm, event.OffsetInSpan() + event.GetEraseLength()));
207 
208     const char* onIMEInputCompleteObjKeys[] = { "spanPosition", "value", "previewText", "textStyle",
209         "offsetInSpan", "paragraphStyle" };
210     Local<JSValueRef> onIMEInputCompleteObjValues[] = {
211         spanPositionObj, panda::StringRef::NewFromUtf8(vm, event.GetValue().c_str()),
212         panda::StringRef::NewFromUtf8(vm, event.GetPreviewText().c_str()),
213         textStyleObj, offsetInSpan,
214         CreateParagraphStyle(vm, event.GetTextStyle())
215     };
216     return panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(onIMEInputCompleteObjKeys),
217         onIMEInputCompleteObjKeys, onIMEInputCompleteObjValues);
218 }
219 
SetOnIMEInputComplete(ArkUIRuntimeCallInfo * runtimeCallInfo)220 ArkUINativeModuleValue RichEditorBridge::SetOnIMEInputComplete(ArkUIRuntimeCallInfo* runtimeCallInfo)
221 {
222     EcmaVM* vm = runtimeCallInfo->GetVM();
223     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
224     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
225     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(NUM_1);
226     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
227     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
228         GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorOnIMEInputComplete(nativeNode);
229         return panda::JSValueRef::Undefined(vm);
230     }
231     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
232     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
233     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
234     std::function<void(RichEditorAbstractSpanResult&)> callback = [vm, frameNode,
235         func = panda::CopyableGlobal(vm, func)](RichEditorAbstractSpanResult& event) {
236         panda::LocalScope pandaScope(vm);
237         panda::TryCatch trycatch(vm);
238         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
239         auto onIMEInputCompleteObj = CreateAbstractSpanResult(vm, event);
240         onIMEInputCompleteObj->SetNativePointerFieldCount(vm, NUM_1);
241         onIMEInputCompleteObj->SetNativePointerField(vm, NUM_0, static_cast<void*>(&event));
242         panda::Local<panda::JSValueRef> params[NUM_1] = { onIMEInputCompleteObj };
243         func->Call(vm, func.ToLocal(), params, NUM_1);
244     };
245     GetArkUINodeModifiers()->getRichEditorModifier()->setRichEditorOnIMEInputComplete(
246         nativeNode, reinterpret_cast<void*>(&callback));
247     return panda::JSValueRef::Undefined(vm);
248 }
249 
ResetOnIMEInputComplete(ArkUIRuntimeCallInfo * runtimeCallInfo)250 ArkUINativeModuleValue RichEditorBridge::ResetOnIMEInputComplete(ArkUIRuntimeCallInfo* runtimeCallInfo)
251 {
252     EcmaVM* vm = runtimeCallInfo->GetVM();
253     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
254     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
255     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
256     GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorOnIMEInputComplete(nativeNode);
257     return panda::JSValueRef::Undefined(vm);
258 }
259 
SetCopyOptions(ArkUIRuntimeCallInfo * runtimeCallInfo)260 ArkUINativeModuleValue RichEditorBridge::SetCopyOptions(ArkUIRuntimeCallInfo* runtimeCallInfo)
261 {
262     EcmaVM* vm = runtimeCallInfo->GetVM();
263     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
264     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
265     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
266     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
267     uint32_t CopyOptionsValue = static_cast<uint32_t>(CopyOptions::Distributed);
268     if (secondArg->IsNumber()) {
269         CopyOptionsValue = secondArg->Uint32Value(vm);
270         GetArkUINodeModifiers()->getRichEditorModifier()->setRichEditorCopyOptions(nativeNode, CopyOptionsValue);
271     } else {
272         GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorCopyOptions(nativeNode);
273     }
274     return panda::JSValueRef::Undefined(vm);
275 }
276 
ResetCopyOptions(ArkUIRuntimeCallInfo * runtimeCallInfo)277 ArkUINativeModuleValue RichEditorBridge::ResetCopyOptions(ArkUIRuntimeCallInfo* runtimeCallInfo)
278 {
279     EcmaVM* vm = runtimeCallInfo->GetVM();
280     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
281     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
282     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
283     GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorCopyOptions(nativeNode);
284     return panda::JSValueRef::Undefined(vm);
285 }
286 
SetOnSelectionChange(ArkUIRuntimeCallInfo * runtimeCallInfo)287 ArkUINativeModuleValue RichEditorBridge::SetOnSelectionChange(ArkUIRuntimeCallInfo* runtimeCallInfo)
288 {
289     EcmaVM *vm = runtimeCallInfo->GetVM();
290     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
291     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
292     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(NUM_1);
293     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
294     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
295     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
296     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
297         GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorOnSelectionChange(nativeNode);
298         return panda::JSValueRef::Undefined(vm);
299     }
300     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
301     std::function<void(const BaseEventInfo* info)> callback =
302         [vm, frameNode, func = panda::CopyableGlobal(vm, func)](const BaseEventInfo* info) {
303         panda::LocalScope pandaScope(vm);
304         panda::TryCatch trycatch(vm);
305         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
306         const auto* changeInfo = TypeInfoHelper::DynamicCast<SelectionRangeInfo>(info);
307         if (!changeInfo) {
308             TAG_LOGW(AceLogTag::ACE_RICH_TEXT, "richEditor SetOnSelectionChange callback execute failed.");
309             return;
310         }
311         const char* keys[] = { "start", "end" };
312         Local<JSValueRef> values[] = { panda::NumberRef::New(vm, changeInfo->start_),
313             panda::NumberRef::New(vm, changeInfo->end_) };
314         auto eventObject = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
315         panda::Local<panda::JSValueRef> params[NUM_1] = { eventObject };
316         func->Call(vm, func.ToLocal(), params, NUM_1);
317     };
318     GetArkUINodeModifiers()->getRichEditorModifier()->setRichEditorOnSelectionChange(
319         nativeNode, reinterpret_cast<void*>(&callback));
320     return panda::JSValueRef::Undefined(vm);
321 }
322 
ResetOnSelectionChange(ArkUIRuntimeCallInfo * runtimeCallInfo)323 ArkUINativeModuleValue RichEditorBridge::ResetOnSelectionChange(ArkUIRuntimeCallInfo* runtimeCallInfo)
324 {
325     EcmaVM* vm = runtimeCallInfo->GetVM();
326     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
327     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
328     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
329     GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorOnSelectionChange(nativeNode);
330     return panda::JSValueRef::Undefined(vm);
331 }
332 
SetCaretColor(ArkUIRuntimeCallInfo * runtimeCallInfo)333 ArkUINativeModuleValue RichEditorBridge::SetCaretColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
334 {
335     EcmaVM* vm = runtimeCallInfo->GetVM();
336     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
337     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
338     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
339     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
340     Color color;
341     if (!ArkTSUtils::ParseJsColorAlpha(vm, secondArg, color)) {
342         GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorCaretColor(nativeNode);
343     } else {
344         GetArkUINodeModifiers()->getRichEditorModifier()->setRichEditorCaretColor(nativeNode, color.GetValue());
345     }
346     return panda::JSValueRef::Undefined(vm);
347 }
348 
ResetCaretColor(ArkUIRuntimeCallInfo * runtimeCallInfo)349 ArkUINativeModuleValue RichEditorBridge::ResetCaretColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
350 {
351     EcmaVM* vm = runtimeCallInfo->GetVM();
352     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
353     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
354     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
355     GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorCaretColor(nativeNode);
356     return panda::JSValueRef::Undefined(vm);
357 }
358 
CreateTextStyleResult(EcmaVM * vm,const TextStyleResult & textStyleResult)359 Local<panda::ObjectRef> CreateTextStyleResult(EcmaVM *vm, const TextStyleResult& textStyleResult)
360 {
361     const char* decorationObjKeys[] = { "type", "color" };
362     Local<JSValueRef> decorationObjValues[] = {
363         panda::NumberRef::New(vm, static_cast<int32_t>(textStyleResult.decorationType)),
364         panda::StringRef::NewFromUtf8(vm, textStyleResult.decorationColor.c_str())
365     };
366     auto decorationObj = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(decorationObjKeys),
367         decorationObjKeys, decorationObjValues);
368 
369     auto leadingMarginArray = panda::ArrayRef::New(vm);
370     panda::ArrayRef::SetValueAt(vm, leadingMarginArray, NUM_0,
371         panda::StringRef::NewFromUtf8(vm, textStyleResult.leadingMarginSize[NUM_0].c_str()));
372     panda::ArrayRef::SetValueAt(vm, leadingMarginArray, NUM_1,
373         panda::StringRef::NewFromUtf8(vm, textStyleResult.leadingMarginSize[NUM_1].c_str()));
374 
375     const char* textStyleObjKeys[] = { "fontColor", "fontFeature", "fontSize", "fontStyle",
376         "lineHeight", "letterSpacing", "fontWeight", "fontFamily", "decoration", "textAlign", "leadingMarginSize" };
377     Local<JSValueRef> textStyleObjValues[] = {
378         panda::StringRef::NewFromUtf8(vm, textStyleResult.fontColor.c_str()),
379         panda::StringRef::NewFromUtf8(vm, UnParseFontFeatureSetting(textStyleResult.fontFeature).c_str()),
380         panda::NumberRef::New(vm, textStyleResult.fontSize),
381         panda::NumberRef::New(vm, textStyleResult.fontStyle),
382         panda::NumberRef::New(vm, textStyleResult.lineHeight),
383         panda::NumberRef::New(vm, textStyleResult.letterSpacing),
384         panda::NumberRef::New(vm, textStyleResult.fontWeight),
385         panda::StringRef::NewFromUtf8(vm, textStyleResult.fontFamily.c_str()), decorationObj,
386         panda::NumberRef::New(vm, textStyleResult.textAlign), leadingMarginArray
387     };
388     return panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(textStyleObjKeys),
389         textStyleObjKeys, textStyleObjValues);
390 }
391 
CreateSymbolSpanStyleResult(EcmaVM * vm,const SymbolSpanStyle & symbolSpanStyle)392 Local<panda::ObjectRef> CreateSymbolSpanStyleResult(EcmaVM *vm, const SymbolSpanStyle& symbolSpanStyle)
393 {
394     const char* symbolSpanStyleObjKeys[] = { "fontColor", "fontFeature", "fontSize", "lineHeight",
395         "letterSpacing", "fontWeight", "renderingStrategy", "effectStrategy" };
396     Local<JSValueRef> symbolSpanStyleObjValues[] = {
397         panda::StringRef::NewFromUtf8(vm, symbolSpanStyle.symbolColor.c_str()),
398         panda::StringRef::NewFromUtf8(vm, UnParseFontFeatureSetting(symbolSpanStyle.fontFeature).c_str()),
399         panda::NumberRef::New(vm, symbolSpanStyle.fontSize),
400         panda::NumberRef::New(vm, symbolSpanStyle.lineHeight),
401         panda::NumberRef::New(vm, symbolSpanStyle.letterSpacing),
402         panda::NumberRef::New(vm, symbolSpanStyle.fontWeight),
403         panda::NumberRef::New(vm, symbolSpanStyle.renderingStrategy),
404         panda::NumberRef::New(vm, symbolSpanStyle.effectStrategy)
405     };
406     return panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(symbolSpanStyleObjKeys),
407         symbolSpanStyleObjKeys, symbolSpanStyleObjValues);
408 }
409 
CreateResourceObjectParam(EcmaVM * vm,const std::vector<ResourceObjectParams> & params)410 Local<panda::ArrayRef> CreateResourceObjectParam(EcmaVM *vm, const std::vector<ResourceObjectParams>& params)
411 {
412     auto size = static_cast<int32_t>(params.size());
413     auto valueResourceObj = panda::ArrayRef::New(vm, size);
414     for (int32_t i = 0; i < size; i++) {
415         const char* valueResourceItemKeys[] = { "type", "value" };
416         auto type = panda::StringRef::NewFromUtf8(vm, "ResourceObjectParamType::NONE");
417         if (params[i].type == ResourceObjectParamType::FLOAT) {
418             type = panda::StringRef::NewFromUtf8(vm, "ResourceObjectParamType::FLOAT");
419         } else if (params[i].type == ResourceObjectParamType::STRING) {
420             type = panda::StringRef::NewFromUtf8(vm, "ResourceObjectParamType::STRING");
421         } else if (params[i].type == ResourceObjectParamType::INT) {
422             type = panda::StringRef::NewFromUtf8(vm, "ResourceObjectParamType::INT");
423         } else {
424             type = panda::StringRef::NewFromUtf8(vm, "ResourceObjectParamType::NONE");
425         }
426         Local<JSValueRef> valueResourceItemValues[] = { type,
427             panda::StringRef::NewFromUtf8(vm, params[i].value->c_str())
428         };
429         auto valueResourceItem = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(valueResourceItemKeys),
430             valueResourceItemKeys, valueResourceItemValues);
431         panda::ArrayRef::SetValueAt(vm, valueResourceObj, i, valueResourceItem);
432     }
433     return valueResourceObj;
434 }
435 
CreateValueResource(EcmaVM * vm,const RefPtr<ResourceObject> & valueResource)436 Local<panda::ObjectRef> CreateValueResource(EcmaVM *vm, const RefPtr<ResourceObject>& valueResource)
437 {
438     const char* valueResourceKeys[] = { "bundleName", "moduleName", "id", "params", "type" };
439     Local<JSValueRef> valueResourceValues[] = {
440         panda::StringRef::NewFromUtf8(vm, valueResource->GetBundleName().c_str()),
441         panda::StringRef::NewFromUtf8(vm, valueResource->GetModuleName().c_str()),
442         panda::NumberRef::New(vm, valueResource->GetId()),
443         CreateResourceObjectParam(vm, valueResource->GetParams()),
444         panda::NumberRef::New(vm, valueResource->GetType())
445     };
446     return panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(valueResourceKeys),
447         valueResourceKeys, valueResourceValues);
448 }
449 
CreateImageStyleResult(EcmaVM * vm,const ImageStyleResult & imageStyleResult)450 Local<panda::ObjectRef> CreateImageStyleResult(EcmaVM *vm, const ImageStyleResult& imageStyleResult)
451 {
452     const char* layoutStyleObjKeys[] = { "borderRadius", "margin" };
453     Local<JSValueRef> layoutStyleObjValues[] = {
454         panda::StringRef::NewFromUtf8(vm, imageStyleResult.borderRadius.c_str()),
455         panda::StringRef::NewFromUtf8(vm, imageStyleResult.margin.c_str())
456     };
457     auto layoutStyleObj = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(layoutStyleObjKeys),
458         layoutStyleObjKeys, layoutStyleObjValues);
459 
460     auto sizeArray = panda::ArrayRef::New(vm);
461     panda::ArrayRef::SetValueAt(vm, sizeArray, NUM_0, panda::NumberRef::New(vm, imageStyleResult.size[NUM_0]));
462     panda::ArrayRef::SetValueAt(vm, sizeArray, NUM_1, panda::NumberRef::New(vm, imageStyleResult.size[NUM_1]));
463 
464     const char* imageSpanStyleObjKeys[] = { "size", "verticalAlign", "objectFit", "layoutStyle" };
465     Local<JSValueRef> imageSpanStyleObjValues[] = {
466         sizeArray, panda::NumberRef::New(vm, imageStyleResult.verticalAlign),
467         panda::NumberRef::New(vm, imageStyleResult.objectFit), layoutStyleObj
468     };
469     return panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(imageSpanStyleObjKeys),
470         imageSpanStyleObjKeys, imageSpanStyleObjValues);
471 }
472 
CreateSpanResultObject(EcmaVM * vm,const ResultObject & resultObject)473 Local<panda::ObjectRef> CreateSpanResultObject(EcmaVM *vm, const ResultObject& resultObject)
474 {
475     auto offsetArray = panda::ArrayRef::New(vm);
476     panda::ArrayRef::SetValueAt(vm, offsetArray, NUM_0, panda::NumberRef::New(vm, resultObject.offsetInSpan[NUM_0]));
477     panda::ArrayRef::SetValueAt(vm, offsetArray, NUM_1, panda::NumberRef::New(vm, resultObject.offsetInSpan[NUM_1]));
478     auto spanRangeArray = panda::ArrayRef::New(vm);
479     panda::ArrayRef::SetValueAt(vm, spanRangeArray, NUM_0,
480         panda::NumberRef::New(vm, resultObject.spanPosition.spanRange[NUM_0]));
481     panda::ArrayRef::SetValueAt(vm, spanRangeArray, NUM_1,
482         panda::NumberRef::New(vm, resultObject.spanPosition.spanRange[NUM_1]));
483     const char* spanPositionObjKeys[] = { "spanIndex", "spanRange" };
484     Local<JSValueRef> spanPositionObjValues[] = {
485         panda::NumberRef::New(vm, resultObject.spanPosition.spanIndex), spanRangeArray
486     };
487     auto spanPositionObj = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(spanPositionObjKeys),
488         spanPositionObjKeys, spanPositionObjValues);
489 
490     auto resultObj = panda::ObjectRef::New(vm);
491     resultObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "offsetInSpan"), offsetArray);
492     resultObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "spanPosition"), spanPositionObj);
493     if (resultObject.type == SelectSpanType::TYPESPAN) {
494         resultObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "value"),
495             panda::StringRef::NewFromUtf8(vm, resultObject.valueString.c_str()));
496         resultObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "textStyle"),
497             CreateTextStyleResult(vm, resultObject.textStyle));
498         resultObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "paragraphStyle"),
499             CreateParagraphStyle(vm, resultObject.textStyle));
500     } else if (resultObject.type == SelectSpanType::TYPESYMBOLSPAN) {
501         resultObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "value"),
502             panda::StringRef::NewFromUtf8(vm, resultObject.valueString.c_str()));
503         resultObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "symbolSpanStyle"),
504             CreateSymbolSpanStyleResult(vm, resultObject.symbolSpanStyle));
505         resultObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "valueResource"),
506             CreateValueResource(vm, resultObject.valueResource));
507     } else if (resultObject.type == SelectSpanType::TYPEIMAGE) {
508         if (resultObject.valuePixelMap) {
509 #if defined (PIXEL_MAP_SUPPORTED)
510             auto jsPixmap = Framework::ConvertPixmap(resultObject.valuePixelMap);
511             if (!jsPixmap->IsUndefined()) {
512                 resultObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "valuePixelMap"),
513                     panda::StringRef::NewFromUtf8(vm, jsPixmap->ToString().c_str()));
514             }
515 #endif
516         } else {
517             resultObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "valueResourceStr"),
518                 panda::StringRef::NewFromUtf8(vm, resultObject.valueString.c_str()));
519         }
520         resultObj->Set(vm, panda::StringRef::NewFromUtf8(vm, "imageStyle"),
521             CreateImageStyleResult(vm, resultObject.imageStyle));
522     }
523 
524     return resultObj;
525 }
526 
CreatSelectEvent(EcmaVM * vm,const BaseEventInfo * info,panda::Local<panda::JSValueRef> params[])527 void CreatSelectEvent(EcmaVM *vm, const BaseEventInfo* info, panda::Local<panda::JSValueRef> params[])
528 {
529     const auto* selectInfo = TypeInfoHelper::DynamicCast<SelectionInfo>(info);
530     if (!selectInfo) {
531         TAG_LOGW(AceLogTag::ACE_RICH_TEXT, "richEditor SetOnSelect callback execute failed.");
532         return;
533     }
534     const char* keys[] = { "selection", "spans" };
535     auto selectionArray = panda::ArrayRef::New(vm, NUM_2);
536     auto selectionObjValue = selectInfo->GetSelection();
537     panda::ArrayRef::SetValueAt(vm, selectionArray, NUM_0,
538         panda::NumberRef::New(vm, selectionObjValue.selection[NUM_0]));
539     panda::ArrayRef::SetValueAt(vm, selectionArray, NUM_1,
540         panda::NumberRef::New(vm, selectionObjValue.selection[NUM_1]));
541 
542     auto spanObjectArray = panda::ArrayRef::New(vm);
543     auto idx = 0;
544     for (const ResultObject& spanObject : selectionObjValue.resultObjects) {
545         panda::ArrayRef::SetValueAt(vm, spanObjectArray, idx++, CreateSpanResultObject(vm, spanObject));
546     }
547     Local<JSValueRef> values[] = { selectionArray, spanObjectArray };
548     auto eventObject = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
549     params[NUM_1] = { eventObject };
550 }
551 
SetOnSelect(ArkUIRuntimeCallInfo * runtimeCallInfo)552 ArkUINativeModuleValue RichEditorBridge::SetOnSelect(ArkUIRuntimeCallInfo* runtimeCallInfo)
553 {
554     EcmaVM *vm = runtimeCallInfo->GetVM();
555     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
556     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
557     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(NUM_1);
558     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
559     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
560     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
561     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
562         GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorOnSelect(nativeNode);
563         return panda::JSValueRef::Undefined(vm);
564     }
565     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
566     std::function<void(const BaseEventInfo* info)> callback =
567         [vm, frameNode, func = panda::CopyableGlobal(vm, func)](const BaseEventInfo* info) {
568         panda::LocalScope pandaScope(vm);
569         panda::TryCatch trycatch(vm);
570         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
571         panda::Local<panda::JSValueRef> params[NUM_1];
572         CreatSelectEvent(vm, info, params);
573         func->Call(vm, func.ToLocal(), params, NUM_1);
574     };
575     GetArkUINodeModifiers()->getRichEditorModifier()->setRichEditorOnSelect(
576         nativeNode, reinterpret_cast<void*>(&callback));
577     return panda::JSValueRef::Undefined(vm);
578 }
579 
ResetOnSelect(ArkUIRuntimeCallInfo * runtimeCallInfo)580 ArkUINativeModuleValue RichEditorBridge::ResetOnSelect(ArkUIRuntimeCallInfo* runtimeCallInfo)
581 {
582     EcmaVM* vm = runtimeCallInfo->GetVM();
583     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
584     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
585     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
586     GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorOnSelect(nativeNode);
587     return panda::JSValueRef::Undefined(vm);
588 }
589 
SetOnSubmit(ArkUIRuntimeCallInfo * runtimeCallInfo)590 ArkUINativeModuleValue RichEditorBridge::SetOnSubmit(ArkUIRuntimeCallInfo* runtimeCallInfo)
591 {
592     EcmaVM *vm = runtimeCallInfo->GetVM();
593     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
594     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
595     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(NUM_1);
596     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
597     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
598     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
599     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
600         GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorOnSubmit(nativeNode);
601         return panda::JSValueRef::Undefined(vm);
602     }
603     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
604     std::function<void(int32_t, NG::TextFieldCommonEvent&)> callback = [vm, frameNode,
605         func = panda::CopyableGlobal(vm, func)](int32_t key, NG::TextFieldCommonEvent& event) {
606         panda::LocalScope pandaScope(vm);
607         panda::TryCatch trycatch(vm);
608         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
609         const char* keys[] = { "text", "keepEditableState" };
610         Local<JSValueRef> values[] = { panda::StringRef::NewFromUtf8(vm, event.GetText().c_str()),
611             panda::FunctionRef::New(vm, Framework::JSRichEditor::JsKeepEditableState) };
612         auto eventObject = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
613         eventObject->SetNativePointerFieldCount(vm, NUM_1);
614         eventObject->SetNativePointerField(vm, 0, static_cast<void*>(&event));
615         panda::Local<panda::JSValueRef> params[NUM_2] = {
616             panda::IntegerRef::New(vm, key), eventObject };
617         func->Call(vm, func.ToLocal(), params, NUM_2);
618     };
619     GetArkUINodeModifiers()->getRichEditorModifier()->setRichEditorOnSubmit(
620         nativeNode, reinterpret_cast<void*>(&callback));
621     return panda::JSValueRef::Undefined(vm);
622 }
623 
ResetOnSubmit(ArkUIRuntimeCallInfo * runtimeCallInfo)624 ArkUINativeModuleValue RichEditorBridge::ResetOnSubmit(ArkUIRuntimeCallInfo* runtimeCallInfo)
625 {
626     EcmaVM* vm = runtimeCallInfo->GetVM();
627     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
628     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
629     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
630     GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorOnSubmit(nativeNode);
631     return panda::JSValueRef::Undefined(vm);
632 }
633 
SetAboutToIMEInput(ArkUIRuntimeCallInfo * runtimeCallInfo)634 ArkUINativeModuleValue RichEditorBridge::SetAboutToIMEInput(ArkUIRuntimeCallInfo* runtimeCallInfo)
635 {
636     EcmaVM *vm = runtimeCallInfo->GetVM();
637     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
638     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
639     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(NUM_1);
640     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
641     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
642     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
643     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
644         GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorAboutToIMEInput(nativeNode);
645         return panda::JSValueRef::Undefined(vm);
646     }
647     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
648     std::function<bool(const RichEditorInsertValue&)> callback =
649         [vm, frameNode, func = panda::CopyableGlobal(vm, func)](const RichEditorInsertValue& insertValue) {
650         panda::LocalScope pandaScope(vm);
651         panda::TryCatch trycatch(vm);
652         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
653         const char* keys[] = { "insertOffset", "insertValue", "previewText" };
654         Local<JSValueRef> values[] = { panda::NumberRef::New(vm, insertValue.GetInsertOffset()),
655             panda::StringRef::NewFromUtf8(vm, insertValue.GetInsertValue().c_str()),
656             panda::StringRef::NewFromUtf8(vm, insertValue.GetPreviewText().c_str()) };
657         auto eventObject = panda::ObjectRef::NewWithNamedProperties(vm, ArraySize(keys), keys, values);
658         panda::Local<panda::JSValueRef> params[NUM_1] = { eventObject };
659         auto ret = func->Call(vm, func.ToLocal(), params, NUM_1);
660         if (ret->IsBoolean()) {
661             return ret->ToBoolean(vm)->Value();
662         }
663         return true;
664     };
665     GetArkUINodeModifiers()->getRichEditorModifier()->setRichEditorAboutToIMEInput(
666         nativeNode, reinterpret_cast<void*>(&callback));
667     return panda::JSValueRef::Undefined(vm);
668 }
669 
ResetAboutToIMEInput(ArkUIRuntimeCallInfo * runtimeCallInfo)670 ArkUINativeModuleValue RichEditorBridge::ResetAboutToIMEInput(ArkUIRuntimeCallInfo* runtimeCallInfo)
671 {
672     EcmaVM* vm = runtimeCallInfo->GetVM();
673     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
674     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
675     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
676     GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorAboutToIMEInput(nativeNode);
677     return panda::JSValueRef::Undefined(vm);
678 }
679 
SetOnReady(ArkUIRuntimeCallInfo * runtimeCallInfo)680 ArkUINativeModuleValue RichEditorBridge::SetOnReady(ArkUIRuntimeCallInfo* runtimeCallInfo)
681 {
682     EcmaVM* vm = runtimeCallInfo->GetVM();
683     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
684     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
685     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(NUM_1);
686     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
687     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
688         GetArkUINodeModifiers()->getRichEditorModifier()->resetOnReady(nativeNode);
689         return panda::JSValueRef::Undefined(vm);
690     }
691     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
692     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
693     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
694     std::function<void(void)> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)]() {
695         panda::LocalScope pandaScope(vm);
696         panda::TryCatch trycatch(vm);
697         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
698         func->Call(vm, func.ToLocal(), nullptr, NUM_0);
699     };
700     GetArkUINodeModifiers()->getRichEditorModifier()->setOnReady(nativeNode, reinterpret_cast<void*>(&callback));
701     return panda::JSValueRef::Undefined(vm);
702 }
703 
ResetOnReady(ArkUIRuntimeCallInfo * runtimeCallInfo)704 ArkUINativeModuleValue RichEditorBridge::ResetOnReady(ArkUIRuntimeCallInfo* runtimeCallInfo)
705 {
706     EcmaVM* vm = runtimeCallInfo->GetVM();
707     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
708     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
709     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
710     GetArkUINodeModifiers()->getRichEditorModifier()->resetOnReady(nativeNode);
711     return panda::JSValueRef::Undefined(vm);
712 }
713 
SetOnDeleteComplete(ArkUIRuntimeCallInfo * runtimeCallInfo)714 ArkUINativeModuleValue RichEditorBridge::SetOnDeleteComplete(ArkUIRuntimeCallInfo* runtimeCallInfo)
715 {
716     EcmaVM* vm = runtimeCallInfo->GetVM();
717     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
718     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
719     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(NUM_1);
720     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
721     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
722         GetArkUINodeModifiers()->getRichEditorModifier()->resetOnDeleteComplete(nativeNode);
723         return panda::JSValueRef::Undefined(vm);
724     }
725     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
726     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
727     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
728     std::function<void(void)> callback = [vm, frameNode, func = panda::CopyableGlobal(vm, func)]() {
729         panda::LocalScope pandaScope(vm);
730         panda::TryCatch trycatch(vm);
731         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
732         func->Call(vm, func.ToLocal(), nullptr, NUM_0);
733     };
734     GetArkUINodeModifiers()->getRichEditorModifier()->setOnDeleteComplete(
735         nativeNode, reinterpret_cast<void*>(&callback));
736     return panda::JSValueRef::Undefined(vm);
737 }
738 
ResetOnDeleteComplete(ArkUIRuntimeCallInfo * runtimeCallInfo)739 ArkUINativeModuleValue RichEditorBridge::ResetOnDeleteComplete(ArkUIRuntimeCallInfo* runtimeCallInfo)
740 {
741     EcmaVM* vm = runtimeCallInfo->GetVM();
742     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
743     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
744     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
745     GetArkUINodeModifiers()->getRichEditorModifier()->resetOnDeleteComplete(nativeNode);
746     return panda::JSValueRef::Undefined(vm);
747 }
748 
SetOnEditingChange(ArkUIRuntimeCallInfo * runtimeCallInfo)749 ArkUINativeModuleValue RichEditorBridge::SetOnEditingChange(ArkUIRuntimeCallInfo* runtimeCallInfo)
750 {
751     EcmaVM* vm = runtimeCallInfo->GetVM();
752     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
753     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
754     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(NUM_1);
755     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
756     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
757         GetArkUINodeModifiers()->getRichEditorModifier()->resetOnEditingChange(nativeNode);
758         return panda::JSValueRef::Undefined(vm);
759     }
760     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
761     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
762     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
763     std::function<void(bool)> callback = [vm, frameNode,
764         func = panda::CopyableGlobal(vm, func)](bool isInEditStatus) {
765         panda::LocalScope pandaScope(vm);
766         panda::TryCatch trycatch(vm);
767         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
768         panda::Local<panda::JSValueRef> params[NUM_1] = {
769             panda::BooleanRef::New(vm, isInEditStatus) };
770         func->Call(vm, func.ToLocal(), params, NUM_1);
771     };
772     GetArkUINodeModifiers()->getRichEditorModifier()->setOnEditingChange(
773         nativeNode, reinterpret_cast<void*>(&callback));
774     return panda::JSValueRef::Undefined(vm);
775 }
776 
ResetOnEditingChange(ArkUIRuntimeCallInfo * runtimeCallInfo)777 ArkUINativeModuleValue RichEditorBridge::ResetOnEditingChange(ArkUIRuntimeCallInfo* runtimeCallInfo)
778 {
779     EcmaVM* vm = runtimeCallInfo->GetVM();
780     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
781     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
782     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
783     GetArkUINodeModifiers()->getRichEditorModifier()->resetOnEditingChange(nativeNode);
784     return panda::JSValueRef::Undefined(vm);
785 }
786 
SetSelectedBackgroundColor(ArkUIRuntimeCallInfo * runtimeCallInfo)787 ArkUINativeModuleValue RichEditorBridge::SetSelectedBackgroundColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
788 {
789     EcmaVM* vm = runtimeCallInfo->GetVM();
790     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
791     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
792     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
793     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
794     Color color;
795     if (!ArkTSUtils::ParseJsColorAlpha(vm, secondArg, color)) {
796         GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorSelectedBackgroundColor(nativeNode);
797     } else {
798         GetArkUINodeModifiers()->getRichEditorModifier()->setRichEditorSelectedBackgroundColor(
799             nativeNode, color.GetValue());
800     }
801     return panda::JSValueRef::Undefined(vm);
802 }
803 
ResetSelectedBackgroundColor(ArkUIRuntimeCallInfo * runtimeCallInfo)804 ArkUINativeModuleValue RichEditorBridge::ResetSelectedBackgroundColor(ArkUIRuntimeCallInfo* runtimeCallInfo)
805 {
806     EcmaVM* vm = runtimeCallInfo->GetVM();
807     CHECK_NULL_RETURN(vm, panda::NativePointerRef::New(vm, nullptr));
808     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
809     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
810     GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorSelectedBackgroundColor(nativeNode);
811     return panda::JSValueRef::Undefined(vm);
812 }
813 
CreateCommonEvent(EcmaVM * vm,TextCommonEvent & event,panda::Local<panda::JSValueRef> params[])814 void CreateCommonEvent(EcmaVM *vm, TextCommonEvent& event, panda::Local<panda::JSValueRef> params[])
815 {
816     auto eventObject = panda::ObjectRef::New(vm);
817     eventObject->SetNativePointerFieldCount(vm, NUM_1);
818     eventObject->Set(vm, panda::StringRef::NewFromUtf8(vm, "preventDefault"),
819         panda::FunctionRef::New(vm, Framework::JsPreventDefault));
820     eventObject->SetNativePointerField(vm, NUM_0, static_cast<void*>(&event));
821     params[NUM_1] = { eventObject };
822 }
823 
SetOnPaste(ArkUIRuntimeCallInfo * runtimeCallInfo)824 ArkUINativeModuleValue RichEditorBridge::SetOnPaste(ArkUIRuntimeCallInfo* runtimeCallInfo)
825 {
826     EcmaVM *vm = runtimeCallInfo->GetVM();
827     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
828     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
829     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(NUM_1);
830     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
831     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
832     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
833     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
834         GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorOnPaste(nativeNode);
835         return panda::JSValueRef::Undefined(vm);
836     }
837     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
838     std::function<void(TextCommonEvent&)> callback = [vm, frameNode,
839         func = panda::CopyableGlobal(vm, func)](TextCommonEvent& event) {
840         panda::LocalScope pandaScope(vm);
841         panda::TryCatch trycatch(vm);
842         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
843         panda::Local<panda::JSValueRef> params[NUM_1];
844         CreateCommonEvent(vm, event, params);
845         func->Call(vm, func.ToLocal(), params, NUM_1);
846     };
847     GetArkUINodeModifiers()->getRichEditorModifier()->setRichEditorOnPaste(
848         nativeNode, reinterpret_cast<void*>(&callback));
849     return panda::JSValueRef::Undefined(vm);
850 }
851 
ResetOnPaste(ArkUIRuntimeCallInfo * runtimeCallInfo)852 ArkUINativeModuleValue RichEditorBridge::ResetOnPaste(ArkUIRuntimeCallInfo* runtimeCallInfo)
853 {
854     EcmaVM* vm = runtimeCallInfo->GetVM();
855     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
856     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
857     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
858     GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorOnPaste(nativeNode);
859     return panda::JSValueRef::Undefined(vm);
860 }
861 
SetOnCut(ArkUIRuntimeCallInfo * runtimeCallInfo)862 ArkUINativeModuleValue RichEditorBridge::SetOnCut(ArkUIRuntimeCallInfo* runtimeCallInfo)
863 {
864     EcmaVM *vm = runtimeCallInfo->GetVM();
865     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
866     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
867     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(NUM_1);
868     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
869     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
870     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
871     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
872         GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorOnCut(nativeNode);
873         return panda::JSValueRef::Undefined(vm);
874     }
875     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
876     std::function<void(TextCommonEvent&)> callback = [vm, frameNode,
877         func = panda::CopyableGlobal(vm, func)](TextCommonEvent& event) {
878         panda::LocalScope pandaScope(vm);
879         panda::TryCatch trycatch(vm);
880         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
881         panda::Local<panda::JSValueRef> params[NUM_1];
882         CreateCommonEvent(vm, event, params);
883         func->Call(vm, func.ToLocal(), params, NUM_1);
884     };
885     GetArkUINodeModifiers()->getRichEditorModifier()->setRichEditorOnCut(
886         nativeNode, reinterpret_cast<void*>(&callback));
887     return panda::JSValueRef::Undefined(vm);
888 }
889 
ResetOnCut(ArkUIRuntimeCallInfo * runtimeCallInfo)890 ArkUINativeModuleValue RichEditorBridge::ResetOnCut(ArkUIRuntimeCallInfo* runtimeCallInfo)
891 {
892     EcmaVM* vm = runtimeCallInfo->GetVM();
893     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
894     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
895     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
896     GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorOnCut(nativeNode);
897     return panda::JSValueRef::Undefined(vm);
898 }
899 
SetOnCopy(ArkUIRuntimeCallInfo * runtimeCallInfo)900 ArkUINativeModuleValue RichEditorBridge::SetOnCopy(ArkUIRuntimeCallInfo* runtimeCallInfo)
901 {
902     EcmaVM *vm = runtimeCallInfo->GetVM();
903     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
904     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
905     Local<JSValueRef> callbackArg = runtimeCallInfo->GetCallArgRef(NUM_1);
906     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
907     auto frameNode = reinterpret_cast<FrameNode*>(nativeNode);
908     CHECK_NULL_RETURN(frameNode, panda::JSValueRef::Undefined(vm));
909     if (callbackArg->IsUndefined() || callbackArg->IsNull() || !callbackArg->IsFunction(vm)) {
910         GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorOnCopy(nativeNode);
911         return panda::JSValueRef::Undefined(vm);
912     }
913     panda::Local<panda::FunctionRef> func = callbackArg->ToObject(vm);
914     std::function<void(TextCommonEvent&)> callback = [vm, frameNode,
915         func = panda::CopyableGlobal(vm, func)](TextCommonEvent& event) {
916         panda::LocalScope pandaScope(vm);
917         panda::TryCatch trycatch(vm);
918         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
919         panda::Local<panda::JSValueRef> params[NUM_1];
920         CreateCommonEvent(vm, event, params);
921         func->Call(vm, func.ToLocal(), params, NUM_1);
922     };
923     GetArkUINodeModifiers()->getRichEditorModifier()->setRichEditorOnCopy(
924         nativeNode, reinterpret_cast<void*>(&callback));
925     return panda::JSValueRef::Undefined(vm);
926 }
927 
ResetOnCopy(ArkUIRuntimeCallInfo * runtimeCallInfo)928 ArkUINativeModuleValue RichEditorBridge::ResetOnCopy(ArkUIRuntimeCallInfo* runtimeCallInfo)
929 {
930     EcmaVM* vm = runtimeCallInfo->GetVM();
931     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
932     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(NUM_0);
933     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
934     GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorOnCopy(nativeNode);
935     return panda::JSValueRef::Undefined(vm);
936 }
937 
SetEnterKeyType(ArkUIRuntimeCallInfo * runtimeCallInfo)938 ArkUINativeModuleValue RichEditorBridge::SetEnterKeyType(ArkUIRuntimeCallInfo* runtimeCallInfo)
939 {
940     EcmaVM* vm = runtimeCallInfo->GetVM();
941     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
942     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
943     Local<JSValueRef> secondArg = runtimeCallInfo->GetCallArgRef(1);
944     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
945     uint32_t enterKeyType = static_cast<uint32_t>(TextInputAction::NEW_LINE);
946     if (secondArg->IsNumber()) {
947         enterKeyType = secondArg->Uint32Value(vm);
948         GetArkUINodeModifiers()->getRichEditorModifier()->setRichEditorEnterKeyType(nativeNode, enterKeyType);
949     } else {
950         GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorEnterKeyType(nativeNode);
951     }
952     return panda::JSValueRef::Undefined(vm);
953 }
954 
ResetEnterKeyType(ArkUIRuntimeCallInfo * runtimeCallInfo)955 ArkUINativeModuleValue RichEditorBridge::ResetEnterKeyType(ArkUIRuntimeCallInfo* runtimeCallInfo)
956 {
957     EcmaVM* vm = runtimeCallInfo->GetVM();
958     CHECK_NULL_RETURN(vm, panda::JSValueRef::Undefined(vm));
959     Local<JSValueRef> firstArg = runtimeCallInfo->GetCallArgRef(0);
960     auto nativeNode = nodePtr(firstArg->ToNativePointer(vm)->Value());
961     GetArkUINodeModifiers()->getRichEditorModifier()->resetRichEditorEnterKeyType(nativeNode);
962     return panda::JSValueRef::Undefined(vm);
963 }
964 }