@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
|
@@ -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 FORMATERROR_H
|
|
7
|
+
#define FORMATERROR_H
|
|
7
8
|
#pragma once
|
|
8
9
|
// 定义 FormatError 类
|
|
9
10
|
#include <string>
|
|
@@ -13,11 +14,10 @@ class FormatError : public std::exception {
|
|
|
13
14
|
public:
|
|
14
15
|
// 构造函数接受错误消息
|
|
15
16
|
explicit FormatError(const std::string &message = "An error occurred") : msg(message) {}
|
|
16
|
-
|
|
17
17
|
// 重写 what() 方法,返回错误消息
|
|
18
|
-
const char *what() const noexcept { return msg.c_str(); }
|
|
19
|
-
|
|
18
|
+
const char *what() const noexcept override { return msg.c_str(); }
|
|
20
19
|
private:
|
|
21
20
|
std::string msg; // 存储错误消息
|
|
22
21
|
};
|
|
23
|
-
} // namespace TinpMask
|
|
22
|
+
} // namespace TinpMask
|
|
23
|
+
#endif
|
|
@@ -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 FORMATSANITIZER_H
|
|
7
|
+
#define FORMATSANITIZER_H
|
|
7
8
|
#pragma once
|
|
8
9
|
#include <iostream>
|
|
9
10
|
#include <vector>
|
|
@@ -17,13 +18,15 @@ namespace TinpMask {
|
|
|
17
18
|
class Compiler;
|
|
18
19
|
class FormatSanitizer {
|
|
19
20
|
public:
|
|
20
|
-
std::string sanitize(const std::string &formatString)
|
|
21
|
+
std::string sanitize(const std::string &formatString)
|
|
22
|
+
{
|
|
21
23
|
checkOpenBraces(formatString);
|
|
22
24
|
std::vector<std::string> blocks = divideBlocksWithMixedCharacters(getFormatBlocks(formatString));
|
|
23
25
|
return sortFormatBlocks(blocks);
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
std::vector<std::string> getFormatBlocks(const std::string &formatString)
|
|
28
|
+
std::vector<std::string> getFormatBlocks(const std::string &formatString)
|
|
29
|
+
{
|
|
27
30
|
std::vector<std::string> blocks;
|
|
28
31
|
std::string currentBlock;
|
|
29
32
|
bool escape = false;
|
|
@@ -36,36 +39,30 @@ public:
|
|
|
36
39
|
continue;
|
|
37
40
|
}
|
|
38
41
|
}
|
|
39
|
-
|
|
40
42
|
if ((ch == '[' || ch == '{') && !escape) {
|
|
41
43
|
if (!currentBlock.empty()) {
|
|
42
44
|
blocks.push_back(currentBlock);
|
|
43
45
|
}
|
|
44
46
|
currentBlock.clear();
|
|
45
47
|
}
|
|
46
|
-
|
|
47
48
|
currentBlock += ch;
|
|
48
49
|
|
|
49
50
|
if ((ch == ']' || ch == '}') && !escape) {
|
|
50
51
|
blocks.push_back(currentBlock);
|
|
51
52
|
currentBlock.clear();
|
|
52
53
|
}
|
|
53
|
-
|
|
54
54
|
escape = false;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
if (!currentBlock.empty()) {
|
|
58
58
|
blocks.push_back(currentBlock);
|
|
59
59
|
}
|
|
60
|
-
|
|
61
60
|
return blocks;
|
|
62
61
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
62
|
public:
|
|
66
|
-
std::vector<std::string> divideBlocksWithMixedCharacters(const std::vector<std::string> &blocks)
|
|
63
|
+
std::vector<std::string> divideBlocksWithMixedCharacters(const std::vector<std::string> &blocks)
|
|
64
|
+
{
|
|
67
65
|
std::vector<std::string> resultingBlocks;
|
|
68
|
-
|
|
69
66
|
for (const auto &block : blocks) {
|
|
70
67
|
if (!block.empty() && block.substr(0, 1) == "[") { // 使用 substr 来检查开头
|
|
71
68
|
std::string blockBuffer;
|
|
@@ -114,7 +111,6 @@ public:
|
|
|
114
111
|
resultingBlocks.push_back(block);
|
|
115
112
|
}
|
|
116
113
|
}
|
|
117
|
-
|
|
118
114
|
return resultingBlocks;
|
|
119
115
|
}
|
|
120
116
|
|
|
@@ -127,7 +123,8 @@ private:
|
|
|
127
123
|
|
|
128
124
|
bool isSpecialCharacter(char ch) const { return ch == '-' || ch == '_'; }
|
|
129
125
|
|
|
130
|
-
bool containsAny(const std::string &str, const std::vector<char> &characters) const
|
|
126
|
+
bool containsAny(const std::string &str, const std::vector<char> &characters) const
|
|
127
|
+
{
|
|
131
128
|
for (char c : characters) {
|
|
132
129
|
if (str.find(c) != std::string::npos) {
|
|
133
130
|
return true;
|
|
@@ -135,9 +132,9 @@ private:
|
|
|
135
132
|
}
|
|
136
133
|
return false;
|
|
137
134
|
}
|
|
138
|
-
|
|
139
135
|
public:
|
|
140
|
-
std::string sortFormatBlocks(const std::vector<std::string> &blocks)
|
|
136
|
+
std::string sortFormatBlocks(const std::vector<std::string> &blocks)
|
|
137
|
+
{
|
|
141
138
|
std::vector<std::string> sortedBlocks;
|
|
142
139
|
|
|
143
140
|
for (const auto &block : blocks) {
|
|
@@ -162,12 +159,11 @@ public:
|
|
|
162
159
|
|
|
163
160
|
return join(sortedBlocks); // Ensure this is returning std::vector<std::string>
|
|
164
161
|
}
|
|
165
|
-
|
|
166
|
-
|
|
162
|
+
void checkOpenBraces(const std::string &inputString)
|
|
163
|
+
{
|
|
167
164
|
bool escape = false;
|
|
168
165
|
bool squareBraceOpen = false;
|
|
169
166
|
bool curlyBraceOpen = false;
|
|
170
|
-
|
|
171
167
|
for (const char &ch : inputString) {
|
|
172
168
|
if (ch == '\\') {
|
|
173
169
|
escape = !escape;
|
|
@@ -191,7 +187,6 @@ public:
|
|
|
191
187
|
}
|
|
192
188
|
curlyBraceOpen = !escape;
|
|
193
189
|
}
|
|
194
|
-
|
|
195
190
|
if (ch == '}' && !escape) {
|
|
196
191
|
curlyBraceOpen = false;
|
|
197
192
|
}
|
|
@@ -200,27 +195,29 @@ public:
|
|
|
200
195
|
}
|
|
201
196
|
|
|
202
197
|
private:
|
|
203
|
-
bool startsWith(const std::string &str,
|
|
204
|
-
|
|
205
|
-
std::string sortString(std::string str)
|
|
198
|
+
bool startsWith(const std::string &str,
|
|
199
|
+
const std::string &prefix) const { return str.rfind(prefix, 0) == 0; }
|
|
200
|
+
std::string sortString(std::string str)
|
|
201
|
+
{
|
|
206
202
|
std::sort(str.begin(), str.end());
|
|
207
203
|
return str;
|
|
208
204
|
}
|
|
209
|
-
|
|
210
|
-
|
|
205
|
+
std::string replaceChars(const std::string &str)
|
|
206
|
+
{
|
|
211
207
|
std::string newStr = str;
|
|
212
208
|
std::replace(newStr.begin(), newStr.end(), '_', 'A');
|
|
213
209
|
std::replace(newStr.begin(), newStr.end(), '-', 'a');
|
|
214
210
|
return newStr;
|
|
215
211
|
}
|
|
216
|
-
|
|
217
|
-
|
|
212
|
+
std::string replaceCharsBack(const std::string &str)
|
|
213
|
+
{
|
|
218
214
|
std::string newStr = str;
|
|
219
215
|
std::replace(newStr.begin(), newStr.end(), 'A', '_');
|
|
220
216
|
std::replace(newStr.begin(), newStr.end(), 'a', '-');
|
|
221
217
|
return newStr;
|
|
222
218
|
}
|
|
223
|
-
std::string join(const std::vector<std::string> &strings)
|
|
219
|
+
std::string join(const std::vector<std::string> &strings)
|
|
220
|
+
{
|
|
224
221
|
std::string result;
|
|
225
222
|
for (const auto &str : strings) {
|
|
226
223
|
result += str; // 将所有块连接成一个字符串
|
|
@@ -228,4 +225,5 @@ private:
|
|
|
228
225
|
return result;
|
|
229
226
|
}
|
|
230
227
|
};
|
|
231
|
-
} // namespace TinpMask
|
|
228
|
+
} // namespace TinpMask
|
|
229
|
+
#endif
|
|
@@ -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 MASK_H
|
|
7
|
+
#define MASK_H
|
|
7
8
|
#pragma once
|
|
8
9
|
#include <string>
|
|
9
10
|
#include <vector>
|
|
@@ -15,7 +16,6 @@
|
|
|
15
16
|
#include "model/State.h"
|
|
16
17
|
|
|
17
18
|
namespace TinpMask {
|
|
18
|
-
|
|
19
19
|
class Mask {
|
|
20
20
|
protected:
|
|
21
21
|
std::vector<Notation> customNotations;
|
|
@@ -28,21 +28,24 @@ private:
|
|
|
28
28
|
|
|
29
29
|
public:
|
|
30
30
|
// 主构造函数
|
|
31
|
-
Mask(const std::string &format, const std::vector<Notation> &customNotations) : customNotations(customNotations)
|
|
31
|
+
Mask(const std::string &format, const std::vector<Notation> &customNotations) : customNotations(customNotations)
|
|
32
|
+
{
|
|
32
33
|
this->format = format;
|
|
33
34
|
this->customNotations = customNotations;
|
|
34
35
|
this->initialState = Compiler(customNotations).compile(format);
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
// 便利构造函数
|
|
38
|
-
Mask(const std::string &format) : Mask(format, {})
|
|
39
|
+
Mask(const std::string &format) : Mask(format, {})
|
|
40
|
+
{ // 调用主构造函数,传入空的 customNotations
|
|
39
41
|
std::vector<Notation> emptyVector;
|
|
40
42
|
this->format = format;
|
|
41
43
|
this->customNotations = emptyVector;
|
|
42
44
|
this->initialState = Compiler(this->customNotations).compile(this->format);
|
|
43
45
|
}
|
|
44
46
|
|
|
45
|
-
|
|
47
|
+
bool hasSameCustomNotations(const std::vector<Notation> &targetNotations) const
|
|
48
|
+
{
|
|
46
49
|
return this->customNotations == targetNotations;
|
|
47
50
|
}
|
|
48
51
|
|
|
@@ -51,7 +54,7 @@ public:
|
|
|
51
54
|
static std::unordered_map<std::string, std::shared_ptr<Mask>> maskCache;
|
|
52
55
|
|
|
53
56
|
public:
|
|
54
|
-
|
|
57
|
+
/* *
|
|
55
58
|
* Factory constructor.
|
|
56
59
|
*
|
|
57
60
|
* Operates over own ``Mask`` cache where initialized ``Mask`` objects are stored under
|
|
@@ -61,7 +64,8 @@ public:
|
|
|
61
64
|
* doesn't exist in cache, the object is constructed, cached and returned.
|
|
62
65
|
*/
|
|
63
66
|
static std::shared_ptr<Mask> getOrCreate(const std::string &format,
|
|
64
|
-
|
|
67
|
+
const std::vector<Notation> &customNotations)
|
|
68
|
+
{
|
|
65
69
|
auto cachedMask = maskCache.find(format);
|
|
66
70
|
if (cachedMask == maskCache.end() || !cachedMask->second->hasSameCustomNotations(customNotations)) {
|
|
67
71
|
auto newMask = std::make_shared<Mask>(format, customNotations);
|
|
@@ -71,7 +75,7 @@ public:
|
|
|
71
75
|
return cachedMask->second;
|
|
72
76
|
}
|
|
73
77
|
|
|
74
|
-
|
|
78
|
+
/* *
|
|
75
79
|
* Check your mask format is valid.
|
|
76
80
|
*
|
|
77
81
|
* @param format mask format.
|
|
@@ -80,7 +84,8 @@ public:
|
|
|
80
84
|
* @returns `true` if this format coupled with custom notations will compile into a working ``Mask`` object.
|
|
81
85
|
* Otherwise `false`.
|
|
82
86
|
*/
|
|
83
|
-
static bool isValid(const std::string &format, const std::vector<Notation> &customNotations)
|
|
87
|
+
static bool isValid(const std::string &format, const std::vector<Notation> &customNotations)
|
|
88
|
+
{
|
|
84
89
|
try {
|
|
85
90
|
Mask(format, customNotations);
|
|
86
91
|
return true;
|
|
@@ -89,14 +94,15 @@ public:
|
|
|
89
94
|
}
|
|
90
95
|
}
|
|
91
96
|
};
|
|
92
|
-
|
|
97
|
+
/* *
|
|
93
98
|
* Apply mask to the user input string.
|
|
94
99
|
*
|
|
95
100
|
* @param text user input string with current cursor position
|
|
96
101
|
*
|
|
97
102
|
* @returns Formatted text with extracted value an adjusted cursor position.
|
|
98
103
|
*/
|
|
99
|
-
virtual Result apply(const CaretString &text)
|
|
104
|
+
virtual Result apply(const CaretString &text)
|
|
105
|
+
{
|
|
100
106
|
auto iterator = makeIterator(text); // Assume this function is defined
|
|
101
107
|
|
|
102
108
|
int affinity = 0;
|
|
@@ -112,7 +118,6 @@ public:
|
|
|
112
118
|
char character = iterator->next();
|
|
113
119
|
while (character != '\0') {
|
|
114
120
|
auto next = state->accept(character);
|
|
115
|
-
|
|
116
121
|
if (next != nullptr) {
|
|
117
122
|
if (deletionAffectsCaret) {
|
|
118
123
|
auto opt = state->autocomplete();
|
|
@@ -155,9 +160,9 @@ public:
|
|
|
155
160
|
|
|
156
161
|
while (text.caretGravity->autocomplete() && insertionAffectsCaret) {
|
|
157
162
|
auto next = state->autocomplete();
|
|
158
|
-
if (next == nullptr)
|
|
163
|
+
if (next == nullptr) {
|
|
159
164
|
break;
|
|
160
|
-
|
|
165
|
+
}
|
|
161
166
|
state = next->state;
|
|
162
167
|
if (next->insert == '\0') {
|
|
163
168
|
modifiedString += "";
|
|
@@ -197,34 +202,35 @@ public:
|
|
|
197
202
|
std::string tailPlaceholder = appendPlaceholder(tailState.get(), tail); // Assume this function is defined
|
|
198
203
|
|
|
199
204
|
return Result(CaretString(modifiedString, modifiedCaretPosition, text.caretGravity), extractedValue, affinity,
|
|
200
|
-
|
|
201
|
-
tailPlaceholder);
|
|
205
|
+
noMandatoryCharactersLeftAfterState(state.get()), tailPlaceholder);
|
|
202
206
|
}
|
|
203
207
|
|
|
204
|
-
|
|
205
208
|
public:
|
|
206
|
-
std::shared_ptr<CaretStringIterator> makeIterator(const CaretString &text) const
|
|
209
|
+
std::shared_ptr<CaretStringIterator> makeIterator(const CaretString &text) const
|
|
210
|
+
{
|
|
207
211
|
return std::make_shared<CaretStringIterator>(text);
|
|
208
212
|
}
|
|
209
|
-
|
|
210
|
-
/**
|
|
213
|
+
/* *
|
|
211
214
|
* Generate placeholder.
|
|
212
215
|
*
|
|
213
216
|
* @return Placeholder string.
|
|
214
217
|
*/
|
|
215
218
|
public:
|
|
216
|
-
std::string placeholder()
|
|
217
|
-
|
|
219
|
+
std::string placeholder()
|
|
220
|
+
{
|
|
221
|
+
return appendPlaceholder(initialState.get(), "");
|
|
222
|
+
}
|
|
223
|
+
/* *
|
|
218
224
|
* Minimal length of the text inside the field to fill all mandatory characters in the mask.
|
|
219
225
|
*
|
|
220
226
|
* @return Minimal satisfying count of characters inside the text field.
|
|
221
227
|
*/
|
|
222
228
|
public:
|
|
223
|
-
int acceptableTextLength()
|
|
229
|
+
int acceptableTextLength()
|
|
230
|
+
{
|
|
224
231
|
std::shared_ptr<State> state = std::move(initialState);
|
|
225
232
|
;
|
|
226
233
|
int length = 0;
|
|
227
|
-
|
|
228
234
|
while (state != nullptr && dynamic_cast<EOLState *>(state.get()) == nullptr) {
|
|
229
235
|
if (dynamic_cast<FixedState *>(state.get()) != nullptr ||
|
|
230
236
|
dynamic_cast<FreeState *>(state.get()) != nullptr ||
|
|
@@ -233,18 +239,16 @@ public:
|
|
|
233
239
|
}
|
|
234
240
|
state = state->child; // 移动到下一个子状态
|
|
235
241
|
}
|
|
236
|
-
|
|
237
242
|
return length;
|
|
238
243
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
/**
|
|
244
|
+
/* *
|
|
242
245
|
* Maximal length of the text inside the field.
|
|
243
246
|
*
|
|
244
247
|
* @return Total available count of mandatory and optional characters inside the text field.
|
|
245
248
|
*/
|
|
246
249
|
public:
|
|
247
|
-
int totalTextLength() const
|
|
250
|
+
int totalTextLength() const
|
|
251
|
+
{
|
|
248
252
|
std::shared_ptr<State> state = initialState;
|
|
249
253
|
;
|
|
250
254
|
int length = 0;
|
|
@@ -258,16 +262,16 @@ public:
|
|
|
258
262
|
}
|
|
259
263
|
state = state->child; // 移动到下一个子状态
|
|
260
264
|
}
|
|
261
|
-
|
|
262
265
|
return length;
|
|
263
266
|
}
|
|
264
|
-
|
|
267
|
+
/* *
|
|
265
268
|
* Minimal length of the extracted value with all mandatory characters filled.\
|
|
266
269
|
*
|
|
267
270
|
* @return Minimal satisfying count of characters in extracted value.
|
|
268
271
|
*/
|
|
269
272
|
public:
|
|
270
|
-
int acceptableValueLength() const
|
|
273
|
+
int acceptableValueLength() const
|
|
274
|
+
{
|
|
271
275
|
std::shared_ptr<State> state = initialState;
|
|
272
276
|
int length = 0;
|
|
273
277
|
while (state != nullptr && dynamic_cast<EOLState *>(state.get()) == nullptr) {
|
|
@@ -277,16 +281,16 @@ public:
|
|
|
277
281
|
}
|
|
278
282
|
state = state->child; // 移动到下一个子状态
|
|
279
283
|
}
|
|
280
|
-
|
|
281
284
|
return length;
|
|
282
285
|
}
|
|
283
|
-
|
|
286
|
+
/* *
|
|
284
287
|
* Maximal length of the extracted value.
|
|
285
288
|
*
|
|
286
289
|
* @return Total available count of mandatory and optional characters for extracted value.
|
|
287
290
|
*/
|
|
288
291
|
public:
|
|
289
|
-
int totalValueLength() const
|
|
292
|
+
int totalValueLength() const
|
|
293
|
+
{
|
|
290
294
|
std::shared_ptr<State> state = initialState;
|
|
291
295
|
int length = 0;
|
|
292
296
|
while (state != nullptr && dynamic_cast<EOLState *>(state.get()) == nullptr) {
|
|
@@ -301,7 +305,8 @@ public:
|
|
|
301
305
|
}
|
|
302
306
|
|
|
303
307
|
private:
|
|
304
|
-
std::string appendPlaceholder(State *state, const std::string &placeholder) const
|
|
308
|
+
std::string appendPlaceholder(State *state, const std::string &placeholder) const
|
|
309
|
+
{
|
|
305
310
|
if (state == nullptr) {
|
|
306
311
|
return placeholder;
|
|
307
312
|
}
|
|
@@ -337,7 +342,6 @@ private:
|
|
|
337
342
|
return placeholder; // 未知类型,返回原始 placeholder
|
|
338
343
|
}
|
|
339
344
|
}
|
|
340
|
-
|
|
341
345
|
if (auto valueState = dynamic_cast<ValueState *>(state)) {
|
|
342
346
|
if (!state) {
|
|
343
347
|
return placeholder; // 如果 state 为 nullptr,直接返回原始 placeholder
|
|
@@ -354,19 +358,17 @@ private:
|
|
|
354
358
|
if (customValueState->type.get()) {
|
|
355
359
|
auto customStateType = dynamic_cast<ValueState::Custom *>(customValueState->type.get());
|
|
356
360
|
return appendPlaceholder(state->child.get(), placeholder + customStateType->character);
|
|
357
|
-
}else {
|
|
358
|
-
throw FormatError("appendPlaceholder customValueState type is null");
|
|
361
|
+
} else {
|
|
362
|
+
throw FormatError("appendPlaceholder customValueState type is null");
|
|
359
363
|
}
|
|
360
|
-
|
|
361
364
|
} else {
|
|
362
|
-
return placeholder;
|
|
365
|
+
return placeholder;
|
|
363
366
|
}
|
|
364
367
|
}
|
|
365
|
-
|
|
366
368
|
return placeholder;
|
|
367
369
|
}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
+
bool noMandatoryCharactersLeftAfterState(State *state) const
|
|
371
|
+
{
|
|
370
372
|
if (dynamic_cast<EOLState *>(state)) {
|
|
371
373
|
return true;
|
|
372
374
|
} else if (auto valueState = dynamic_cast<ValueState *>(state)) {
|
|
@@ -378,4 +380,5 @@ private:
|
|
|
378
380
|
}
|
|
379
381
|
}
|
|
380
382
|
};
|
|
381
|
-
} // namespace TinpMask
|
|
383
|
+
} // namespace TinpMask
|
|
384
|
+
#endif
|
|
@@ -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 RTLMASK_H
|
|
7
|
+
#define RTLMASK_H
|
|
7
8
|
#pragma once
|
|
8
9
|
#include "common/Mask.h"
|
|
9
10
|
#include "common/model/CaretString.h"
|
|
@@ -13,11 +14,12 @@ namespace TinpMask {
|
|
|
13
14
|
class RTLMask : public Mask {
|
|
14
15
|
|
|
15
16
|
public:
|
|
16
|
-
|
|
17
|
+
static std::unordered_map<std::string, std::shared_ptr<RTLMask>> cache ;
|
|
17
18
|
RTLMask(const std::string& format, const std::vector<Notation>& customNotations)
|
|
18
19
|
: Mask(reversedFormat(format), customNotations) {}
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
static std::shared_ptr<RTLMask> getOrCreate(const std::string& format,
|
|
21
|
+
const std::vector<Notation>& customNotations)
|
|
22
|
+
{
|
|
21
23
|
std::string reversed = reversedFormat(format);
|
|
22
24
|
auto it = cache.find(reversed);
|
|
23
25
|
if (it != cache.end()) {
|
|
@@ -29,40 +31,35 @@ public:
|
|
|
29
31
|
cache[reversed] = newMask;
|
|
30
32
|
return newMask;
|
|
31
33
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
Result apply(const CaretString& text) override
|
|
35
|
+
{
|
|
34
36
|
return Mask::apply(text.reversed()).reversed(); // Assuming the Result class has a reversed method
|
|
35
37
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
38
|
private:
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
static constexpr size_t ESCAPED_BRACKET_LENGTH = 2;
|
|
40
|
+
static std::string reversedFormat(const std::string& format)
|
|
41
|
+
{
|
|
42
42
|
std::string reversed = std::string(format.rbegin(), format.rend());
|
|
43
|
-
|
|
44
|
-
// Replace logic (equivalent to Kotlin's replace)
|
|
45
43
|
size_t pos = 0;
|
|
46
44
|
while ((pos = reversed.find("\\[", pos)) != std::string::npos) {
|
|
47
|
-
reversed.replace(pos,
|
|
48
|
-
pos += 1;
|
|
45
|
+
reversed.replace(pos, ESCAPED_BRACKET_LENGTH, "\\");
|
|
46
|
+
pos += 1;
|
|
49
47
|
}
|
|
50
48
|
pos = 0;
|
|
51
49
|
while ((pos = reversed.find("]\\", pos)) != std::string::npos) {
|
|
52
|
-
reversed.replace(pos,
|
|
50
|
+
reversed.replace(pos, ESCAPED_BRACKET_LENGTH, "\\[");
|
|
53
51
|
pos += 1;
|
|
54
52
|
}
|
|
55
53
|
pos = 0;
|
|
56
54
|
while ((pos = reversed.find("\\{", pos)) != std::string::npos) {
|
|
57
|
-
reversed.replace(pos,
|
|
55
|
+
reversed.replace(pos, ESCAPED_BRACKET_LENGTH, "\\}");
|
|
58
56
|
pos += 1;
|
|
59
57
|
}
|
|
60
58
|
pos = 0;
|
|
61
59
|
while ((pos = reversed.find("}\\", pos)) != std::string::npos) {
|
|
62
|
-
reversed.replace(pos,
|
|
60
|
+
reversed.replace(pos, ESCAPED_BRACKET_LENGTH, "\\{");
|
|
63
61
|
pos += 1;
|
|
64
62
|
}
|
|
65
|
-
|
|
66
63
|
// Map logic for brackets
|
|
67
64
|
for (char& ch : reversed) {
|
|
68
65
|
switch (ch) {
|
|
@@ -76,4 +73,5 @@ private:
|
|
|
76
73
|
return reversed;
|
|
77
74
|
}
|
|
78
75
|
};
|
|
79
|
-
}
|
|
76
|
+
}
|
|
77
|
+
#endif
|
|
@@ -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 AFFINITYCALCULATIONSTRATEGY_H
|
|
7
|
+
#define AFFINITYCALCULATIONSTRATEGY_H
|
|
7
8
|
#pragma once
|
|
8
9
|
#include <string>
|
|
9
10
|
#include <stdexcept>
|
|
@@ -18,32 +19,34 @@ enum class AffinityCalculationStrategy { WHOLE_STRING, PREFIX, CAPACITY, EXTRACT
|
|
|
18
19
|
class AffinityCalculator {
|
|
19
20
|
public:
|
|
20
21
|
static int calculateAffinityOfMask(AffinityCalculationStrategy strategy, Mask &mask,
|
|
21
|
-
|
|
22
|
+
const CaretString &text)
|
|
23
|
+
{
|
|
22
24
|
switch (strategy) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
case AffinityCalculationStrategy::WHOLE_STRING:
|
|
26
|
+
return mask.apply(text).affinity;
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
case AffinityCalculationStrategy::PREFIX:
|
|
29
|
+
return prefixIntersection(mask.apply(text).formattedText.string, text.string).length();
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
case AffinityCalculationStrategy::CAPACITY:
|
|
32
|
+
return text.string.length() > mask.totalTextLength() ? std::numeric_limits<int>::min()
|
|
33
|
+
: text.string.length() - mask.totalTextLength();
|
|
32
34
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
case AffinityCalculationStrategy::EXTRACTED_VALUE_CAPACITY: {
|
|
36
|
+
const auto &extractedValue = mask.apply(text).extractedValue;
|
|
37
|
+
return extractedValue.length() > mask.totalValueLength()
|
|
38
|
+
? std::numeric_limits<int>::min()
|
|
39
|
+
: extractedValue.length() - mask.totalValueLength();
|
|
40
|
+
}
|
|
41
|
+
default:
|
|
42
|
+
throw std::invalid_argument("Unknown AffinityCalculationStrategy");
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
private:
|
|
45
47
|
// Helper function to find prefix intersection
|
|
46
|
-
static std::string prefixIntersection(const std::string &str1, const std::string &str2)
|
|
48
|
+
static std::string prefixIntersection(const std::string &str1, const std::string &str2)
|
|
49
|
+
{
|
|
47
50
|
size_t endIndex = 0;
|
|
48
51
|
while (endIndex < str1.length() && endIndex < str2.length()) {
|
|
49
52
|
if (str1[endIndex] == str2[endIndex]) {
|
|
@@ -55,4 +58,5 @@ private:
|
|
|
55
58
|
return str1.substr(0, endIndex);
|
|
56
59
|
}
|
|
57
60
|
};
|
|
58
|
-
} // namespace TinpMask
|
|
61
|
+
} // namespace TinpMask
|
|
62
|
+
#endif
|
|
@@ -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 CARETSTRING_H
|
|
7
|
+
#define CARETSTRING_H
|
|
7
8
|
#pragma once
|
|
8
9
|
#include <string>
|
|
9
10
|
#include <memory>
|
|
@@ -26,7 +27,7 @@ public:
|
|
|
26
27
|
// 向前的光标重力
|
|
27
28
|
class Forward : public CaretGravity {
|
|
28
29
|
public:
|
|
29
|
-
Forward(bool autoCompleteValue) : autocompleteValue(autoCompleteValue) {}
|
|
30
|
+
explicit Forward(bool autoCompleteValue) : autocompleteValue(autoCompleteValue) {}
|
|
30
31
|
|
|
31
32
|
bool autocomplete() const override { return autocompleteValue; }
|
|
32
33
|
|
|
@@ -37,7 +38,7 @@ public:
|
|
|
37
38
|
// 向后的光标重力
|
|
38
39
|
class Backward : public CaretGravity {
|
|
39
40
|
public:
|
|
40
|
-
Backward(bool autoSkipValue) : autoskipValue(autoSkipValue) {}
|
|
41
|
+
explicit Backward(bool autoSkipValue) : autoskipValue(autoSkipValue) {}
|
|
41
42
|
|
|
42
43
|
bool autoskip() const override { return autoskipValue; }
|
|
43
44
|
|
|
@@ -51,26 +52,23 @@ public:
|
|
|
51
52
|
: string(str), caretPosition(caretPos), caretGravity(caretGrav) {}
|
|
52
53
|
|
|
53
54
|
// 反转字符串并返回新的 CaretString 对象
|
|
54
|
-
CaretString reversed() const
|
|
55
|
+
CaretString reversed() const
|
|
56
|
+
{
|
|
55
57
|
// 创建一个反转后的字符串
|
|
56
58
|
std::string reversedStr(string.rbegin(), string.rend());
|
|
57
59
|
// 计算新的 caretPosition
|
|
58
60
|
int newCaretPos = string.length() - caretPosition;
|
|
59
61
|
return CaretString(reversedStr, newCaretPos, caretGravity);
|
|
60
62
|
}
|
|
61
|
-
|
|
62
|
-
// 获取字符串
|
|
63
63
|
const std::string &getString() const { return string; }
|
|
64
64
|
// 获取光标位置
|
|
65
65
|
int getCaretPosition() const { return caretPosition; }
|
|
66
66
|
// 获取光标重力
|
|
67
67
|
std::shared_ptr<CaretGravity> getCaretGravity() const { return caretGravity; }
|
|
68
|
-
|
|
69
|
-
|
|
70
68
|
public:
|
|
71
|
-
std::string string;
|
|
72
|
-
int caretPosition;
|
|
73
|
-
std::shared_ptr<CaretGravity> caretGravity;
|
|
69
|
+
std::string string;
|
|
70
|
+
int caretPosition;
|
|
71
|
+
std::shared_ptr<CaretGravity> caretGravity;
|
|
74
72
|
};
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
} // namespace TinpMask
|
|
74
|
+
#endif
|