From eb6c0e96d84b6f6404b6f02b4cc0fe849992f3cb Mon Sep 17 00:00:00 2001 From: xiangyuan6 Date: Tue, 2 Sep 2025 15:15:30 +0800 Subject: [PATCH] =?UTF-8?q?fix=20setStyledString=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E5=A4=8D=E7=94=A8ai=E8=AF=86=E5=88=AB=E7=BB=93=E6=9E=9C?= =?UTF-8?q?=E5=8F=8A=E6=97=A0=E9=9A=9C=E7=A2=8D=E6=92=AD=E6=8A=A5=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E3=80=90=E6=8C=91=E5=8D=956.0=E3=80=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: xiangyuan6 --- .../core/common/ai/data_detector_adapter.h | 9 ++++++ .../pattern/search/search_pattern.cpp | 17 +++++++++- .../pattern/text/text_pattern.cpp | 3 +- .../text_field/text_input_response_area.cpp | 14 ++++++++- .../core/pattern/text/text_test_ng.cpp | 18 +++++++++++ .../text_input/text_field_pattern_test.cpp | 2 +- .../pattern/text_input/text_input_test.cpp | 31 +++++++++++++++++++ 7 files changed, 90 insertions(+), 4 deletions(-) diff --git a/frameworks/core/common/ai/data_detector_adapter.h b/frameworks/core/common/ai/data_detector_adapter.h index 18f4d826471..45f1e920af6 100644 --- a/frameworks/core/common/ai/data_detector_adapter.h +++ b/frameworks/core/common/ai/data_detector_adapter.h @@ -51,6 +51,15 @@ struct AISpan { { return start == span.start && end == span.end && content == span.content && type == span.type; } + std::string ToString() + { + std::stringstream ss; + ss << "start: " << start << ","; + ss << "end: " << end << ","; + ss << "content: " << content << ","; + ss << "type: " << static_cast(type) << "\n"; + return ss.str(); + } }; class DataDetectorAdapter : public AceType { DECLARE_ACE_TYPE(DataDetectorAdapter, AceType); diff --git a/frameworks/core/components_ng/pattern/search/search_pattern.cpp b/frameworks/core/components_ng/pattern/search/search_pattern.cpp index 0846a5d4fb0..2d6f2fa8321 100644 --- a/frameworks/core/components_ng/pattern/search/search_pattern.cpp +++ b/frameworks/core/components_ng/pattern/search/search_pattern.cpp @@ -853,7 +853,22 @@ void SearchPattern::OnClickCancelButton() CHECK_NULL_VOID(focusHub); focusHub->RequestFocusImmediately(); textFieldPattern->HandleFocusEvent(); - textFieldFrameNode->OnAccessibilityEvent(AccessibilityEventType::REQUEST_FOCUS); + auto context = host->GetContext(); + if (context) { + context->AddAfterRenderTask([weak = WeakClaim(this)] { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + auto host = pattern->GetHost(); + CHECK_NULL_VOID(host); + auto textFieldFrameNode = AceType::DynamicCast(host->GetChildren().front()); + CHECK_NULL_VOID(textFieldFrameNode); + textFieldFrameNode->OnAccessibilityEvent( + AccessibilityEventType::REQUEST_FOCUS_FOR_ACCESSIBILITY_NOT_INTERRUPT); + }); + } else { + textFieldFrameNode->OnAccessibilityEvent( + AccessibilityEventType::REQUEST_FOCUS_FOR_ACCESSIBILITY_NOT_INTERRUPT); + } host->MarkModifyDone(); textFieldFrameNode->MarkModifyDone(); } diff --git a/frameworks/core/components_ng/pattern/text/text_pattern.cpp b/frameworks/core/components_ng/pattern/text/text_pattern.cpp index dbc890ca446..8142698d15a 100644 --- a/frameworks/core/components_ng/pattern/text/text_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text/text_pattern.cpp @@ -6030,6 +6030,7 @@ void TextPattern::ProcessSpanString() childNodes_.clear(); // styled string perf can be optimized via create as requirement CHECK_NULL_VOID(GetDataDetectorAdapter()); + auto savedTextForAI = dataDetectorAdapter_->textForAI_; dataDetectorAdapter_->textForAI_.clear(); host->Clean(); hasSpanStringLongPressEvent_ = false; @@ -6063,7 +6064,7 @@ void TextPattern::ProcessSpanString() } textForDisplay_ += span->content; } - if (dataDetectorAdapter_->textForAI_ != textForDisplay_) { + if (dataDetectorAdapter_->textForAI_ != textForDisplay_ || savedTextForAI != dataDetectorAdapter_->textForAI_) { dataDetectorAdapter_->aiDetectInitialized_ = false; } if (CanStartAITask() && !dataDetectorAdapter_->aiDetectInitialized_) { diff --git a/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp b/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp index 1ea9892659f..337eea26bb1 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp @@ -1055,7 +1055,19 @@ void CleanNodeResponseArea::OnCleanNodeClicked() textFieldPattern->CleanNodeResponseKeyEvent(); auto host = textFieldPattern->GetHost(); CHECK_NULL_VOID(host); - host->OnAccessibilityEvent(AccessibilityEventType::REQUEST_FOCUS); + auto context = host->GetContext(); + if (context) { + context->AddAfterRenderTask([weak = WeakClaim(this)] { + auto responseAreaPattern = weak.Upgrade(); + CHECK_NULL_VOID(responseAreaPattern); + auto textFieldPattern = DynamicCast(responseAreaPattern->hostPattern_.Upgrade()); + CHECK_NULL_VOID(textFieldPattern); + auto host = textFieldPattern->GetHost(); + CHECK_NULL_VOID(host); + host->OnAccessibilityEvent( + AccessibilityEventType::REQUEST_FOCUS_FOR_ACCESSIBILITY_NOT_INTERRUPT); + }); + } } void CleanNodeResponseArea::UpdateCleanNode(bool isShow) diff --git a/test/unittest/core/pattern/text/text_test_ng.cpp b/test/unittest/core/pattern/text/text_test_ng.cpp index 9a68faeab28..57e33f83899 100644 --- a/test/unittest/core/pattern/text/text_test_ng.cpp +++ b/test/unittest/core/pattern/text/text_test_ng.cpp @@ -4510,6 +4510,24 @@ HWTEST_F(TextTestNg, ProcessSpanString002, TestSize.Level1) EXPECT_EQ(info->moduleName_, "moduleName"); } +/** + * @tc.name: ProcessSpanString003 + * @tc.desc: Test TextPattern ProcessSpanString + * @tc.type: FUNC + */ +HWTEST_F(TextTestNg, ProcessSpanString003, TestSize.Level1) +{ + /** + * @tc.steps: step1. create frameNode and test pattern ProcessSpanString + */ + auto [frameNode, pattern] = Init(); + ASSERT_NE(pattern->GetDataDetectorAdapter(), nullptr); + pattern->dataDetectorAdapter_->aiDetectInitialized_ = false; + pattern->dataDetectorAdapter_->textForAI_ = pattern->textForDisplay_; + pattern->ProcessSpanString(); + EXPECT_EQ(pattern->textForDisplay_.length(), 0); +} + /** * @tc.name: UpdateParagraphBySpan002 * @tc.desc: Test the maxlines of UpdateParagraphBySpan diff --git a/test/unittest/core/pattern/text_input/text_field_pattern_test.cpp b/test/unittest/core/pattern/text_input/text_field_pattern_test.cpp index 96265ecef23..6562a3eb1bc 100644 --- a/test/unittest/core/pattern/text_input/text_field_pattern_test.cpp +++ b/test/unittest/core/pattern/text_input/text_field_pattern_test.cpp @@ -115,7 +115,7 @@ HWTEST_F(TextFieldPatternTest, TextPattern004, TestSize.Level1) HWTEST_F(TextFieldPatternTest, TextPattern005, TestSize.Level1) { /** - * @tc.steps: step1. create frameNode and test pattern IsShowHandle + * @tc.steps: step1. create frameNode and test pattern IsShowHandle. */ CreateTextField(); auto textFieldNode = FrameNode::GetOrCreateFrameNode(V2::TEXTINPUT_ETS_TAG, diff --git a/test/unittest/core/pattern/text_input/text_input_test.cpp b/test/unittest/core/pattern/text_input/text_input_test.cpp index 94f6e2c2392..9ac7b5dd7fe 100644 --- a/test/unittest/core/pattern/text_input/text_input_test.cpp +++ b/test/unittest/core/pattern/text_input/text_input_test.cpp @@ -325,6 +325,37 @@ HWTEST_F(TextFieldUXTest, CleanNode006, TestSize.Level1) AceApplicationInfo::GetInstance().SetApiTargetVersion(static_cast(backupApiVersion)); } +/** + * @tc.name: CleanNode007 + * @tc.desc: Test OnCleanNodeClicked + * @tc.type: FUNC + */ +HWTEST_F(TextFieldUXTest, CleanNode007, TestSize.Level1) +{ + /** + * @tc.steps: step1. Initialize text input + */ + CreateTextField(DEFAULT_TEXT, "", [](TextFieldModelNG model) { + model.SetCleanNodeStyle(CleanNodeStyle::CONSTANT); + model.SetIsShowCancelButton(true); + model.SetCancelIconSize(Dimension(ICON_SIZE, DimensionUnit::PX)); + model.SetCancelButtonSymbol(false); + }); + + auto cleanNodeResponseArea = AceType::DynamicCast(pattern_->cleanNodeResponseArea_); + ASSERT_NE(cleanNodeResponseArea, nullptr); + EXPECT_FALSE(cleanNodeResponseArea->IsShowSymbol()); + EXPECT_FALSE(cleanNodeResponseArea->IsSymbolIcon()); + + /** + * @tc.steps: step2. test clean node clicked + */ + + cleanNodeResponseArea->OnCleanNodeClicked(); + pattern_->BeforeCreateLayoutWrapper(); + EXPECT_EQ(pattern_->GetTextValue(), ""); +} + /** * @tc.name: RepeatClickCaret * @tc.desc: Test RepeatClickCaret -- Gitee