diff --git a/harmony/text_input_mask.har b/harmony/text_input_mask.har new file mode 100644 index 0000000..aa95879 Binary files /dev/null and b/harmony/text_input_mask.har differ diff --git a/harmony/text_input_mask/BuildProfile.ets b/harmony/text_input_mask/BuildProfile.ets index b8000f1..8dec343 100644 --- a/harmony/text_input_mask/BuildProfile.ets +++ b/harmony/text_input_mask/BuildProfile.ets @@ -1,7 +1,7 @@ /** * Use these variables when you tailor your ArkTS code. They must be of the const type. */ -export const HAR_VERSION = '3.1.5-0.0.2'; +export const HAR_VERSION = '3.1.5-0.0.3'; export const BUILD_MODE_NAME = 'debug'; export const DEBUG = true; export const TARGET_NAME = 'default'; diff --git a/harmony/text_input_mask/oh-package.json5 b/harmony/text_input_mask/oh-package.json5 index d9285de..05ee0ab 100644 --- a/harmony/text_input_mask/oh-package.json5 +++ b/harmony/text_input_mask/oh-package.json5 @@ -1,6 +1,6 @@ { "name": "@react-native-oh-tpl/react-native-text-input-mask", - "version": "3.1.5-0.0.2", + "version": "3.1.5-0.0.3", "description": "Please describe the basic information.", "main": "Index.ets", "author": "", diff --git a/harmony/text_input_mask/src/main/cpp/RNTextInputMask.cpp b/harmony/text_input_mask/src/main/cpp/RNTextInputMask.cpp index 5b05765..2386d91 100644 --- a/harmony/text_input_mask/src/main/cpp/RNTextInputMask.cpp +++ b/harmony/text_input_mask/src/main/cpp/RNTextInputMask.cpp @@ -1,3 +1,4 @@ +#pragma once #include "RNTextInputMask.h" #include "RNOH/arkui/TextInputNode.h" #include "RNOH/ComponentInstance.h" @@ -49,19 +50,17 @@ void myEventReceiver(ArkUI_NodeEvent *event) { : std::make_shared(CaretString::Forward(useAutocomplete)); CaretString text(content, content.length(), caretGravity); try { - // if (!isDelete) { - auto maskObj = self->pickMask(text, userData->maskOptions, userData->primaryFormat); - auto result = maskObj->apply(text); - std::string resultString = result.formattedText.string; - DLOG(INFO) << "mask result complete: " << result.complete; - userData->lastInputText = resultString; - std::string finalString = isDelete ? content : resultString; - ArkUI_AttributeItem item{.string = finalString.c_str()}; - userData->lastInputText = finalString; - maybeThrow(NativeNodeApi::getInstance()->setAttribute(userData->data, NODE_TEXT_INPUT_TEXT, &item)); - //} + auto maskObj = self->pickMask(text, userData->maskOptions, userData->primaryFormat); + auto result = maskObj->apply(text); + std::string resultString = result.formattedText.string; + DLOG(INFO) << "mask result complete: " << result.complete; + userData->lastInputText = resultString; + std::string finalString = isDelete ? content : resultString; + ArkUI_AttributeItem item{.string = finalString.c_str()}; + userData->lastInputText = finalString; + maybeThrow(NativeNodeApi::getInstance()->setAttribute(userData->data, NODE_TEXT_INPUT_TEXT, &item)); } catch (FormatError e) { - DLOG(ERROR) << " mask complier error " << e.what(); + DLOG(ERROR) << " mask compiler error " << e.what(); } } // onFocus 事件 @@ -73,11 +72,11 @@ void myEventReceiver(ArkUI_NodeEvent *event) { CaretString string(text, text.length(), std::make_shared(userData->maskOptions.autocomplete.value())); auto maskObj = self->pickMask(string, userData->maskOptions, userData->primaryFormat); - std::string resultString = maskObj->apply(string).formattedText.string; + std::string resultString = maskObj.get()->apply(string).formattedText.string; ArkUI_AttributeItem item{.string = resultString.c_str()}; maybeThrow(NativeNodeApi::getInstance()->setAttribute(userData->data, NODE_TEXT_INPUT_TEXT, &item)); } catch (FormatError e) { - DLOG(ERROR) << " mask complier error " << e.what(); + DLOG(ERROR) << " mask compiler error " << e.what(); } } } @@ -94,7 +93,9 @@ int calculateAffinity(Mask mask, const CaretString &text, std::string affinityCa } else { strategy = AffinityCalculationStrategy::EXTRACTED_VALUE_CAPACITY; } - return AffinityCalculator::calculateAffinityOfMask(strategy, mask, text); + int affinity = AffinityCalculator::calculateAffinityOfMask(strategy, mask, text); + + return affinity; } // 获取或创建 Mask std::shared_ptr maskGetOrCreate(const std::string &format, const std::vector &customNotations, @@ -109,8 +110,13 @@ std::shared_ptr maskGetOrCreate(const std::string &format, const std::vect std::shared_ptr RNTextInputMask::pickMask(const CaretString &text, MaskOptions maskOptions, std::string primaryMask) { // 如果 affineFormats 为空,直接返回 primaryMask - if (maskOptions.affineFormats->size() <= 0) - return maskGetOrCreate(primaryMask, maskOptions.customNotations.value(), maskOptions.rightToLeft.value()); + if (maskOptions.affineFormats->size() <= 0) { + auto mask = maskGetOrCreate(primaryMask, maskOptions.customNotations.value(), maskOptions.rightToLeft.value()); + int affinity = calculateAffinity(*mask, text, maskOptions.affinityCalculationStrategy.value()); + DLOG(INFO) << " ======= pickMask calculateAffinity value: " << affinity + << "\n affinityCalculationStrategy: " << maskOptions.affinityCalculationStrategy.value(); + return mask; + } // 定义 MaskAffinity 结构体,用于存储 Mask 和相应的亲和度 struct MaskAffinity { Mask mask; // Mask 对象 @@ -120,7 +126,8 @@ std::shared_ptr RNTextInputMask::pickMask(const CaretString &text, MaskOpt // 计算 primaryMask 的亲和度 int primaryAffinity = calculateAffinity(primaryMask, text, maskOptions.affinityCalculationStrategy.value()); - + DLOG(INFO) << " ======= pickMask calculateAffinity value: " << primaryAffinity << " \n mask: " << primaryMask + << "\n affinityCalculationStrategy: " << maskOptions.affinityCalculationStrategy.value(); // 存储所有 mask 和亲和度的列表 std::vector masksAndAffinities; @@ -129,6 +136,8 @@ std::shared_ptr RNTextInputMask::pickMask(const CaretString &text, MaskOpt std::shared_ptr mask = maskGetOrCreate(format, maskOptions.customNotations.value(), maskOptions.rightToLeft.value()); int affinity = calculateAffinity(*mask, text, maskOptions.affinityCalculationStrategy.value()); + DLOG(INFO) << " ======= pickMask calculateAffinity value: " << affinity << "\n affineFormat: " << format + << "\n affinityCalculationStrategy: " << maskOptions.affinityCalculationStrategy.value(); masksAndAffinities.emplace_back(*mask, affinity); } @@ -187,11 +196,13 @@ void RNTextInputMask::setMask(int reactNode, std::string primaryFormat, MaskOpti NativeNodeApi::getInstance()->addNodeEventReceiver(textInputNode->getArkUINodeHandle(), myEventReceiver); }; this->m_ctx.taskExecutor->runTask(TaskThread::MAIN, std::move(task)); + } std::string getString(std::string maskValue, std::string value, bool autocomplete, bool isMask) { - Mask maskObj(maskValue); + + auto maskObj = Mask::MaskFactory::getOrCreate(maskValue, {}); CaretString text(value, value.length(), std::make_shared(autocomplete)); - auto r = maskObj.apply(text); + auto r = maskObj->apply(text); std::string result; if (isMask) { result = r.formattedText.string; @@ -208,8 +219,14 @@ static jsi::Value __hostFunction_RNTextInputMask_unmask(jsi::Runtime &rt, react: return createPromiseAsJSIValue( rt, [maskValue, value, autocomplete](jsi::Runtime &rt2, std::shared_ptr promise) { try { + auto start = std::chrono::high_resolution_clock::now(); std::string result = getString(maskValue, value, autocomplete, 0); promise->resolve(jsi::String::createFromUtf8(rt2, result)); + // 获取结束时间点 + auto end = std::chrono::high_resolution_clock::now(); + // 计算延迟 + std::chrono::duration latency = end - start; + DLOG(INFO) << "=======unmask 响应时长: " << latency.count() << " 毫秒" << std::endl; } catch (FormatError e) { promise->reject(e.what()); } @@ -217,15 +234,20 @@ static jsi::Value __hostFunction_RNTextInputMask_unmask(jsi::Runtime &rt, react: } static jsi::Value __hostFunction_RNTextInputMask_mask(jsi::Runtime &rt, react::TurboModule &turboModule, const jsi::Value *args, size_t count) { - std::string maskValue = args[0].getString(rt).utf8(rt); std::string value = args[1].getString(rt).utf8(rt); bool autocomplete = args[2].getBool(); return createPromiseAsJSIValue( rt, [maskValue, value, autocomplete](jsi::Runtime &rt2, std::shared_ptr promise) { try { + auto start = std::chrono::high_resolution_clock::now(); std::string result = getString(maskValue, value, autocomplete, 1); promise->resolve(jsi::String::createFromUtf8(rt2, result)); + // 获取结束时间点 + auto end = std::chrono::high_resolution_clock::now(); + // 计算延迟 + std::chrono::duration latency = end - start; + DLOG(INFO) << "=======mask 响应时长: " << latency.count() << " 毫秒" << std::endl; } catch (FormatError e) { promise->reject(e.what()); } diff --git a/harmony/text_input_mask/src/main/cpp/common/Compiler.h b/harmony/text_input_mask/src/main/cpp/common/Compiler.h index 9f3dd31..d6d5d06 100644 --- a/harmony/text_input_mask/src/main/cpp/common/Compiler.h +++ b/harmony/text_input_mask/src/main/cpp/common/Compiler.h @@ -105,14 +105,17 @@ class Compiler { } std::unique_ptr compileWithCustomNotations(char c, const std::string &str) { + DLOG(ERROR) << "====== compileWithCustomNotations customNotations size: " << customNotations.size(); for (const auto &customNotation : customNotations) { if (customNotation.character == c) { std::shared_ptr compiledState = compile(str.substr(1), true, false, c); if (customNotation.isOptional) { + DLOG(ERROR) << "====== compileWithCustomNotations customNotations isOptional :" << customNotation.isOptional; return std::make_unique( std::move(compiledState), std::make_shared(c, customNotation.characterSet)); } else { + DLOG(ERROR) << "======= compileWithCustomNotations customNotations isOptional :" << customNotation.isOptional; return std::make_unique( std::move(compiledState), std::make_shared(c, customNotation.characterSet)); } @@ -150,6 +153,7 @@ class Compiler { if (!lastCharacter.has_value()) { throw FormatError(); // 处理空字符情况,抛出异常 } + DLOG(INFO) << "======determineTypeWithCustomNotations customNotations size: "< customNotations; - - private: - std::shared_ptr initialState; - - private: - std::string format; - +class Mask { +protected: + std::vector customNotations; + +private: + std::shared_ptr initialState; + +private: + std::string format; + +public: + // 主构造函数 + Mask(const std::string &format, const std::vector &customNotations) : customNotations(customNotations) { + this->format = format; + this->customNotations = customNotations; + this->initialState = Compiler(customNotations).compile(format); + } + + // 便利构造函数 + Mask(const std::string &format) : Mask(format, {}) { // 调用主构造函数,传入空的 customNotations + std::vector emptyVector; + this->format = format; + this->customNotations = emptyVector; + this->initialState = Compiler(this->customNotations).compile(this->format); + } + + + class MaskFactory { public: - // 主构造函数 - Mask(const std::string &format, const std::vector &customNotations) - : customNotations(customNotations) { - this->format = format; - this->customNotations = customNotations; - this->initialState = Compiler(customNotations).compile(format); - } - - // 便利构造函数 - Mask(const std::string &format) : Mask(format, {}) { // 调用主构造函数,传入空的 customNotations - std::vector emptyVector; - this->format = format; - this->customNotations = emptyVector; - this->initialState = Compiler(this->customNotations).compile(this->format); - } - + static std::unordered_map> maskCache; - class MaskFactory { - public: - static std::unordered_map> maskCache; - - public: - /** - * Factory constructor. - * - * Operates over own ``Mask`` cache where initialized ``Mask`` objects are stored under - * corresponding format key: `[format : mask]` - * - * @returns Previously cached ``Mask`` object for requested format string. If such it - * doesn't exist in cache, the object is constructed, cached and returned. - */ - static std::shared_ptr getOrCreate(const std::string &format, - const std::vector &customNotations) { - auto cachedMask = maskCache.find(format); - if (cachedMask == maskCache.end()) { - auto newMask = std::make_shared(format, customNotations); - maskCache[format] = newMask; - return newMask; - } - return cachedMask->second; + public: + /** + * Factory constructor. + * + * Operates over own ``Mask`` cache where initialized ``Mask`` objects are stored under + * corresponding format key: `[format : mask]` + * + * @returns Previously cached ``Mask`` object for requested format string. If such it + * doesn't exist in cache, the object is constructed, cached and returned. + */ + static std::shared_ptr getOrCreate(const std::string &format, + const std::vector &customNotations) { + auto cachedMask = maskCache.find(format); + if (cachedMask == maskCache.end()) { + auto newMask = std::make_shared(format, customNotations); + maskCache[format] = newMask; + return newMask; } + return cachedMask->second; + } - /** - * Check your mask format is valid. - * - * @param format mask format. - * @param customNotations a list of custom rules to compile square bracket `[]` groups of format symbols. - * - * @returns `true` if this format coupled with custom notations will compile into a working ``Mask`` object. - * Otherwise `false`. - */ - static bool isValid(const std::string &format, const std::vector &customNotations) { - try { - Mask(format, customNotations); - return true; - } catch (const FormatError &) { - return false; - } - } - }; /** - * Apply mask to the user input string. + * Check your mask format is valid. * - * @param text user input string with current cursor position + * @param format mask format. + * @param customNotations a list of custom rules to compile square bracket `[]` groups of format symbols. * - * @returns Formatted text with extracted value an adjusted cursor position. + * @returns `true` if this format coupled with custom notations will compile into a working ``Mask`` object. + * Otherwise `false`. */ - virtual Result apply(const CaretString &text) { - auto iterator = makeIterator(text); // Assume this function is defined - - int affinity = 0; - std::string extractedValue; - std::string modifiedString; - int modifiedCaretPosition = text.caretPosition; - - std::shared_ptr state = initialState; - AutocompletionStack autocompletionStack; - - bool insertionAffectsCaret = iterator->insertionAffectsCaret(); - bool deletionAffectsCaret = iterator->deletionAffectsCaret(); - char character = iterator->next(); - while (character != '\0') { - auto next = state->accept(character); - - if (next != nullptr) { - if (deletionAffectsCaret) { - auto opt = state->autocomplete(); - if (opt != nullptr) { - autocompletionStack.push(*opt); - } - } - state = next->state; - if (next->insert == '\0') { - modifiedString += ""; - } else { - modifiedString += next->insert; - } - if (next->value == '\0') { - extractedValue += ""; - } else { - extractedValue += next->value; - } - if (next->pass) { - insertionAffectsCaret = iterator->insertionAffectsCaret(); - deletionAffectsCaret = iterator->deletionAffectsCaret(); - character = iterator->next(); - affinity += 1; - } else { - if (insertionAffectsCaret && next->insert != '\0') { - modifiedCaretPosition += 1; - } - affinity -= 1; - } - } else { - if (deletionAffectsCaret) { - modifiedCaretPosition -= 1; + static bool isValid(const std::string &format, const std::vector &customNotations) { + try { + Mask(format, customNotations); + return true; + } catch (const FormatError &) { + return false; + } + } + }; + /** + * Apply mask to the user input string. + * + * @param text user input string with current cursor position + * + * @returns Formatted text with extracted value an adjusted cursor position. + */ + virtual Result apply(const CaretString &text) { + auto iterator = makeIterator(text); // Assume this function is defined + + int affinity = 0; + std::string extractedValue; + std::string modifiedString; + int modifiedCaretPosition = text.caretPosition; + + std::shared_ptr state = initialState; + AutocompletionStack autocompletionStack; + + bool insertionAffectsCaret = iterator->insertionAffectsCaret(); + bool deletionAffectsCaret = iterator->deletionAffectsCaret(); + char character = iterator->next(); + while (character != '\0') { + auto next = state->accept(character); + + if (next != nullptr) { + if (deletionAffectsCaret) { + auto opt = state->autocomplete(); + if (opt != nullptr) { + autocompletionStack.push(*opt); } - insertionAffectsCaret = iterator->insertionAffectsCaret(); - deletionAffectsCaret = iterator->deletionAffectsCaret(); - character = iterator->next(); - affinity -= 1; } - } - - while (text.caretGravity->autocomplete() && insertionAffectsCaret) { - auto next = state->autocomplete(); - if (next == nullptr) - break; - state = next->state; if (next->insert == '\0') { modifiedString += ""; @@ -161,211 +122,251 @@ namespace TinpMask { } else { extractedValue += next->value; } - if (next->insert == '\0') { - modifiedCaretPosition += 1; - } - } - std::shared_ptr tailState = state; - std::string tail; - while (text.caretGravity->autoskip() && !autocompletionStack.isEmpty()) { - auto skip = autocompletionStack.pop(); - if (modifiedString.length() == modifiedCaretPosition) { - if (!skip->insert == '\0' && skip->insert == modifiedString.back()) { - modifiedString.pop_back(); - modifiedCaretPosition -= 1; - } - if (skip.has_value() && skip.value().value == modifiedString.back()) { - extractedValue.pop_back(); - } + if (next->pass) { + insertionAffectsCaret = iterator->insertionAffectsCaret(); + deletionAffectsCaret = iterator->deletionAffectsCaret(); + character = iterator->next(); + affinity += 1; } else { - if (!skip->insert == '\0') { - modifiedCaretPosition -= 1; + if (insertionAffectsCaret && next->insert != '\0') { + modifiedCaretPosition += 1; } + affinity -= 1; } - tailState = skip->state; - tail += skip->insert; + } else { + if (deletionAffectsCaret) { + modifiedCaretPosition -= 1; + } + insertionAffectsCaret = iterator->insertionAffectsCaret(); + deletionAffectsCaret = iterator->deletionAffectsCaret(); + character = iterator->next(); + affinity -= 1; } - - std::string tailPlaceholder = appendPlaceholder(tailState.get(), tail); // Assume this function is defined - - return Result(CaretString(modifiedString, modifiedCaretPosition, text.caretGravity), extractedValue, - affinity, - noMandatoryCharactersLeftAfterState(state.get()), // Assume this function is defined - tailPlaceholder); } + while (text.caretGravity->autocomplete() && insertionAffectsCaret) { + auto next = state->autocomplete(); + if (next == nullptr) + break; - public: - std::shared_ptr makeIterator(const CaretString &text) const { - return std::make_shared(text); + state = next->state; + if (next->insert == '\0') { + modifiedString += ""; + } else { + modifiedString += next->insert; + } + if (next->value == '\0') { + extractedValue += ""; + } else { + extractedValue += next->value; + } + if (next->insert == '\0') { + modifiedCaretPosition += 1; + } } - - /** - * Generate placeholder. - * - * @return Placeholder string. - */ - public: - std::string placeholder() { return appendPlaceholder(initialState.get(), ""); } - /** - * Minimal length of the text inside the field to fill all mandatory characters in the mask. - * - * @return Minimal satisfying count of characters inside the text field. - */ - public: - int acceptableTextLength() { - std::shared_ptr state = std::move(initialState); - ; - int length = 0; - - while (state != nullptr && dynamic_cast(state.get()) == nullptr) { - if (dynamic_cast(state.get()) != nullptr || - dynamic_cast(state.get()) != nullptr || - dynamic_cast(state.get()) != nullptr) { - length += 1; + std::shared_ptr tailState = state; + std::string tail; + while (text.caretGravity->autoskip() && !autocompletionStack.isEmpty()) { + auto skip = autocompletionStack.pop(); + if (modifiedString.length() == modifiedCaretPosition) { + if (!skip->insert == '\0' && skip->insert == modifiedString.back()) { + modifiedString.pop_back(); + modifiedCaretPosition -= 1; + } + if (skip.has_value() && skip.value().value == modifiedString.back()) { + extractedValue.pop_back(); + } + } else { + if (!skip->insert == '\0') { + modifiedCaretPosition -= 1; } - state = state->child; // 移动到下一个子状态 } - - return length; + tailState = skip->state; + tail += skip->insert; } + std::string tailPlaceholder = appendPlaceholder(tailState.get(), tail); // Assume this function is defined + + return Result(CaretString(modifiedString, modifiedCaretPosition, text.caretGravity), extractedValue, affinity, + noMandatoryCharactersLeftAfterState(state.get()), // Assume this function is defined + tailPlaceholder); + } + + +public: + std::shared_ptr makeIterator(const CaretString &text) const { + return std::make_shared(text); + } + + /** + * Generate placeholder. + * + * @return Placeholder string. + */ +public: + std::string placeholder() { return appendPlaceholder(initialState.get(), ""); } + /** + * Minimal length of the text inside the field to fill all mandatory characters in the mask. + * + * @return Minimal satisfying count of characters inside the text field. + */ +public: + int acceptableTextLength() { + std::shared_ptr state = std::move(initialState); + ; + int length = 0; + + while (state != nullptr && dynamic_cast(state.get()) == nullptr) { + if (dynamic_cast(state.get()) != nullptr || + dynamic_cast(state.get()) != nullptr || + dynamic_cast(state.get()) != nullptr) { + length += 1; + } + state = state->child; // 移动到下一个子状态 + } - /** - * Maximal length of the text inside the field. - * - * @return Total available count of mandatory and optional characters inside the text field. - */ - public: - int totalTextLength() const { - std::shared_ptr state = initialState; - ; - int length = 0; - - while (state != nullptr && dynamic_cast(state.get()) == nullptr) { - if (dynamic_cast(state.get()) != nullptr || - dynamic_cast(state.get()) != nullptr || - dynamic_cast(state.get()) != nullptr || - dynamic_cast(state.get()) != nullptr) { - length += 1; - } - state = state->child; // 移动到下一个子状态 + return length; + } + + + /** + * Maximal length of the text inside the field. + * + * @return Total available count of mandatory and optional characters inside the text field. + */ +public: + int totalTextLength() const { + std::shared_ptr state = initialState; + ; + int length = 0; + + while (state != nullptr && dynamic_cast(state.get()) == nullptr) { + if (dynamic_cast(state.get()) != nullptr || + dynamic_cast(state.get()) != nullptr || + dynamic_cast(state.get()) != nullptr || + dynamic_cast(state.get()) != nullptr) { + length += 1; } + state = state->child; // 移动到下一个子状态 + } - return length; + return length; + } + /** + * Minimal length of the extracted value with all mandatory characters filled.\ + * + * @return Minimal satisfying count of characters in extracted value. + */ +public: + int acceptableValueLength() const { + std::shared_ptr state = initialState; + int length = 0; + while (state != nullptr && dynamic_cast(state.get()) == nullptr) { + if (dynamic_cast(state.get()) != nullptr || + dynamic_cast(state.get()) != nullptr) { + length += 1; + } + state = state->child; // 移动到下一个子状态 } - /** - * Minimal length of the extracted value with all mandatory characters filled.\ - * - * @return Minimal satisfying count of characters in extracted value. - */ - public: - int acceptableValueLength() const { - std::shared_ptr state = initialState; - int length = 0; - while (state != nullptr && dynamic_cast(state.get()) == nullptr) { - if (dynamic_cast(state.get()) != nullptr || - dynamic_cast(state.get()) != nullptr) { - length += 1; - } - state = state->child; // 移动到下一个子状态 + + return length; + } + /** + * Maximal length of the extracted value. + * + * @return Total available count of mandatory and optional characters for extracted value. + */ +public: + int totalValueLength() const { + std::shared_ptr state = initialState; + int length = 0; + while (state != nullptr && dynamic_cast(state.get()) == nullptr) { + if (dynamic_cast(state.get()) != nullptr || + dynamic_cast(state.get()) != nullptr || + dynamic_cast(state.get()) != nullptr) { + length += 1; } + state = state->child; // 移动到下一个子状态 + } + return length; + } - return length; +private: + std::string appendPlaceholder(State *state, const std::string &placeholder) const { + if (state == nullptr) { + return placeholder; } - /** - * Maximal length of the extracted value. - * - * @return Total available count of mandatory and optional characters for extracted value. - */ - public: - int totalValueLength() const { - std::shared_ptr state = initialState; - int length = 0; - while (state != nullptr && dynamic_cast(state.get()) == nullptr) { - if (dynamic_cast(state.get()) != nullptr || - dynamic_cast(state.get()) != nullptr || - dynamic_cast(state.get()) != nullptr) { - length += 1; - } - state = state->child; // 移动到下一个子状态 - } - return length; + + if (dynamic_cast(state)) { + return placeholder; } - private: - std::string appendPlaceholder(State *state, const std::string &placeholder) const { - if (state == nullptr) { - return placeholder; - } + if (auto fixedState = dynamic_cast(state)) { + return appendPlaceholder(fixedState->child.get(), placeholder + fixedState->ownCharacter); + } - if (dynamic_cast(state)) { - return placeholder; - } + if (auto freeState = dynamic_cast(state)) { + return appendPlaceholder(freeState->child.get(), placeholder + freeState->ownCharacter); + } - if (auto fixedState = dynamic_cast(state)) { - return appendPlaceholder(fixedState->child.get(), placeholder + fixedState->ownCharacter); + if (auto optionalValueState = dynamic_cast(state)) { + if (!state) { + return placeholder; // 如果 state 为 nullptr,直接返回原始 placeholder } - - if (auto freeState = dynamic_cast(state)) { - return appendPlaceholder(freeState->child.get(), placeholder + freeState->ownCharacter); + // 使用 if-else 替代 switch + if (optionalValueState->type->getName() == StateTypeName::Numeric) { + return appendPlaceholder(state->child.get(), placeholder + "0"); + } else if (optionalValueState->type->getName() == StateTypeName::Literal) { + return appendPlaceholder(state->child.get(), placeholder + "a"); + } else if (optionalValueState->type->getName() == StateTypeName::AlphaNumeric) { + return appendPlaceholder(state->child.get(), placeholder + "-"); + } else if (optionalValueState->type->getName() == StateTypeName::Custom) { + auto customValueState = dynamic_cast(state); + auto customStateType = dynamic_cast(customValueState->type.get()); + return appendPlaceholder(state->child.get(), placeholder + customStateType->character); + } else { + return placeholder; // 未知类型,返回原始 placeholder } + } - if (auto optionalValueState = dynamic_cast(state)) { - if (!state) { - return placeholder; // 如果 state 为 nullptr,直接返回原始 placeholder - } - // 使用 if-else 替代 switch - if (optionalValueState->type->getName() == StateTypeName::Numeric) { - return appendPlaceholder(state->child.get(), placeholder + "0"); - } else if (optionalValueState->type->getName() == StateTypeName::Literal) { - return appendPlaceholder(state->child.get(), placeholder + "a"); - } else if (optionalValueState->type->getName() == StateTypeName::AlphaNumeric) { - return appendPlaceholder(state->child.get(), placeholder + "-"); - } else if (optionalValueState->type->getName() == StateTypeName::Custom) { - auto customValueState = dynamic_cast(state); - auto customStateType = dynamic_cast(customValueState->type.get()); - return appendPlaceholder(state->child.get(), - placeholder + customStateType->character); - } else { - return placeholder; // 未知类型,返回原始 placeholder - } + if (auto valueState = dynamic_cast(state)) { + if (!state) { + return placeholder; // 如果 state 为 nullptr,直接返回原始 placeholder } - - if (auto valueState = dynamic_cast(state)) { - if (!state) { - return placeholder; // 如果 state 为 nullptr,直接返回原始 placeholder + // 使用 if-else 替代 switch + if (valueState->type->getName() == StateTypeName::Numeric) { + return appendPlaceholder(state->child.get(), placeholder + "0"); + } else if (valueState->type->getName() == StateTypeName::Literal) { + return appendPlaceholder(state->child.get(), placeholder + "a"); + } else if (valueState->type->getName() == StateTypeName::AlphaNumeric) { + return appendPlaceholder(state->child.get(), placeholder + "-"); + } else if (valueState->type->getName() == StateTypeName::Custom) { + auto customValueState = dynamic_cast(state); + if (customValueState->type.get()) { + auto customStateType = dynamic_cast(customValueState->type.get()); + return appendPlaceholder(state->child.get(), placeholder + customStateType->character); + }else { + throw FormatError("appendPlaceholder customValueState type is null"); // 未找到匹配项,抛出异常 } - // 使用 if-else 替代 switch - if (valueState->type->getName() == StateTypeName::Numeric) { - return appendPlaceholder(state->child.get(), placeholder + "0"); - } else if (valueState->type->getName() == StateTypeName::Literal) { - return appendPlaceholder(state->child.get(), placeholder + "a"); - } else if (valueState->type->getName() == StateTypeName::AlphaNumeric) { - return appendPlaceholder(state->child.get(), placeholder + "-"); - } else if (valueState->type->getName() == StateTypeName::Custom) { - auto customValueState = dynamic_cast(state); - auto customStateType = dynamic_cast(customValueState->type.get()); - return appendPlaceholder(state->child.get(), - placeholder + customStateType->character); - } else { - return placeholder; // 未知类型,返回原始 placeholder - } - } - - return placeholder; - } - bool noMandatoryCharactersLeftAfterState(State *state) const { - if (dynamic_cast(state)) { - return true; - } else if (auto valueState = dynamic_cast(state)) { - return valueState->isElliptical(); - } else if (dynamic_cast(state)) { - return false; } else { - return noMandatoryCharactersLeftAfterState(state->nextState().get()); + return placeholder; // 未知类型,返回原始 placeholder } } - }; -} \ No newline at end of file + + return placeholder; + } + + bool noMandatoryCharactersLeftAfterState(State *state) const { + if (dynamic_cast(state)) { + return true; + } else if (auto valueState = dynamic_cast(state)) { + return valueState->isElliptical(); + } else if (dynamic_cast(state)) { + return false; + } else { + return noMandatoryCharactersLeftAfterState(state->nextState().get()); + } + } +}; +} // namespace TinpMask \ No newline at end of file diff --git a/harmony/text_input_mask/src/main/cpp/common/model/AffinityCalculationStrategy.h b/harmony/text_input_mask/src/main/cpp/common/model/AffinityCalculationStrategy.h index b72a907..afb5678 100644 --- a/harmony/text_input_mask/src/main/cpp/common/model/AffinityCalculationStrategy.h +++ b/harmony/text_input_mask/src/main/cpp/common/model/AffinityCalculationStrategy.h @@ -30,7 +30,6 @@ class AffinityCalculator { ? std::numeric_limits::min() : extractedValue.length() - mask.totalValueLength(); } - default: throw std::invalid_argument("Unknown AffinityCalculationStrategy"); } diff --git a/package.json b/package.json index 34c8f98..a844e64 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@react-native-oh-tpl/react-native-text-input-mask", - "version": "3.1.5-0.0.2", + "version": "3.1.5-0.0.3", "description": "Text input mask for React Native.", "main": "dist/index.js", "typings": "dist/index.d.ts",