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 }