@react-native-ohos/react-native-text-input-mask 3.1.6-rc.4 → 3.1.6-rc.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc +16 -0
- package/.gitattributes +1 -0
- package/.mtslconfig.json +1 -0
- package/OAT.xml +79 -0
- package/README.md +6 -8
- package/dist/index.d.ts +0 -2
- package/dist/index.js +6 -25
- package/dist/index.js.map +1 -1
- package/dist/src/RNNativeTextInputMask.d.ts +0 -1
- package/dist/src/RNNativeTextInputMask.js.map +1 -1
- package/dist/src/index.harmony.d.ts +0 -1
- package/dist/src/index.harmony.js +0 -3
- package/dist/src/index.harmony.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/harmony/text_input_mask/Index.ets +3 -1
- package/harmony/text_input_mask/oh-package.json5 +2 -2
- package/harmony/text_input_mask/src/main/cpp/RNTextInputMask.cpp +64 -95
- package/harmony/text_input_mask/src/main/cpp/RNTextInputMask.h +10 -9
- package/harmony/text_input_mask/src/main/cpp/RNTextInputMaskPackage.h +4 -2
- package/harmony/text_input_mask/src/main/cpp/common/Compiler.h +84 -81
- package/harmony/text_input_mask/src/main/cpp/common/FormatError.h +5 -5
- package/harmony/text_input_mask/src/main/cpp/common/FormatSanitizer.h +26 -28
- package/harmony/text_input_mask/src/main/cpp/common/Mask.h +48 -45
- package/harmony/text_input_mask/src/main/cpp/common/RTLMask.h +18 -20
- package/harmony/text_input_mask/src/main/cpp/common/model/AffinityCalculationStrategy.h +23 -19
- package/harmony/text_input_mask/src/main/cpp/common/model/CaretString.h +11 -13
- package/harmony/text_input_mask/src/main/cpp/common/model/CaretStringIterator.h +9 -10
- package/harmony/text_input_mask/src/main/cpp/common/model/Next.h +8 -8
- package/harmony/text_input_mask/src/main/cpp/common/model/Notation.h +11 -11
- package/harmony/text_input_mask/src/main/cpp/common/model/RTLCaretStringIterator.h +2 -2
- package/harmony/text_input_mask/src/main/cpp/common/model/State.h +43 -32
- package/harmony/text_input_mask/src/main/cpp/common/model/common.h +19 -11
- package/harmony/text_input_mask/src/main/ets/{RNTextInputMaskPackage.ts → RNTextInputMaskPackage.ets} +2 -1
- package/harmony/text_input_mask/src/main/ets/RNTextInputMaskTurboModle.ts +0 -4
- package/harmony/text_input_mask/src/ohosTest/ets/test/Ability.test.ets +41 -0
- package/harmony/text_input_mask/src/ohosTest/ets/test/List.test.ets +11 -0
- package/harmony/text_input_mask/src/ohosTest/module.json5 +13 -0
- package/harmony/text_input_mask/src/test/List.test.ets +11 -0
- package/harmony/text_input_mask/src/test/LocalUnit.test.ets +39 -0
- package/harmony/text_input_mask.har +0 -0
- package/index.tsx +5 -24
- package/package.json +17 -11
- package/src/RNNativeTextInputMask.ts +0 -1
- package/src/index.harmony.ts +0 -3
- package/tsconfig.json +43 -0
- package/README.OpenSource +0 -11
- package/dist/babel.config.d.ts +0 -7
- package/dist/babel.config.js +0 -16
- package/dist/babel.config.js.map +0 -1
- package/harmony/text_input_mask/BuildProfile.ets +0 -17
- /package/harmony/text_input_mask/{ts.ts → ts.ets} +0 -0
|
@@ -22,9 +22,12 @@ using namespace rnoh;
|
|
|
22
22
|
using namespace react;
|
|
23
23
|
using namespace TinpMask;
|
|
24
24
|
static constexpr int AVOIDENCE = 1;
|
|
25
|
+
static constexpr int EVENT_ID_ONCHANGE = 110;
|
|
26
|
+
static constexpr int EVENT_ID_ONFOCUS = 111;
|
|
25
27
|
std::unordered_map<std::string, std::shared_ptr<RTLMask>> TinpMask::RTLMask::cache;
|
|
26
28
|
std::unordered_map<std::string, std::shared_ptr<Mask>> TinpMask::Mask::MaskFactory::maskCache;
|
|
27
|
-
void maybeThrow(int32_t status)
|
|
29
|
+
void maybeThrow(int32_t status)
|
|
30
|
+
{
|
|
28
31
|
DLOG(INFO) << "=====text change maybeThrow status: " << status;
|
|
29
32
|
if (status != 0) {
|
|
30
33
|
auto message = std::string("ArkUINode operation failed with status: ") + std::to_string(status);
|
|
@@ -33,7 +36,8 @@ void maybeThrow(int32_t status) {
|
|
|
33
36
|
}
|
|
34
37
|
}
|
|
35
38
|
|
|
36
|
-
void myEventReceiver(ArkUI_NodeEvent *event)
|
|
39
|
+
void myEventReceiver(ArkUI_NodeEvent *event)
|
|
40
|
+
{
|
|
37
41
|
int32_t eventId = OH_ArkUI_NodeEvent_GetTargetId(event);
|
|
38
42
|
ArkUI_NodeHandle textNode = OH_ArkUI_NodeEvent_GetNodeHandle(event);
|
|
39
43
|
void *data = NativeNodeApi::getInstance()->getUserData(textNode);
|
|
@@ -41,11 +45,12 @@ void myEventReceiver(ArkUI_NodeEvent *event) {
|
|
|
41
45
|
std::string content = item->string;
|
|
42
46
|
UserData *userData = reinterpret_cast<UserData *>(data);
|
|
43
47
|
auto self = userData->instance;
|
|
44
|
-
if (self == nullptr) {
|
|
48
|
+
if (self == nullptr) {
|
|
49
|
+
return;
|
|
50
|
+
};
|
|
45
51
|
bool isDelete = userData->lastInputText.size() >= content.size();
|
|
46
52
|
bool useAutocomplete = !isDelete ? userData->maskOptions.autocomplete.value() : false;
|
|
47
53
|
bool useAutoskip = isDelete ? userData->maskOptions.autoskip.value() : false;
|
|
48
|
-
|
|
49
54
|
// onChange 事件
|
|
50
55
|
if (eventId == userData->node) {
|
|
51
56
|
std::shared_ptr<CaretString::CaretGravity> caretGravity = nullptr;
|
|
@@ -65,26 +70,30 @@ void myEventReceiver(ArkUI_NodeEvent *event) {
|
|
|
65
70
|
content = resultString;
|
|
66
71
|
}
|
|
67
72
|
std::string finalString = isDelete ? content : resultString;
|
|
68
|
-
ArkUI_AttributeItem item{
|
|
73
|
+
ArkUI_AttributeItem item{
|
|
74
|
+
.string = finalString.c_str()
|
|
75
|
+
};
|
|
69
76
|
userData->lastInputText = finalString;
|
|
70
77
|
maybeThrow(NativeNodeApi::getInstance()->setAttribute(userData->data, NODE_TEXT_INPUT_TEXT, &item));
|
|
71
|
-
} catch (FormatError e) {
|
|
78
|
+
} catch (const FormatError &e) {
|
|
72
79
|
DLOG(ERROR) << " mask complier error " << e.what();
|
|
73
80
|
}
|
|
74
81
|
}
|
|
75
82
|
// onFocus 事件
|
|
76
|
-
if (eventId ==
|
|
83
|
+
if (eventId == EVENT_ID_ONFOCUS) {
|
|
77
84
|
if (userData->maskOptions.autocomplete.value()) {
|
|
78
85
|
std::string text = "";
|
|
79
86
|
text += content;
|
|
80
87
|
try {
|
|
81
88
|
CaretString string(text, text.length(),
|
|
82
|
-
|
|
89
|
+
std::make_shared<CaretString::Forward>(userData->maskOptions.autocomplete.value()));
|
|
83
90
|
auto maskObj = self->pickMask(string, userData->maskOptions, userData->primaryFormat);
|
|
84
91
|
std::string resultString = maskObj->apply(string).formattedText.string;
|
|
85
|
-
ArkUI_AttributeItem item{
|
|
92
|
+
ArkUI_AttributeItem item{
|
|
93
|
+
.string = resultString.c_str()
|
|
94
|
+
};
|
|
86
95
|
maybeThrow(NativeNodeApi::getInstance()->setAttribute(userData->data, NODE_TEXT_INPUT_TEXT, &item));
|
|
87
|
-
} catch (FormatError e) {
|
|
96
|
+
} catch (const FormatError &e) {
|
|
88
97
|
DLOG(ERROR) << " mask complier error " << e.what();
|
|
89
98
|
}
|
|
90
99
|
}
|
|
@@ -92,7 +101,8 @@ void myEventReceiver(ArkUI_NodeEvent *event) {
|
|
|
92
101
|
}
|
|
93
102
|
|
|
94
103
|
// 计算亲和度
|
|
95
|
-
int calculateAffinity(Mask mask, const CaretString &text, std::string affinityCalculationStrategy)
|
|
104
|
+
int calculateAffinity(Mask mask, const CaretString &text, std::string affinityCalculationStrategy)
|
|
105
|
+
{
|
|
96
106
|
AffinityCalculationStrategy strategy;
|
|
97
107
|
if (affinityCalculationStrategy == "WHOLE_STRING") {
|
|
98
108
|
strategy = AffinityCalculationStrategy::WHOLE_STRING;
|
|
@@ -109,7 +119,8 @@ int calculateAffinity(Mask mask, const CaretString &text, std::string affinityCa
|
|
|
109
119
|
}
|
|
110
120
|
// 获取或创建 Mask
|
|
111
121
|
std::shared_ptr<Mask> maskGetOrCreate(const std::string &format, const std::vector<Notation> &customNotations,
|
|
112
|
-
|
|
122
|
+
bool rightToLeft)
|
|
123
|
+
{
|
|
113
124
|
if (rightToLeft) {
|
|
114
125
|
return RTLMask::getOrCreate(format, customNotations);
|
|
115
126
|
} else {
|
|
@@ -118,13 +129,14 @@ std::shared_ptr<Mask> maskGetOrCreate(const std::string &format, const std::vect
|
|
|
118
129
|
}
|
|
119
130
|
|
|
120
131
|
std::shared_ptr<Mask> RNTextInputMask::pickMask(const CaretString &text, MaskOptions maskOptions,
|
|
121
|
-
|
|
132
|
+
std::string primaryMask)
|
|
133
|
+
{
|
|
122
134
|
// 如果 affineFormats 为空,直接返回 primaryMask
|
|
123
135
|
if (maskOptions.affineFormats->size() <= 0) {
|
|
124
136
|
auto mask = maskGetOrCreate(primaryMask, maskOptions.customNotations.value(), maskOptions.rightToLeft.value());
|
|
125
137
|
int affinity = calculateAffinity(*mask, text, maskOptions.affinityCalculationStrategy.value());
|
|
126
|
-
DLOG(INFO) << " ======= pickMask calculateAffinity value: " << affinity
|
|
127
|
-
|
|
138
|
+
DLOG(INFO) << " ======= pickMask calculateAffinity value: " << affinity <<
|
|
139
|
+
"\n affinityCalculationStrategy: " << maskOptions.affinityCalculationStrategy.value();
|
|
128
140
|
return mask;
|
|
129
141
|
}
|
|
130
142
|
// 定义 MaskAffinity 结构体,用于存储 Mask 和相应的亲和度
|
|
@@ -136,8 +148,8 @@ std::shared_ptr<Mask> RNTextInputMask::pickMask(const CaretString &text, MaskOpt
|
|
|
136
148
|
|
|
137
149
|
// 计算 primaryMask 的亲和度
|
|
138
150
|
int primaryAffinity = calculateAffinity(primaryMask, text, maskOptions.affinityCalculationStrategy.value());
|
|
139
|
-
DLOG(INFO) << " ======= pickMask calculateAffinity value: " << primaryAffinity << " \n mask: " << primaryMask
|
|
140
|
-
|
|
151
|
+
DLOG(INFO) << " ======= pickMask calculateAffinity value: " << primaryAffinity << " \n mask: " << primaryMask <<
|
|
152
|
+
"\n affinityCalculationStrategy: " << maskOptions.affinityCalculationStrategy.value();
|
|
141
153
|
// 存储所有 mask 和亲和度的列表
|
|
142
154
|
std::vector<MaskAffinity> masksAndAffinities;
|
|
143
155
|
|
|
@@ -146,14 +158,14 @@ std::shared_ptr<Mask> RNTextInputMask::pickMask(const CaretString &text, MaskOpt
|
|
|
146
158
|
std::shared_ptr<Mask> mask =
|
|
147
159
|
maskGetOrCreate(format, maskOptions.customNotations.value(), maskOptions.rightToLeft.value());
|
|
148
160
|
int affinity = calculateAffinity(*mask, text, maskOptions.affinityCalculationStrategy.value());
|
|
149
|
-
DLOG(INFO) << " ======= pickMask calculateAffinity value: " << affinity << "\n affineFormat: " << format
|
|
150
|
-
|
|
161
|
+
DLOG(INFO) << " ======= pickMask calculateAffinity value: " << affinity << "\n affineFormat: " << format <<
|
|
162
|
+
"\n affinityCalculationStrategy: " << maskOptions.affinityCalculationStrategy.value();
|
|
151
163
|
masksAndAffinities.emplace_back(*mask, affinity);
|
|
152
164
|
}
|
|
153
165
|
|
|
154
166
|
// 按亲和度降序排序
|
|
155
167
|
std::sort(masksAndAffinities.begin(), masksAndAffinities.end(),
|
|
156
|
-
|
|
168
|
+
[](const MaskAffinity &a, const MaskAffinity &b) { return a.affinity > b.affinity; });
|
|
157
169
|
|
|
158
170
|
// 寻找插入位置
|
|
159
171
|
int insertIndex = -1;
|
|
@@ -175,7 +187,8 @@ std::shared_ptr<Mask> RNTextInputMask::pickMask(const CaretString &text, MaskOpt
|
|
|
175
187
|
return std::make_shared<Mask>(masksAndAffinities.front().mask);
|
|
176
188
|
}
|
|
177
189
|
|
|
178
|
-
void RNTextInputMask::setMask(int reactNode, std::string primaryFormat, MaskOptions maskOptions)
|
|
190
|
+
void RNTextInputMask::setMask(int reactNode, std::string primaryFormat, MaskOptions maskOptions)
|
|
191
|
+
{
|
|
179
192
|
auto task = [this, reactNode, primaryFormat, maskOptions] {
|
|
180
193
|
auto weakInstance = m_ctx.instance;
|
|
181
194
|
auto instance = weakInstance.lock();
|
|
@@ -193,24 +206,24 @@ void RNTextInputMask::setMask(int reactNode, std::string primaryFormat, MaskOpti
|
|
|
193
206
|
}
|
|
194
207
|
ArkUINode &node = input->getLocalRootArkUINode();
|
|
195
208
|
TextInputNode *textInputNode = dynamic_cast<TextInputNode *>(&node);
|
|
196
|
-
UserData *userData = new UserData({
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
209
|
+
UserData *userData = new UserData({
|
|
210
|
+
.data = textInputNode->getArkUINodeHandle(),
|
|
211
|
+
.maskOptions = maskOptions,
|
|
212
|
+
.primaryFormat = primaryFormat,
|
|
213
|
+
.node = reactNode,
|
|
214
|
+
.instance = this });
|
|
201
215
|
NativeNodeApi::getInstance()->registerNodeEvent(textInputNode->getArkUINodeHandle(), NODE_TEXT_INPUT_ON_CHANGE,
|
|
202
|
-
|
|
216
|
+
reactNode, textInputNode);
|
|
203
217
|
NativeNodeApi::getInstance()->registerNodeEvent(textInputNode->getArkUINodeHandle(), NODE_ON_FOCUS, 111,
|
|
204
|
-
|
|
218
|
+
textInputNode);
|
|
205
219
|
this->m_userDatas.insert(userData);
|
|
206
220
|
NativeNodeApi::getInstance()->setUserData(textInputNode->getArkUINodeHandle(), userData);
|
|
207
221
|
NativeNodeApi::getInstance()->addNodeEventReceiver(textInputNode->getArkUINodeHandle(), myEventReceiver);
|
|
208
222
|
};
|
|
209
223
|
this->m_ctx.taskExecutor->runTask(TaskThread::MAIN, std::move(task));
|
|
210
224
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
225
|
+
std::string getString(std::string maskValue, std::string value, bool autocomplete, bool isMask)
|
|
226
|
+
{
|
|
214
227
|
auto maskObj = Mask::MaskFactory::getOrCreate(maskValue, {});
|
|
215
228
|
CaretString text(value, value.length(), std::make_shared<CaretString::Forward>(autocomplete));
|
|
216
229
|
auto r = maskObj->apply(text);
|
|
@@ -222,32 +235,14 @@ std::string getString(std::string maskValue, std::string value, bool autocomplet
|
|
|
222
235
|
}
|
|
223
236
|
return result;
|
|
224
237
|
}
|
|
225
|
-
|
|
226
|
-
std::string getString(std::string maskValue, std::string value, bool autocomplete, bool isMask, bool rightToLeft) {
|
|
227
|
-
std::shared_ptr<Mask> maskObj;
|
|
228
|
-
if (rightToLeft) {
|
|
229
|
-
maskObj = RTLMask::getOrCreate(maskValue, {});
|
|
230
|
-
} else {
|
|
231
|
-
maskObj = Mask::MaskFactory::getOrCreate(maskValue, {});
|
|
232
|
-
}
|
|
233
|
-
CaretString text(value, value.length(), std::make_shared<CaretString::Forward>(autocomplete));
|
|
234
|
-
auto r = maskObj->apply(text);
|
|
235
|
-
std::string result;
|
|
236
|
-
if (isMask) {
|
|
237
|
-
result = r.formattedText.string;
|
|
238
|
-
} else {
|
|
239
|
-
result = r.extractedValue;
|
|
240
|
-
}
|
|
241
|
-
return result;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
238
|
static jsi::Value __hostFunction_RNTextInputMask_unmask(jsi::Runtime &rt, react::TurboModule &turboModule,
|
|
245
|
-
|
|
239
|
+
const jsi::Value *args, size_t count)
|
|
240
|
+
{
|
|
246
241
|
std::string maskValue = args[0].getString(rt).utf8(rt);
|
|
247
242
|
std::string value = args[1].getString(rt).utf8(rt);
|
|
248
243
|
bool autocomplete = args[2].getBool();
|
|
249
|
-
return createPromiseAsJSIValue(
|
|
250
|
-
|
|
244
|
+
return createPromiseAsJSIValue(rt,
|
|
245
|
+
[maskValue, value, autocomplete](jsi::Runtime &rt2, std::shared_ptr<facebook::react::Promise> promise) {
|
|
251
246
|
try {
|
|
252
247
|
auto start = std::chrono::high_resolution_clock::now();
|
|
253
248
|
std::string result = getString(maskValue, value, autocomplete, 0);
|
|
@@ -262,37 +257,14 @@ static jsi::Value __hostFunction_RNTextInputMask_unmask(jsi::Runtime &rt, react:
|
|
|
262
257
|
}
|
|
263
258
|
});
|
|
264
259
|
}
|
|
265
|
-
|
|
266
|
-
static jsi::Value __hostFunction_RNTextInputMask_unmaskWithRightToLeft(jsi::Runtime &rt, react::TurboModule &turboModule,
|
|
267
|
-
const jsi::Value *args, size_t count) {
|
|
268
|
-
std::string maskValue = args[0].getString(rt).utf8(rt);
|
|
269
|
-
std::string value = args[1].getString(rt).utf8(rt);
|
|
270
|
-
bool autocomplete = args[2].getBool();
|
|
271
|
-
bool rightToLeft = args[3].getBool();
|
|
272
|
-
return createPromiseAsJSIValue(
|
|
273
|
-
rt, [maskValue, value, autocomplete, rightToLeft](jsi::Runtime &rt2, std::shared_ptr<facebook::react::Promise> promise) {
|
|
274
|
-
try {
|
|
275
|
-
auto start = std::chrono::high_resolution_clock::now();
|
|
276
|
-
std::string result = getString(maskValue, value, autocomplete, 0, rightToLeft);
|
|
277
|
-
promise->resolve(jsi::String::createFromUtf8(rt2, result));
|
|
278
|
-
// 获取结束时间点
|
|
279
|
-
auto end = std::chrono::high_resolution_clock::now();
|
|
280
|
-
// 计算延迟
|
|
281
|
-
std::chrono::duration<double, std::milli> latency = end - start;
|
|
282
|
-
DLOG(INFO) << "=======unmask 响应时长: " << latency.count() << " 毫秒" << std::endl;
|
|
283
|
-
} catch (FormatError e) {
|
|
284
|
-
promise->reject(e.what());
|
|
285
|
-
}
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
|
|
289
260
|
static jsi::Value __hostFunction_RNTextInputMask_mask(jsi::Runtime &rt, react::TurboModule &turboModule,
|
|
290
|
-
|
|
261
|
+
const jsi::Value *args, size_t count)
|
|
262
|
+
{
|
|
291
263
|
std::string maskValue = args[0].getString(rt).utf8(rt);
|
|
292
264
|
std::string value = args[1].getString(rt).utf8(rt);
|
|
293
265
|
bool autocomplete = args[2].getBool();
|
|
294
|
-
return createPromiseAsJSIValue(
|
|
295
|
-
|
|
266
|
+
return createPromiseAsJSIValue(rt,
|
|
267
|
+
[maskValue, value, autocomplete](jsi::Runtime &rt2, std::shared_ptr<facebook::react::Promise> promise) {
|
|
296
268
|
try {
|
|
297
269
|
auto start = std::chrono::high_resolution_clock::now();
|
|
298
270
|
std::string result = getString(maskValue, value, autocomplete, 1);
|
|
@@ -307,10 +279,9 @@ static jsi::Value __hostFunction_RNTextInputMask_mask(jsi::Runtime &rt, react::T
|
|
|
307
279
|
}
|
|
308
280
|
});
|
|
309
281
|
}
|
|
310
|
-
|
|
311
282
|
static jsi::Value __hostFunction_RNTextInputMask_setMask(jsi::Runtime &rt, react::TurboModule &turboModule,
|
|
312
|
-
|
|
313
|
-
|
|
283
|
+
const jsi::Value *args, size_t count)
|
|
284
|
+
{
|
|
314
285
|
auto turbo = static_cast<RNTextInputMask *>(&turboModule);
|
|
315
286
|
if (turbo->grt == nullptr) {
|
|
316
287
|
turbo->grt = &rt;
|
|
@@ -330,8 +301,8 @@ static jsi::Value __hostFunction_RNTextInputMask_setMask(jsi::Runtime &rt, react
|
|
|
330
301
|
for (size_t i = 0; i < length; ++i) {
|
|
331
302
|
// 获取数组元素
|
|
332
303
|
jsi::Value value = arrayAffineFormats.getValueAtIndex(rt, i);
|
|
333
|
-
std::cout << "===affineFormats index" + std::to_string(i) << "--" << value.getString(rt).utf8(rt)
|
|
334
|
-
|
|
304
|
+
std::cout << "===affineFormats index" + std::to_string(i) << "--" << value.getString(rt).utf8(rt) <<
|
|
305
|
+
std::endl;
|
|
335
306
|
affineFormatsValues.push_back(value.getString(rt).utf8(rt));
|
|
336
307
|
}
|
|
337
308
|
} else {
|
|
@@ -369,8 +340,6 @@ static jsi::Value __hostFunction_RNTextInputMask_setMask(jsi::Runtime &rt, react
|
|
|
369
340
|
std::cerr << "====The property 'myArray' is not an array." << std::endl;
|
|
370
341
|
}
|
|
371
342
|
}
|
|
372
|
-
|
|
373
|
-
|
|
374
343
|
std::string affinityCalculationStrategy;
|
|
375
344
|
if (obj.hasProperty(rt, "affinityCalculationStrategy") &&
|
|
376
345
|
!obj.getProperty(rt, "affinityCalculationStrategy").isUndefined()) {
|
|
@@ -393,20 +362,20 @@ static jsi::Value __hostFunction_RNTextInputMask_setMask(jsi::Runtime &rt, react
|
|
|
393
362
|
}
|
|
394
363
|
|
|
395
364
|
auto maskOptions = new MaskOptions(affineFormatsValues, customNotationsValues, affinityCalculationStrategy,
|
|
396
|
-
|
|
365
|
+
autocomplete, autoskip, rightToLeft);
|
|
397
366
|
static_cast<RNTextInputMask *>(&turboModule)->setMask(reactNode, primaryFormat, *maskOptions);
|
|
398
367
|
return jsi::Value::undefined();
|
|
399
368
|
}
|
|
400
369
|
|
|
401
370
|
RNTextInputMask::RNTextInputMask(const ArkTSTurboModule::Context ctx, const std::string name)
|
|
402
|
-
: ArkTSTurboModule(ctx, name)
|
|
403
|
-
|
|
404
|
-
methodMap_["
|
|
405
|
-
methodMap_["
|
|
406
|
-
methodMap_["
|
|
371
|
+
: ArkTSTurboModule(ctx, name)
|
|
372
|
+
{
|
|
373
|
+
methodMap_["setMask"] = MethodMetadata{ 3, __hostFunction_RNTextInputMask_setMask };
|
|
374
|
+
methodMap_["mask"] = MethodMetadata{ 3, __hostFunction_RNTextInputMask_mask };
|
|
375
|
+
methodMap_["unmask"] = MethodMetadata{ 3, __hostFunction_RNTextInputMask_unmask };
|
|
407
376
|
}
|
|
408
|
-
|
|
409
|
-
|
|
377
|
+
RNTextInputMask::~RNTextInputMask()
|
|
378
|
+
{
|
|
410
379
|
for (auto userData : m_userDatas) {
|
|
411
380
|
if (userData != nullptr) {
|
|
412
381
|
NativeNodeApi::getInstance()->unregisterNodeEvent(userData->data, NODE_TEXT_INPUT_ON_CHANGE);
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
*
|
|
13
13
|
* @generatorVersion: 1
|
|
14
14
|
*/
|
|
15
|
+
#ifndef RNTEXTINPUTMASK_H
|
|
16
|
+
#define RNTEXTINPUTMASK_H
|
|
15
17
|
#pragma once
|
|
16
18
|
|
|
17
19
|
#include "RNOH/ArkTSTurboModule.h"
|
|
@@ -37,7 +39,8 @@ struct MaskParams {
|
|
|
37
39
|
MaskParams() = default;
|
|
38
40
|
MaskParams(const std::string &m, const std::string &v, std::optional<bool> autoComplete = std::nullopt)
|
|
39
41
|
: mask(m), value(v), autocomplete(autoComplete) {} // 构造函数
|
|
40
|
-
MaskParams &operator=(const MaskParams &input)
|
|
42
|
+
MaskParams &operator=(const MaskParams &input)
|
|
43
|
+
{
|
|
41
44
|
this->mask = input.mask;
|
|
42
45
|
this->value = input.value;
|
|
43
46
|
this->autocomplete = input.autocomplete;
|
|
@@ -55,12 +58,13 @@ struct MaskOptions {
|
|
|
55
58
|
|
|
56
59
|
MaskOptions()
|
|
57
60
|
: affineFormats(std::vector<std::string>()), customNotations(std::vector<Notation>()),
|
|
58
|
-
|
|
61
|
+
affinityCalculationStrategy(std::nullopt), autocomplete(true), autoskip(false), rightToLeft(false) {}
|
|
59
62
|
MaskOptions(const std::vector<std::string> &formats, const std::vector<Notation> ¬ations,
|
|
60
|
-
|
|
63
|
+
const std::string &strategy, bool autoComp, bool autoSkip, bool rtl)
|
|
61
64
|
: affineFormats(formats), customNotations(notations),
|
|
62
|
-
|
|
63
|
-
|
|
65
|
+
affinityCalculationStrategy(strategy.empty() ?
|
|
66
|
+
std::make_optional("WHOLE_STRING") : std::make_optional(strategy)),
|
|
67
|
+
autocomplete(autoComp), autoskip(autoSkip), rightToLeft(rtl) {}
|
|
64
68
|
};
|
|
65
69
|
|
|
66
70
|
typedef struct {
|
|
@@ -78,16 +82,13 @@ public:
|
|
|
78
82
|
void setMask(int reactNode, std::string primaryFormat, MaskOptions options);
|
|
79
83
|
jsi::Value mask(std::string mask, std::string value, bool autocomplete);
|
|
80
84
|
jsi::Value unmask(std::string mask, std::string value, bool autocomplete);
|
|
81
|
-
jsi::Value unmaskWithRightToLeft(std::string mask, std::string value, bool autocomplete, bool rightToLeft);
|
|
82
85
|
jsi::Runtime *grt = nullptr;
|
|
83
86
|
std::shared_ptr<Mask> pickMask(const CaretString &text, MaskOptions maskOptions, std::string primaryMask);
|
|
84
|
-
|
|
85
87
|
// 释放资源
|
|
86
88
|
~RNTextInputMask();
|
|
87
89
|
|
|
88
90
|
private:
|
|
89
91
|
std::unordered_set<UserData *> m_userDatas;
|
|
90
92
|
};
|
|
91
|
-
|
|
92
|
-
|
|
93
93
|
} // namespace rnoh
|
|
94
|
+
#endif
|
|
@@ -13,7 +13,8 @@ using namespace facebook;
|
|
|
13
13
|
namespace rnoh {
|
|
14
14
|
class RNTextInputMaskTurboModuleFactoryDelegate : public TurboModuleFactoryDelegate {
|
|
15
15
|
public:
|
|
16
|
-
SharedTurboModule createTurboModule(Context ctx, const std::string &name) const override
|
|
16
|
+
SharedTurboModule createTurboModule(Context ctx, const std::string &name) const override
|
|
17
|
+
{
|
|
17
18
|
if (name == "RNTextInputMask") {
|
|
18
19
|
return std::make_shared<RNTextInputMask>(ctx, name);
|
|
19
20
|
}
|
|
@@ -24,7 +25,8 @@ public:
|
|
|
24
25
|
class RNTextInputMaskPackage : public Package {
|
|
25
26
|
public:
|
|
26
27
|
RNTextInputMaskPackage(Package::Context ctx) : Package(ctx) {}
|
|
27
|
-
std::unique_ptr<TurboModuleFactoryDelegate> createTurboModuleFactoryDelegate() override
|
|
28
|
+
std::unique_ptr<TurboModuleFactoryDelegate> createTurboModuleFactoryDelegate() override
|
|
29
|
+
{
|
|
28
30
|
return std::make_unique<RNTextInputMaskTurboModuleFactoryDelegate>();
|
|
29
31
|
}
|
|
30
32
|
// std::vector<ArkTSMessageHandler::Shared> createArkTSMessageHandlers() override;
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* Use of this source code is governed by a MIT license that can be
|
|
4
4
|
* found in the LICENSE file.
|
|
5
5
|
*/
|
|
6
|
-
|
|
6
|
+
#ifndef COMPILER_H
|
|
7
|
+
#define COMPILER_H
|
|
7
8
|
#pragma once
|
|
8
9
|
#include <string>
|
|
9
10
|
#include <vector>
|
|
@@ -23,86 +24,86 @@ private:
|
|
|
23
24
|
std::vector<Notation> customNotations;
|
|
24
25
|
|
|
25
26
|
public:
|
|
26
|
-
Compiler(const std::vector<Notation> ¬ations) : customNotations(notations) {}
|
|
27
|
+
explicit Compiler(const std::vector<Notation> ¬ations) : customNotations(notations) {}
|
|
27
28
|
|
|
28
|
-
std::shared_ptr<State> compile(const std::string &formatString)
|
|
29
|
+
std::shared_ptr<State> compile(const std::string &formatString)
|
|
30
|
+
{
|
|
29
31
|
FormatSanitizer sanitizer;
|
|
30
32
|
std::string sanitizedString = sanitizer.sanitize(formatString);
|
|
31
33
|
return compile(sanitizedString, false, false, '\0');
|
|
32
34
|
}
|
|
33
35
|
|
|
34
|
-
std::shared_ptr<State> compile(const std::string &formatString, bool valuable, bool fixed, char lastCharacter)
|
|
36
|
+
std::shared_ptr<State> compile(const std::string &formatString, bool valuable, bool fixed, char lastCharacter)
|
|
37
|
+
{
|
|
35
38
|
if (formatString.empty()) {
|
|
36
39
|
return std::make_shared<EOLState>();
|
|
37
40
|
}
|
|
38
|
-
|
|
39
41
|
char ch = formatString.front();
|
|
40
42
|
switch (ch) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
case '{':
|
|
48
|
-
if (lastCharacter != '\\') {
|
|
49
|
-
return compile(formatString.substr(1), false, true, ch);
|
|
50
|
-
}
|
|
51
|
-
break;
|
|
43
|
+
case '[':
|
|
44
|
+
if (lastCharacter != '\\') {
|
|
45
|
+
return compile(formatString.substr(1), true, false, ch);
|
|
46
|
+
}
|
|
47
|
+
break;
|
|
52
48
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
break;
|
|
49
|
+
case '{':
|
|
50
|
+
if (lastCharacter != '\\') {
|
|
51
|
+
return compile(formatString.substr(1), false, true, ch);
|
|
52
|
+
}
|
|
53
|
+
break;
|
|
59
54
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
55
|
+
case ']':
|
|
56
|
+
case '}':
|
|
57
|
+
if (lastCharacter != '\\') {
|
|
58
|
+
return compile(formatString.substr(1), false, false, ch);
|
|
59
|
+
}
|
|
60
|
+
break;
|
|
65
61
|
|
|
66
|
-
|
|
67
|
-
|
|
62
|
+
case '\\':
|
|
63
|
+
if (lastCharacter != '\\') {
|
|
64
|
+
return compile(formatString.substr(1), valuable, fixed, ch);
|
|
65
|
+
}
|
|
66
|
+
break;
|
|
67
|
+
default:
|
|
68
|
+
break;
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
if (valuable) {
|
|
71
72
|
switch (ch) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
case '0':
|
|
74
|
+
return std::make_shared<ValueState>(
|
|
75
|
+
this->compile(formatString.substr(1), true, false, ch),
|
|
76
|
+
// std::static_pointer_cast<ValueState::StateType>( std::make_shared<ValueState::Numeric>())
|
|
77
|
+
std::make_shared<ValueState::Numeric>());
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
case 'A':
|
|
80
|
+
return std::make_shared<ValueState>(this->compile(formatString.substr(1), true, false, ch),
|
|
81
|
+
std::make_shared<ValueState::Literal>());
|
|
81
82
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
case '_':
|
|
84
|
+
return std::make_shared<ValueState>(this->compile(formatString.substr(1), true, false, ch),
|
|
85
|
+
std::make_shared<ValueState::AlphaNumeric>());
|
|
85
86
|
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
case '...':
|
|
88
|
+
return std::make_unique<ValueState>(determineInheritedType(lastCharacter));
|
|
88
89
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
case '9':
|
|
91
|
+
return std::make_shared<OptionalValueState>(this->compile(formatString.substr(1), true, false, ch),
|
|
92
|
+
std::make_shared<OptionalValueState::Numeric>()
|
|
92
93
|
|
|
93
|
-
|
|
94
|
+
);
|
|
94
95
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
case 'a':
|
|
97
|
+
return std::make_shared<OptionalValueState>(this->compile(formatString.substr(1), true, false, ch),
|
|
98
|
+
std::make_shared<OptionalValueState::Literal>());
|
|
98
99
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
case '-':
|
|
101
|
+
return std::make_shared<OptionalValueState>(this->compile(formatString.substr(1), true, false, ch),
|
|
102
|
+
std::make_shared<OptionalValueState::AlphaNumeric>());
|
|
102
103
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
default:
|
|
105
|
+
return compileWithCustomNotations(ch, formatString);
|
|
106
|
+
}
|
|
106
107
|
}
|
|
107
108
|
if (fixed) {
|
|
108
109
|
return std::make_shared<FixedState>(compile(formatString.substr(1), false, true, ch), ch);
|
|
@@ -110,18 +111,21 @@ public:
|
|
|
110
111
|
return std::make_shared<FreeState>(compile(formatString.substr(1), false, false, ch), ch);
|
|
111
112
|
}
|
|
112
113
|
|
|
113
|
-
std::unique_ptr<State> compileWithCustomNotations(char c, const std::string &str)
|
|
114
|
-
|
|
114
|
+
std::unique_ptr<State> compileWithCustomNotations(char c, const std::string &str)
|
|
115
|
+
{
|
|
116
|
+
DLOG(ERROR) << "====== compileWithCustomNotations customNotations size: " << customNotations.size();
|
|
115
117
|
for (const auto &customNotation : customNotations) {
|
|
116
118
|
if (customNotation.character == c) {
|
|
117
119
|
std::shared_ptr<State> compiledState = compile(str.substr(1), true, false, c);
|
|
118
120
|
if (customNotation.isOptional) {
|
|
119
|
-
DLOG(ERROR) << "====== compileWithCustomNotations customNotations isOptional :"
|
|
121
|
+
DLOG(ERROR) << "====== compileWithCustomNotations customNotations isOptional :"
|
|
122
|
+
<< customNotation.isOptional;
|
|
120
123
|
return std::make_unique<OptionalValueState>(
|
|
121
124
|
std::move(compiledState),
|
|
122
125
|
std::make_shared<OptionalValueState::Custom>(c, customNotation.characterSet));
|
|
123
126
|
} else {
|
|
124
|
-
|
|
127
|
+
DLOG(ERROR) << "======= compileWithCustomNotations customNotations isOptional :"
|
|
128
|
+
<< customNotation.isOptional;
|
|
125
129
|
return std::make_unique<ValueState>(
|
|
126
130
|
std::move(compiledState), std::make_shared<ValueState::Custom>(c, customNotation.characterSet));
|
|
127
131
|
}
|
|
@@ -130,46 +134,45 @@ public:
|
|
|
130
134
|
DLOG(INFO) << "compileWithCustomNotations No Match Found ";
|
|
131
135
|
throw FormatError("compileWithCustomNotations No Match Found");
|
|
132
136
|
}
|
|
133
|
-
std::shared_ptr<ValueState::ValueStateType> determineInheritedType(std::optional<char> lastCharacter)
|
|
137
|
+
std::shared_ptr<ValueState::ValueStateType> determineInheritedType(std::optional<char> lastCharacter)
|
|
138
|
+
{
|
|
134
139
|
if (!lastCharacter.has_value()) {
|
|
135
140
|
throw FormatError(); // 处理空字符情况,抛出异常
|
|
136
141
|
}
|
|
137
142
|
char character = lastCharacter.value();
|
|
138
143
|
switch (character) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
default:
|
|
154
|
-
return determineTypeWithCustomNotations(lastCharacter);
|
|
144
|
+
case '0':
|
|
145
|
+
case '9':
|
|
146
|
+
return std::make_shared<ValueState::Numeric>();
|
|
147
|
+
case 'A':
|
|
148
|
+
case 'a':
|
|
149
|
+
return std::make_shared<ValueState::Literal>();
|
|
150
|
+
case '_':
|
|
151
|
+
case '-':
|
|
152
|
+
case '...':
|
|
153
|
+
case '[':
|
|
154
|
+
return std::make_shared<ValueState::AlphaNumeric>();
|
|
155
|
+
default:
|
|
156
|
+
return determineTypeWithCustomNotations(lastCharacter);
|
|
155
157
|
}
|
|
156
158
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
+
std::shared_ptr<ValueState::ValueStateType> determineTypeWithCustomNotations(std::optional<char> lastCharacter)
|
|
160
|
+
{
|
|
159
161
|
if (!lastCharacter.has_value()) {
|
|
160
162
|
throw FormatError(); // 处理空字符情况,抛出异常
|
|
161
163
|
}
|
|
162
|
-
|
|
164
|
+
DLOG(INFO) << "======determineTypeWithCustomNotations customNotations size: "<<customNotations.size();
|
|
163
165
|
char character = lastCharacter.value();
|
|
164
166
|
for (const auto &customNotation : customNotations) {
|
|
165
167
|
if (customNotation.character == character) {
|
|
166
168
|
// 返回 Custom 状态
|
|
167
169
|
return std::make_shared<ValueState::Custom>(lastCharacter.value(),
|
|
168
|
-
|
|
170
|
+
customNotation.characterSet); // 可以根据需要调整返回内容
|
|
169
171
|
}
|
|
170
172
|
}
|
|
171
173
|
DLOG(INFO) << "determineTypeWithCustomNotations No Match Found ";
|
|
172
174
|
throw FormatError("determineTypeWithCustomNotations No Match Found"); // 未找到匹配项,抛出异常
|
|
173
175
|
}
|
|
174
176
|
};
|
|
175
|
-
} // namespace TinpMask
|
|
177
|
+
} // namespace TinpMask
|
|
178
|
+
#endif
|