@react-native-ohos/react-native-text-input-mask 3.1.6-rc.1
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/LICENSE +21 -0
- package/README.OpenSource +11 -0
- package/README.md +134 -0
- package/dist/babel.config.d.ts +7 -0
- package/dist/babel.config.js +16 -0
- package/dist/babel.config.js.map +1 -0
- package/dist/index.d.ts +138 -0
- package/dist/index.js +92 -0
- package/dist/index.js.map +1 -0
- package/dist/src/RNNativeTextInputMask.d.ts +129 -0
- package/dist/src/RNNativeTextInputMask.js +8 -0
- package/dist/src/RNNativeTextInputMask.js.map +1 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.harmony.d.ts +127 -0
- package/dist/src/index.harmony.js +23 -0
- package/dist/src/index.harmony.js.map +1 -0
- package/dist/src/index.js +27 -0
- package/dist/src/index.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/harmony/text_input_mask/BuildProfile.ets +17 -0
- package/harmony/text_input_mask/Index.ets +7 -0
- package/harmony/text_input_mask/build-profile.json5 +31 -0
- package/harmony/text_input_mask/consumer-rules.txt +0 -0
- package/harmony/text_input_mask/hvigorfile.ts +6 -0
- package/harmony/text_input_mask/obfuscation-rules.txt +23 -0
- package/harmony/text_input_mask/oh-package.json5 +11 -0
- package/harmony/text_input_mask/src/main/cpp/CMakeLists.txt +9 -0
- package/harmony/text_input_mask/src/main/cpp/RNTextInputMask.cpp +415 -0
- package/harmony/text_input_mask/src/main/cpp/RNTextInputMask.h +93 -0
- package/harmony/text_input_mask/src/main/cpp/RNTextInputMaskPackage.h +32 -0
- package/harmony/text_input_mask/src/main/cpp/common/Compiler.h +175 -0
- package/harmony/text_input_mask/src/main/cpp/common/FormatError.h +23 -0
- package/harmony/text_input_mask/src/main/cpp/common/FormatSanitizer.h +231 -0
- package/harmony/text_input_mask/src/main/cpp/common/Mask.h +378 -0
- package/harmony/text_input_mask/src/main/cpp/common/RTLMask.h +79 -0
- package/harmony/text_input_mask/src/main/cpp/common/model/AffinityCalculationStrategy.h +58 -0
- package/harmony/text_input_mask/src/main/cpp/common/model/CaretString.h +76 -0
- package/harmony/text_input_mask/src/main/cpp/common/model/CaretStringIterator.h +58 -0
- package/harmony/text_input_mask/src/main/cpp/common/model/Next.h +25 -0
- package/harmony/text_input_mask/src/main/cpp/common/model/Notation.h +25 -0
- package/harmony/text_input_mask/src/main/cpp/common/model/RTLCaretStringIterator.h +23 -0
- package/harmony/text_input_mask/src/main/cpp/common/model/State.h +302 -0
- package/harmony/text_input_mask/src/main/cpp/common/model/common.h +95 -0
- package/harmony/text_input_mask/src/main/ets/RNTextInputMaskPackage.ts +29 -0
- package/harmony/text_input_mask/src/main/ets/RNTextInputMaskTurboModle.ts +33 -0
- package/harmony/text_input_mask/src/main/module.json5 +11 -0
- package/harmony/text_input_mask/src/main/resources/base/element/string.json +8 -0
- package/harmony/text_input_mask/src/main/resources/en_US/element/string.json +8 -0
- package/harmony/text_input_mask/src/main/resources/zh_CN/element/string.json +8 -0
- package/harmony/text_input_mask/ts.ts +8 -0
- package/harmony/text_input_mask.har +0 -0
- package/index.tsx +258 -0
- package/package.json +50 -0
- package/src/RNNativeTextInputMask.ts +143 -0
- package/src/index.harmony.ts +147 -0
- package/src/index.ts +36 -0
|
@@ -0,0 +1,25 @@
|
|
|
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
|
+
#pragma once
|
|
8
|
+
#include <string>
|
|
9
|
+
|
|
10
|
+
namespace TinpMask {
|
|
11
|
+
|
|
12
|
+
class Notation {
|
|
13
|
+
public:
|
|
14
|
+
// 构造函数
|
|
15
|
+
Notation(const char character, const std::string &characterSet, bool isOptional)
|
|
16
|
+
: character(character), characterSet(characterSet), isOptional(isOptional) {}
|
|
17
|
+
|
|
18
|
+
// 成员变量
|
|
19
|
+
char character; // 单个字符作为字符串
|
|
20
|
+
std::string characterSet; // 字符集
|
|
21
|
+
bool isOptional; // 是否可选
|
|
22
|
+
|
|
23
|
+
// 其他方法和成员可以根据需要添加
|
|
24
|
+
};
|
|
25
|
+
} // namespace TinpMask
|
|
@@ -0,0 +1,23 @@
|
|
|
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
|
+
#pragma once
|
|
8
|
+
#include "CaretString.h"
|
|
9
|
+
#include "CaretStringIterator.h"
|
|
10
|
+
|
|
11
|
+
namespace TinpMask {
|
|
12
|
+
|
|
13
|
+
class RTLCaretStringIterator : public CaretStringIterator {
|
|
14
|
+
public:
|
|
15
|
+
RTLCaretStringIterator(const CaretString& caretString)
|
|
16
|
+
: CaretStringIterator(caretString) {}
|
|
17
|
+
|
|
18
|
+
bool insertionAffectsCaret() {
|
|
19
|
+
return currentIndex <= caretString.caretPosition;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
}
|
|
@@ -0,0 +1,302 @@
|
|
|
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
|
+
#pragma once
|
|
8
|
+
#include <memory>
|
|
9
|
+
#include <iostream>
|
|
10
|
+
|
|
11
|
+
namespace TinpMask {
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Next;
|
|
15
|
+
class State {
|
|
16
|
+
public:
|
|
17
|
+
std::shared_ptr<State> child; // 指向下一个状态的智能指针
|
|
18
|
+
|
|
19
|
+
public:
|
|
20
|
+
// 构造函数
|
|
21
|
+
explicit State(std::shared_ptr<State> child = nullptr) : child(child) {}
|
|
22
|
+
|
|
23
|
+
// 虚析构函数,以确保派生类的析构函数被正确调用
|
|
24
|
+
virtual ~State() = default;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Abstract method.
|
|
28
|
+
*
|
|
29
|
+
* Defines whether the state accepts user input character or not, and which actions should take
|
|
30
|
+
* place when the character is accepted.
|
|
31
|
+
*
|
|
32
|
+
* @param character character from the user input string.
|
|
33
|
+
*
|
|
34
|
+
* @returns Next object instance with a set of actions that should take place when the user
|
|
35
|
+
* input character is accepted.
|
|
36
|
+
*
|
|
37
|
+
* @throws Fatal error, if the method is not implemented.
|
|
38
|
+
*/
|
|
39
|
+
virtual std::shared_ptr<Next> accept(char character) = 0;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Automatically complete user input.
|
|
43
|
+
*
|
|
44
|
+
* @returns Next object instance with a set of actions to complete user input. If no
|
|
45
|
+
* autocomplete available, returns nullptr.
|
|
46
|
+
*/
|
|
47
|
+
virtual std::shared_ptr<Next> autocomplete() {
|
|
48
|
+
return nullptr; // 默认返回 nullptr
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Obtain the next state.
|
|
53
|
+
*
|
|
54
|
+
* Sometimes it is necessary to override this behavior. For instance, State may want to
|
|
55
|
+
* return self as the next state under certain conditions.
|
|
56
|
+
*
|
|
57
|
+
* @returns State object.
|
|
58
|
+
*/
|
|
59
|
+
virtual std::shared_ptr<State> nextState() {
|
|
60
|
+
return child; // 返回下一个状态
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// 转换为字符串表示
|
|
64
|
+
virtual std::string toString() const { return "BASE -> " + (child ? child->toString() : "null"); }
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// EOLState 类的实现
|
|
68
|
+
class EOLState : public State {
|
|
69
|
+
public:
|
|
70
|
+
EOLState(std::shared_ptr<State> child = nullptr) : State(child) {}
|
|
71
|
+
|
|
72
|
+
std::shared_ptr<Next> accept(char character) override {
|
|
73
|
+
return nullptr; // 该状态不接受字符
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
std::string toString() const override {
|
|
77
|
+
return "EOL"; // 返回字符串表示
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
// FixedState 类的实现
|
|
83
|
+
class FixedState : public State {
|
|
84
|
+
public:
|
|
85
|
+
char ownCharacter;
|
|
86
|
+
|
|
87
|
+
public:
|
|
88
|
+
FixedState(std::shared_ptr<State> child, char ownCharacter) : State(child), ownCharacter(ownCharacter) {}
|
|
89
|
+
|
|
90
|
+
std::shared_ptr<Next> accept(char character) override {
|
|
91
|
+
if (this->ownCharacter == character) {
|
|
92
|
+
return std::make_shared<Next>(this->nextState(), character, true, character);
|
|
93
|
+
} else {
|
|
94
|
+
return std::make_shared<Next>(this->nextState(), this->ownCharacter, false, this->ownCharacter);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
std::shared_ptr<Next> autocomplete() override {
|
|
99
|
+
return std::make_shared<Next>(this->nextState(), this->ownCharacter, false, this->ownCharacter);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
std::string toString() const override {
|
|
103
|
+
return "{" + std::string(1, this->ownCharacter) + "} -> " + (child ? child->toString() : "null");
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// FreeState 类的实现
|
|
108
|
+
class FreeState : public State {
|
|
109
|
+
public:
|
|
110
|
+
char ownCharacter;
|
|
111
|
+
|
|
112
|
+
public:
|
|
113
|
+
FreeState(std::shared_ptr<State> child, char ownCharacter) : State(child), ownCharacter(ownCharacter) {}
|
|
114
|
+
|
|
115
|
+
std::shared_ptr<Next> accept(char character) override {
|
|
116
|
+
if (this->ownCharacter == character) {
|
|
117
|
+
return std::make_shared<Next>(this->nextState(), character, true, '\0');
|
|
118
|
+
} else {
|
|
119
|
+
return std::make_shared<Next>(this->nextState(), this->ownCharacter, false, '\0');
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
std::shared_ptr<Next> autocomplete() override {
|
|
124
|
+
return std::make_shared<Next>(this->nextState(), this->ownCharacter, false, '\0');
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
std::string toString() const override {
|
|
128
|
+
return std::string(1, this->ownCharacter) + " -> " + (child ? child->toString() : "null");
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
enum StateTypeName { Numeric, Literal, AlphaNumeric, Custom };
|
|
132
|
+
class OptionalValueState : public State {
|
|
133
|
+
public:
|
|
134
|
+
class OptionalValueStateType {
|
|
135
|
+
public:
|
|
136
|
+
virtual StateTypeName getName() = 0;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
class Numeric : public OptionalValueStateType {
|
|
140
|
+
public:
|
|
141
|
+
StateTypeName getName() override { return StateTypeName::Numeric; }
|
|
142
|
+
};
|
|
143
|
+
class Literal : public OptionalValueStateType {
|
|
144
|
+
public:
|
|
145
|
+
StateTypeName getName() override { return StateTypeName::Literal; }
|
|
146
|
+
};
|
|
147
|
+
class AlphaNumeric : public OptionalValueStateType {
|
|
148
|
+
public:
|
|
149
|
+
StateTypeName getName() override { return StateTypeName::AlphaNumeric; }
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
class Custom : public OptionalValueStateType {
|
|
153
|
+
public:
|
|
154
|
+
char character;
|
|
155
|
+
std::string characterSet;
|
|
156
|
+
StateTypeName getName() override { return StateTypeName::Custom; }
|
|
157
|
+
Custom(char character, const std::string &characterSet) : character(character), characterSet(characterSet) {}
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
public:
|
|
161
|
+
std::shared_ptr<OptionalValueStateType> type;
|
|
162
|
+
|
|
163
|
+
bool accepts(char character) {
|
|
164
|
+
if (dynamic_cast<Numeric *>(type.get())) {
|
|
165
|
+
return std::isdigit(character);
|
|
166
|
+
} else if (dynamic_cast<Literal *>(type.get())) {
|
|
167
|
+
return std::isalpha(character);
|
|
168
|
+
} else if (dynamic_cast<AlphaNumeric *>(type.get())) {
|
|
169
|
+
return std::isalnum(character);
|
|
170
|
+
} else if (auto customType = dynamic_cast<Custom *>(type.get())) {
|
|
171
|
+
return customType->characterSet.find(character) != std::string::npos;
|
|
172
|
+
}
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
OptionalValueState(std::shared_ptr<State> child, std::shared_ptr<OptionalValueStateType> type)
|
|
177
|
+
: State(child), type(type) {}
|
|
178
|
+
|
|
179
|
+
OptionalValueState(std::shared_ptr<State> child, std::shared_ptr<OptionalValueStateType> &type)
|
|
180
|
+
: State(child), type(type) {}
|
|
181
|
+
|
|
182
|
+
std::shared_ptr<Next> accept(char character) override {
|
|
183
|
+
if (this->accepts(character)) {
|
|
184
|
+
return std::make_shared<Next>(this->nextState(), character, true, character);
|
|
185
|
+
} else {
|
|
186
|
+
return std::make_shared<Next>(this->nextState(), '\0', false, '\0');
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
std::string toString() const override {
|
|
191
|
+
if (dynamic_cast<Literal *>(type.get())) {
|
|
192
|
+
return "[a] -> " + (child ? child->toString() : "null");
|
|
193
|
+
} else if (dynamic_cast<Numeric *>(type.get())) {
|
|
194
|
+
return "[9] -> " + (child ? child->toString() : "null");
|
|
195
|
+
} else if (dynamic_cast<AlphaNumeric *>(type.get())) {
|
|
196
|
+
return "[-] -> " + (child ? child->toString() : "null");
|
|
197
|
+
} else if (auto customType = dynamic_cast<Custom *>(type.get())) {
|
|
198
|
+
return "[" + std::string(1, customType->character) + "] -> " + (child ? child->toString() : "null");
|
|
199
|
+
}
|
|
200
|
+
return "unknown -> null";
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
// ValueState 类定义
|
|
205
|
+
class ValueState : public State, public std::enable_shared_from_this<ValueState> {
|
|
206
|
+
public:
|
|
207
|
+
class ValueStateType {
|
|
208
|
+
public:
|
|
209
|
+
virtual StateTypeName getName() = 0;
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
class Numeric : public ValueStateType {
|
|
213
|
+
public:
|
|
214
|
+
StateTypeName getName() override { return StateTypeName::Numeric; }
|
|
215
|
+
};
|
|
216
|
+
class Literal : public ValueStateType {
|
|
217
|
+
public:
|
|
218
|
+
StateTypeName getName() override { return StateTypeName::Literal; }
|
|
219
|
+
};
|
|
220
|
+
class AlphaNumeric : public ValueStateType {
|
|
221
|
+
public:
|
|
222
|
+
StateTypeName getName() override { return StateTypeName::AlphaNumeric; }
|
|
223
|
+
};
|
|
224
|
+
class Ellipsis : public ValueStateType {
|
|
225
|
+
public:
|
|
226
|
+
std::shared_ptr<ValueStateType> inheritedType;
|
|
227
|
+
explicit Ellipsis(std::shared_ptr<ValueStateType> inheritedType) : inheritedType(inheritedType) {}
|
|
228
|
+
StateTypeName getName() override { return StateTypeName::Custom; }
|
|
229
|
+
};
|
|
230
|
+
class Custom : public ValueStateType {
|
|
231
|
+
|
|
232
|
+
public:
|
|
233
|
+
char character;
|
|
234
|
+
std::string characterSet;
|
|
235
|
+
Custom(char character, const std::string &characterSet) : character(character), characterSet(characterSet) {}
|
|
236
|
+
StateTypeName getName() override { return StateTypeName::Custom; }
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
public:
|
|
240
|
+
std::shared_ptr<ValueStateType> type;
|
|
241
|
+
bool accepts(char character) {
|
|
242
|
+
if (dynamic_cast<Numeric *>(type.get())) {
|
|
243
|
+
return std::isdigit(character);
|
|
244
|
+
} else if (dynamic_cast<Literal *>(type.get())) {
|
|
245
|
+
return std::isalpha(character);
|
|
246
|
+
} else if (dynamic_cast<AlphaNumeric *>(type.get())) {
|
|
247
|
+
return std::isalnum(character);
|
|
248
|
+
} else if (auto ellipsisType = dynamic_cast<Ellipsis *>(type.get())) {
|
|
249
|
+
return acceptsWithInheritedType(ellipsisType->inheritedType, character);
|
|
250
|
+
} else if (auto customType = dynamic_cast<Custom *>(type.get())) {
|
|
251
|
+
return customType->characterSet.find(character) != std::string::npos;
|
|
252
|
+
}
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
bool acceptsWithInheritedType(std::shared_ptr<ValueStateType> inheritedType, char character) {
|
|
257
|
+
if (dynamic_cast<Numeric *>(inheritedType.get())) {
|
|
258
|
+
return std::isdigit(character);
|
|
259
|
+
} else if (dynamic_cast<Literal *>(inheritedType.get())) {
|
|
260
|
+
return std::isalpha(character);
|
|
261
|
+
} else if (dynamic_cast<AlphaNumeric *>(inheritedType.get())) {
|
|
262
|
+
return std::isalnum(character);
|
|
263
|
+
} else if (auto customType = dynamic_cast<Custom *>(inheritedType.get())) {
|
|
264
|
+
return customType->characterSet.find(character) != std::string::npos;
|
|
265
|
+
}
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
public:
|
|
270
|
+
// 构造函数用于创建 Ellipsis 类型的 ValueState
|
|
271
|
+
ValueState(std::shared_ptr<ValueStateType> inheritedType)
|
|
272
|
+
: State(nullptr), type(std::make_shared<Ellipsis>(inheritedType)) {}
|
|
273
|
+
|
|
274
|
+
ValueState(std::shared_ptr<State> child, std::shared_ptr<ValueStateType> type) : State(child), type(type) {}
|
|
275
|
+
|
|
276
|
+
std::shared_ptr<Next> accept(char character) override {
|
|
277
|
+
if (!accepts(character))
|
|
278
|
+
return nullptr;
|
|
279
|
+
return std::make_shared<Next>(nextState(), character, true, character);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
bool isElliptical() const { return dynamic_cast<Ellipsis *>(type.get()) != nullptr; }
|
|
283
|
+
|
|
284
|
+
std::shared_ptr<State> nextState() override { return isElliptical() ? shared_from_this() : State::nextState(); }
|
|
285
|
+
|
|
286
|
+
std::string toString() const override {
|
|
287
|
+
if (dynamic_cast<Literal *>(type.get())) {
|
|
288
|
+
return "[A] -> " + (child ? child->toString() : "null");
|
|
289
|
+
} else if (dynamic_cast<Numeric *>(type.get())) {
|
|
290
|
+
return "[0] -> " + (child ? child->toString() : "null");
|
|
291
|
+
} else if (dynamic_cast<AlphaNumeric *>(type.get())) {
|
|
292
|
+
return "[_] -> " + (child ? child->toString() : "null");
|
|
293
|
+
} else if (dynamic_cast<Ellipsis *>(type.get())) {
|
|
294
|
+
return "[…] -> " + (child ? child->toString() : "null");
|
|
295
|
+
} else if (auto customType = dynamic_cast<Custom *>(type.get())) {
|
|
296
|
+
return "[" + std::string(1, customType->character) + "] -> " + (child ? child->toString() : "null");
|
|
297
|
+
}
|
|
298
|
+
return "unknown -> null";
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
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
|
+
#pragma once
|
|
8
|
+
#include "CaretString.h"
|
|
9
|
+
#include <string>
|
|
10
|
+
#include <vector>
|
|
11
|
+
#include "State.h"
|
|
12
|
+
#include "Next.h"
|
|
13
|
+
|
|
14
|
+
namespace TinpMask {
|
|
15
|
+
|
|
16
|
+
class Result {
|
|
17
|
+
public:
|
|
18
|
+
// 属性
|
|
19
|
+
CaretString formattedText;
|
|
20
|
+
std::string extractedValue;
|
|
21
|
+
int affinity;
|
|
22
|
+
bool complete;
|
|
23
|
+
std::string tailPlaceholder;
|
|
24
|
+
|
|
25
|
+
// 构造函数
|
|
26
|
+
Result(const CaretString &formattedText, const std::string &extractedValue, int affinity, bool complete,
|
|
27
|
+
const std::string &tailPlaceholder)
|
|
28
|
+
: formattedText(formattedText), extractedValue(extractedValue), affinity(affinity), complete(complete),
|
|
29
|
+
tailPlaceholder(tailPlaceholder) {}
|
|
30
|
+
|
|
31
|
+
// reversed 方法
|
|
32
|
+
Result reversed() const {
|
|
33
|
+
return Result(this->formattedText.reversed(), reverseString(this->extractedValue), this->affinity,
|
|
34
|
+
this->complete, reverseString(this->tailPlaceholder));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private:
|
|
38
|
+
// 辅助函数,用于反转字符串
|
|
39
|
+
std::string reverseString(const std::string &str) const { return std::string(str.rbegin(), str.rend()); }
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* While scanning through the input string in the `.apply(…)` method, the mask builds a graph of
|
|
43
|
+
* autocompletion steps.
|
|
44
|
+
*
|
|
45
|
+
* This graph accumulates the results of `.autocomplete()` calls for each consecutive ``State``,
|
|
46
|
+
* acting as a `stack` of ``Next`` object instances.
|
|
47
|
+
*
|
|
48
|
+
* Each time the ``State`` returns `null` for its `.autocomplete()`, the graph resets empty.
|
|
49
|
+
*/
|
|
50
|
+
class AutocompletionStack {
|
|
51
|
+
private:
|
|
52
|
+
std::vector<Next> stack;
|
|
53
|
+
|
|
54
|
+
public:
|
|
55
|
+
// Push 方法
|
|
56
|
+
std::optional<Next> push(const std::optional<Next> &item) {
|
|
57
|
+
if (item.has_value()) {
|
|
58
|
+
stack.push_back(item.value());
|
|
59
|
+
return item;
|
|
60
|
+
} else {
|
|
61
|
+
clear(); // 清空栈
|
|
62
|
+
return std::nullopt; // 返回 std::nullopt
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// 清空栈的方法
|
|
67
|
+
void clear() { stack.clear(); }
|
|
68
|
+
|
|
69
|
+
// Optional: 获取栈的元素(用于检查或调试)
|
|
70
|
+
std::vector<Next> getStack() const {
|
|
71
|
+
return stack; // 返回当前栈的拷贝
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Optional: 从栈中弹出一个元素
|
|
75
|
+
std::optional<Next> pop() {
|
|
76
|
+
if (stack.empty()) {
|
|
77
|
+
return std::nullopt; // 栈为空时返回 std::nullopt
|
|
78
|
+
}
|
|
79
|
+
Next item = stack.back();
|
|
80
|
+
stack.pop_back();
|
|
81
|
+
return item;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// 检查栈是否为空
|
|
85
|
+
bool isEmpty() const { return stack.empty(); }
|
|
86
|
+
|
|
87
|
+
// Optional: 获取栈顶元素而不移除它
|
|
88
|
+
std::optional<Next> peek() const {
|
|
89
|
+
if (stack.empty()) {
|
|
90
|
+
return std::nullopt; // 栈为空时返回 std::nullopt
|
|
91
|
+
}
|
|
92
|
+
return stack.back();
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
} // namespace TinpMask
|
|
@@ -0,0 +1,29 @@
|
|
|
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
|
+
import { RNPackage, TurboModulesFactory } from '@rnoh/react-native-openharmony/ts';
|
|
8
|
+
import type { TurboModule, TurboModuleContext } from '@rnoh/react-native-openharmony/ts';
|
|
9
|
+
import { RNTextInputMaskTurboModule } from './RNTextInputMaskTurboModle';
|
|
10
|
+
|
|
11
|
+
class RNTextInputMaskTurboModuleFactory extends TurboModulesFactory {
|
|
12
|
+
createTurboModule(name: string): TurboModule | null {
|
|
13
|
+
globalThis.uiAbilityContext = this.ctx.uiAbilityContext
|
|
14
|
+
if (this.hasTurboModule(name)) {
|
|
15
|
+
return new RNTextInputMaskTurboModule(this.ctx);
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
hasTurboModule(name: string): boolean {
|
|
21
|
+
return name === "RNTextInputMask";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export class RNTextInputMaskPackage extends RNPackage {
|
|
26
|
+
createTurboModulesFactory(ctx: TurboModuleContext): TurboModulesFactory {
|
|
27
|
+
return new RNTextInputMaskTurboModuleFactory(ctx);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
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
|
+
import { TurboModule, TurboModuleContext } from '@rnoh/react-native-openharmony/ts';
|
|
8
|
+
|
|
9
|
+
export class RNTextInputMaskTurboModule extends TurboModule {
|
|
10
|
+
private context: TurboModuleContext;
|
|
11
|
+
|
|
12
|
+
constructor(ctx: TurboModuleContext) {
|
|
13
|
+
super(ctx)
|
|
14
|
+
this.context = ctx
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
mask(mask: string, value: string, autocomplete: boolean): Promise<string> {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
unmask(mask: string, value: string, autocomplete: boolean): Promise<string> {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
setMask(reactNode: number, primaryFormat: string, options: object): void {
|
|
26
|
+
console.log("==================", "setMask")
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
unmaskWithRightToLeft(mask: string, value: string, autocomplete: boolean, rightToLeft: boolean): Promise<string> {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
}
|
|
@@ -0,0 +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
|
+
*/
|
|
6
|
+
|
|
7
|
+
export * from './src/main/ets/RNTextInputMaskPackage';
|
|
8
|
+
export * from "./src/main/ets/RNTextInputMaskTurboModle"
|
|
Binary file
|