Skip to content

Commit c8ee52e

Browse files
authored
fix: 修复框架升级导致的点击输入框crash (#11)
1 parent 3c18fed commit c8ee52e

21 files changed

+159
-40
lines changed

harmony/text_input_mask.har

45 Bytes
Binary file not shown.

harmony/text_input_mask/Index.ets

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
1-
export * from "./ts";
1+
/*
2+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
3+
* Use of this source code is governed by a MIT license that can be
4+
* found in the LICENSE file.
5+
*/
6+
7+
export * from "./ts";

harmony/text_input_mask/src/main/cpp/RNTextInputMask.cpp

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
#pragma once
1+
/*
2+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
3+
* Use of this source code is governed by a MIT license that can be
4+
* found in the LICENSE file.
5+
*/
6+
27
#include "RNTextInputMask.h"
38
#include "RNOH/arkui/TextInputNode.h"
49
#include "RNOH/ComponentInstance.h"
@@ -29,16 +34,14 @@ void maybeThrow(int32_t status) {
2934
}
3035

3136
void myEventReceiver(ArkUI_NodeEvent *event) {
32-
auto self = reinterpret_cast<RNTextInputMask *>(OH_ArkUI_NodeEvent_GetUserData(event));
33-
if (self == nullptr) {
34-
return;
35-
}
3637
int32_t eventId = OH_ArkUI_NodeEvent_GetTargetId(event);
3738
ArkUI_NodeHandle textNode = OH_ArkUI_NodeEvent_GetNodeHandle(event);
3839
void *data = NativeNodeApi::getInstance()->getUserData(textNode);
3940
auto item = NativeNodeApi::getInstance()->getAttribute(textNode, NODE_TEXT_INPUT_TEXT);
4041
std::string content = item->string;
4142
UserData *userData = reinterpret_cast<UserData *>(data);
43+
auto self = userData->instance;
44+
if (self == nullptr) { return; };
4245
bool isDelete = userData->lastInputText.size() > content.size();
4346
bool useAutocomplete = !isDelete ? userData->maskOptions.autocomplete.value() : false;
4447
bool useAutoskip = isDelete ? userData->maskOptions.autoskip.value() : false;
@@ -60,7 +63,7 @@ void myEventReceiver(ArkUI_NodeEvent *event) {
6063
userData->lastInputText = finalString;
6164
maybeThrow(NativeNodeApi::getInstance()->setAttribute(userData->data, NODE_TEXT_INPUT_TEXT, &item));
6265
} catch (FormatError e) {
63-
DLOG(ERROR) << " mask compiler error " << e.what();
66+
DLOG(ERROR) << " mask complier error " << e.what();
6467
}
6568
}
6669
// onFocus 事件
@@ -72,15 +75,16 @@ void myEventReceiver(ArkUI_NodeEvent *event) {
7275
CaretString string(text, text.length(),
7376
std::make_shared<CaretString::Forward>(userData->maskOptions.autocomplete.value()));
7477
auto maskObj = self->pickMask(string, userData->maskOptions, userData->primaryFormat);
75-
std::string resultString = maskObj.get()->apply(string).formattedText.string;
78+
std::string resultString = maskObj->apply(string).formattedText.string;
7679
ArkUI_AttributeItem item{.string = resultString.c_str()};
7780
maybeThrow(NativeNodeApi::getInstance()->setAttribute(userData->data, NODE_TEXT_INPUT_TEXT, &item));
7881
} catch (FormatError e) {
79-
DLOG(ERROR) << " mask compiler error " << e.what();
82+
DLOG(ERROR) << " mask complier error " << e.what();
8083
}
8184
}
8285
}
8386
}
87+
8488
// 计算亲和度
8589
int calculateAffinity(Mask mask, const CaretString &text, std::string affinityCalculationStrategy) {
8690
AffinityCalculationStrategy strategy;
@@ -183,21 +187,22 @@ void RNTextInputMask::setMask(int reactNode, std::string primaryFormat, MaskOpti
183187
}
184188
ArkUINode &node = input->getLocalRootArkUINode();
185189
TextInputNode *textInputNode = dynamic_cast<TextInputNode *>(&node);
186-
NativeNodeApi::getInstance()->registerNodeEvent(textInputNode->getArkUINodeHandle(), NODE_TEXT_INPUT_ON_CHANGE,
187-
110, this);
188-
NativeNodeApi::getInstance()->registerNodeEvent(textInputNode->getArkUINodeHandle(), NODE_ON_FOCUS, 111, this);
189-
190190
UserData *userData = new UserData({.data = textInputNode->getArkUINodeHandle(),
191191
.maskOptions = maskOptions,
192192
.primaryFormat = primaryFormat,
193-
.node = reactNode});
193+
.node = reactNode,
194+
.instance = this});
195+
NativeNodeApi::getInstance()->registerNodeEvent(textInputNode->getArkUINodeHandle(), NODE_TEXT_INPUT_ON_CHANGE,
196+
110, textInputNode);
197+
NativeNodeApi::getInstance()->registerNodeEvent(textInputNode->getArkUINodeHandle(), NODE_ON_FOCUS, 111,
198+
textInputNode);
194199
this->m_userDatas.insert(userData);
195200
NativeNodeApi::getInstance()->setUserData(textInputNode->getArkUINodeHandle(), userData);
196201
NativeNodeApi::getInstance()->addNodeEventReceiver(textInputNode->getArkUINodeHandle(), myEventReceiver);
197202
};
198203
this->m_ctx.taskExecutor->runTask(TaskThread::MAIN, std::move(task));
199-
200204
}
205+
201206
std::string getString(std::string maskValue, std::string value, bool autocomplete, bool isMask) {
202207

203208
auto maskObj = Mask::MaskFactory::getOrCreate(maskValue, {});
@@ -211,6 +216,7 @@ std::string getString(std::string maskValue, std::string value, bool autocomplet
211216
}
212217
return result;
213218
}
219+
214220
static jsi::Value __hostFunction_RNTextInputMask_unmask(jsi::Runtime &rt, react::TurboModule &turboModule,
215221
const jsi::Value *args, size_t count) {
216222
std::string maskValue = args[0].getString(rt).utf8(rt);
@@ -232,6 +238,7 @@ static jsi::Value __hostFunction_RNTextInputMask_unmask(jsi::Runtime &rt, react:
232238
}
233239
});
234240
}
241+
235242
static jsi::Value __hostFunction_RNTextInputMask_mask(jsi::Runtime &rt, react::TurboModule &turboModule,
236243
const jsi::Value *args, size_t count) {
237244
std::string maskValue = args[0].getString(rt).utf8(rt);
@@ -346,11 +353,21 @@ static jsi::Value __hostFunction_RNTextInputMask_setMask(jsi::Runtime &rt, react
346353

347354
RNTextInputMask::RNTextInputMask(const ArkTSTurboModule::Context ctx, const std::string name)
348355
: ArkTSTurboModule(ctx, name) {
349-
// methodMap_ = {{"setMask", {3, setMask}}};
350356
methodMap_["setMask"] = MethodMetadata{3, __hostFunction_RNTextInputMask_setMask};
351357
methodMap_["mask"] = MethodMetadata{3, __hostFunction_RNTextInputMask_mask};
352358
methodMap_["unmask"] = MethodMetadata{3, __hostFunction_RNTextInputMask_unmask};
353359
}
354360

361+
RNTextInputMask::~RNTextInputMask() {
362+
for (auto userData : m_userDatas) {
363+
if (userData != nullptr) {
364+
NativeNodeApi::getInstance()->unregisterNodeEvent(userData->data, NODE_TEXT_INPUT_ON_CHANGE);
365+
NativeNodeApi::getInstance()->unregisterNodeEvent(userData->data, NODE_ON_FOCUS);
366+
NativeNodeApi::getInstance()->removeNodeEventReceiver(userData->data, myEventReceiver);
367+
delete userData;
368+
userData = nullptr;
369+
}
370+
}
371+
}
355372

356373
// namespace rnoh

harmony/text_input_mask/src/main/cpp/RNTextInputMask.h

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/*
2+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
3+
* Use of this source code is governed by a MIT license that can be
4+
* found in the LICENSE file.
5+
*/
16

27
/**
38
* This code was generated by "react-native codegen-harmony"
@@ -18,7 +23,13 @@
1823
using namespace rnoh;
1924
using namespace facebook;
2025
using namespace TinpMask;
26+
27+
void myEventReceiver(ArkUI_NodeEvent *event);
28+
2129
namespace rnoh {
30+
31+
class RNTextInputMask;
32+
2233
struct MaskParams {
2334
std::string mask; // mask的格式
2435
std::string value; // 待mask的值
@@ -48,42 +59,30 @@ struct MaskOptions {
4859
MaskOptions(const std::vector<std::string> &formats, const std::vector<Notation> &notations,
4960
const std::string &strategy, bool autoComp, bool autoSkip, bool rtl)
5061
: affineFormats(formats), customNotations(notations),
51-
affinityCalculationStrategy(strategy.empty() ? std::nullopt : std::make_optional(strategy)),
62+
affinityCalculationStrategy(strategy.empty() ? std::make_optional("WHOLE_STRING") : std::make_optional(strategy)),
5263
autocomplete(autoComp), autoskip(autoSkip), rightToLeft(rtl) {}
5364
};
65+
5466
typedef struct {
5567
ArkUI_NodeHandle data;
5668
MaskOptions maskOptions;
5769
std::string primaryFormat;
5870
int node;
59-
std::string lastInputText ;
71+
std::string lastInputText;
72+
RNTextInputMask *instance;
6073
} UserData;
6174

6275
class JSI_EXPORT RNTextInputMask : public ArkTSTurboModule {
6376
public:
6477
RNTextInputMask(const ArkTSTurboModule::Context ctx, const std::string name);
65-
// reactNode: number, primaryFormat: string, options: TM.RNTextInputMask.MaskOptions
6678
void setMask(int reactNode, std::string primaryFormat, MaskOptions options);
6779
jsi::Value mask(std::string mask, std::string value, bool autocomplete);
6880
jsi::Value unmask(std::string mask, std::string value, bool autocomplete);
6981
jsi::Runtime *grt = nullptr;
7082
std::shared_ptr<Mask> pickMask(const CaretString &text, MaskOptions maskOptions, std::string primaryMask);
71-
72-
// if (userData->maskOptions != nullptr) {
73-
// delete userData->maskOptions;
74-
// userData->maskOptions = nullptr;
75-
// }
7683

7784
// 释放资源
78-
~RNTextInputMask() {
79-
for (auto userData : m_userDatas) {
80-
if (userData != nullptr) {
81-
delete userData;
82-
userData = nullptr;
83-
}
84-
}
85-
}
86-
85+
~RNTextInputMask();
8786

8887
private:
8988
std::unordered_set<UserData *> m_userDatas;

harmony/text_input_mask/src/main/cpp/RNTextInputMaskPackage.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
#ifndef WORKLETSPACKAGE_H
2-
#define WORKLETSPACKAGE_H
1+
/*
2+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
3+
* Use of this source code is governed by a MIT license that can be
4+
* found in the LICENSE file.
5+
*/
36

7+
#pragma once
48
#include "RNOH/Package.h"
59
#include "RNTextInputMask.h"
610

@@ -25,5 +29,4 @@ class RNTextInputMaskPackage : public Package {
2529
}
2630
// std::vector<ArkTSMessageHandler::Shared> createArkTSMessageHandlers() override;
2731
};
28-
} // namespace rnoh
29-
#endif
32+
} // namespace rnoh

harmony/text_input_mask/src/main/cpp/common/Compiler.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/*
2+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
3+
* Use of this source code is governed by a MIT license that can be
4+
* found in the LICENSE file.
5+
*/
6+
17
#pragma once
28
#include <string>
39
#include <vector>

harmony/text_input_mask/src/main/cpp/common/FormatError.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/*
2+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
3+
* Use of this source code is governed by a MIT license that can be
4+
* found in the LICENSE file.
5+
*/
6+
17
#pragma once
28
// 定义 FormatError 类
39
#include <string>

harmony/text_input_mask/src/main/cpp/common/FormatSanitizer.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/*
2+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
3+
* Use of this source code is governed by a MIT license that can be
4+
* found in the LICENSE file.
5+
*/
6+
17
#pragma once
28
#include <iostream>
39
#include <vector>

harmony/text_input_mask/src/main/cpp/common/Mask.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/*
2+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
3+
* Use of this source code is governed by a MIT license that can be
4+
* found in the LICENSE file.
5+
*/
6+
17
#pragma once
28
#include <string>
39
#include <vector>
@@ -341,9 +347,9 @@ class Mask {
341347
} else if (valueState->type->getName() == StateTypeName::AlphaNumeric) {
342348
return appendPlaceholder(state->child.get(), placeholder + "-");
343349
} else if (valueState->type->getName() == StateTypeName::Custom) {
344-
auto customValueState = dynamic_cast<OptionalValueState *>(state);
350+
auto customValueState = dynamic_cast<ValueState *>(state);
345351
if (customValueState->type.get()) {
346-
auto customStateType = dynamic_cast<OptionalValueState::Custom *>(customValueState->type.get());
352+
auto customStateType = dynamic_cast<ValueState::Custom *>(customValueState->type.get());
347353
return appendPlaceholder(state->child.get(), placeholder + customStateType->character);
348354
}else {
349355
throw FormatError("appendPlaceholder customValueState type is null"); // 未找到匹配项,抛出异常

harmony/text_input_mask/src/main/cpp/common/RTLMask.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/*
2+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
3+
* Use of this source code is governed by a MIT license that can be
4+
* found in the LICENSE file.
5+
*/
6+
17
#pragma once
28
#include "common/Mask.h"
39
#include "common/model/CaretString.h"

harmony/text_input_mask/src/main/cpp/common/model/AffinityCalculationStrategy.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/*
2+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
3+
* Use of this source code is governed by a MIT license that can be
4+
* found in the LICENSE file.
5+
*/
6+
17
#pragma once
28
#include <string>
39
#include <stdexcept>

harmony/text_input_mask/src/main/cpp/common/model/CaretString.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/*
2+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
3+
* Use of this source code is governed by a MIT license that can be
4+
* found in the LICENSE file.
5+
*/
6+
17
#pragma once
28
#include <string>
39
#include <memory>

harmony/text_input_mask/src/main/cpp/common/model/CaretStringIterator.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/*
2+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
3+
* Use of this source code is governed by a MIT license that can be
4+
* found in the LICENSE file.
5+
*/
6+
17
#pragma once
28
#include <string>
39
#include <memory>

harmony/text_input_mask/src/main/cpp/common/model/Next.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/*
2+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
3+
* Use of this source code is governed by a MIT license that can be
4+
* found in the LICENSE file.
5+
*/
6+
17
#pragma once
28
#include <memory>
39
#include "State.h"

harmony/text_input_mask/src/main/cpp/common/model/Notation.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/*
2+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
3+
* Use of this source code is governed by a MIT license that can be
4+
* found in the LICENSE file.
5+
*/
6+
17
#pragma once
28
#include <string>
39

harmony/text_input_mask/src/main/cpp/common/model/RTLCaretStringIterator.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/*
2+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
3+
* Use of this source code is governed by a MIT license that can be
4+
* found in the LICENSE file.
5+
*/
6+
17
#pragma once
28
#include "CaretString.h"
39
#include "CaretStringIterator.h"

harmony/text_input_mask/src/main/cpp/common/model/State.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/*
2+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
3+
* Use of this source code is governed by a MIT license that can be
4+
* found in the LICENSE file.
5+
*/
6+
17
#pragma once
28
#include <memory>
39
#include <iostream>

harmony/text_input_mask/src/main/cpp/common/model/common.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/*
2+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
3+
* Use of this source code is governed by a MIT license that can be
4+
* found in the LICENSE file.
5+
*/
6+
17
#pragma once
28
#include "CaretString.h"
39
#include <string>

harmony/text_input_mask/src/main/ets/RNTextInputMaskPackage.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
/*
2+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
3+
* Use of this source code is governed by a MIT license that can be
4+
* found in the LICENSE file.
5+
*/
6+
17
import { RNPackage, TurboModulesFactory } from '@rnoh/react-native-openharmony/ts';
28
import type { TurboModule, TurboModuleContext } from '@rnoh/react-native-openharmony/ts';
3-
// import { TM } from '@rnoh/react-native-openharmony/generated/ts'
49
import { RNTextInputMaskTurboModule } from './RNTextInputMaskTurboModle';
510

611
class RNTextInputMaskTurboModuleFactory extends TurboModulesFactory {

harmony/text_input_mask/src/main/ets/RNTextInputMaskTurboModle.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/*
2+
* Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
3+
* Use of this source code is governed by a MIT license that can be
4+
* found in the LICENSE file.
5+
*/
6+
17
import { TurboModule, TurboModuleContext } from '@rnoh/react-native-openharmony/ts';
28

39
export class RNTextInputMaskTurboModule extends TurboModule {

0 commit comments

Comments
 (0)