已合并
fix(web): add text share eligibility check for web selection #77573
fix(web): add text share eligibility check for web selection #77573
已合并
jerrywangxmu创建于 2025年12月9日
共 3 个文件变更+123-1
@@ -20,6 +20,7 @@
20 20 
21#include "base/utils/utils.h"21#include "base/utils/utils.h"
22#include "arkweb_utils.h"22#include "arkweb_utils.h"
23+#include "core/common/share/text_share_adapter.h"
23#include "core/components_ng/manager/select_content_overlay/select_content_overlay_manager.h"24#include "core/components_ng/manager/select_content_overlay/select_content_overlay_manager.h"
24#include "core/components_ng/manager/select_overlay/select_overlay_manager.h"25#include "core/components_ng/manager/select_overlay/select_overlay_manager.h"
25#include "core/components_ng/pattern/web/web_pattern.h"26#include "core/components_ng/pattern/web/web_pattern.h"
@@ -1283,6 +1284,22 @@ void WebSelectOverlay::OnUpdateSelectOverlayInfo(SelectOverlayInfo &selectInfo,
1283 }1284 }
1284}1285}
1285 1286 
1287+bool WebSelectOverlay::IsNeedMenuShareForWeb()
1288+{
1289+ const auto& shareContent = GetSelectedText();
1290+ std::string_view sv(shareContent);
1291+ // whitespace characters to trim (same as \s in regex for ASCII whitespace)
1292+ constexpr auto ws = " \t\n\r\f\v";
1293+ const auto start = sv.find_first_not_of(ws);
1294+ if (start == std::string_view::npos) {
1295+ return false;
1296+ }
1297+ const auto end = sv.find_last_not_of(ws);
1298+ const auto trimmedLen = end - start + 1;
1299+ const auto maxShareLength = static_cast<size_t>(TextShareAdapter::GetMaxTextShareLength());
zhufenghao
zhufenghaozhufenghao2025年12月10日

转换是否必要,是因为下面判断的静态告警吗

likedislike
jerrywangxmu
jerrywangxmu
2025年12月11日 评论:
1300+ return trimmedLen <= maxShareLength;
1301+}
1302+ 
1286void WebSelectOverlay::OnHandleMarkInfoChange(1303void WebSelectOverlay::OnHandleMarkInfoChange(
1287 const std::shared_ptr<SelectOverlayInfo> info, SelectOverlayDirtyFlag flag)1304 const std::shared_ptr<SelectOverlayInfo> info, SelectOverlayDirtyFlag flag)
1288{1305{
@@ -1300,7 +1317,7 @@ void WebSelectOverlay::OnHandleMarkInfoChange(
1300 auto copyOption = delegate->GetCopyOptionMode();1317 auto copyOption = delegate->GetCopyOptionMode();
1301 bool canCopyOut = (copyOption != OHOS::NWeb::NWebPreference::CopyOptionMode::NONE) &&1318 bool canCopyOut = (copyOption != OHOS::NWeb::NWebPreference::CopyOptionMode::NONE) &&
1302 (copyOption != OHOS::NWeb::NWebPreference::CopyOptionMode::IN_APP);1319 (copyOption != OHOS::NWeb::NWebPreference::CopyOptionMode::IN_APP);
1303- if (info->menuInfo.showShare != (IsSupportMenuShare() && IsNeedMenuShare())) {1320+ if (info->menuInfo.showShare != (IsSupportMenuShare() && IsNeedMenuShareForWeb())) {
1304 info->menuInfo.showShare = !info->menuInfo.showShare && canCopyOut;1321 info->menuInfo.showShare = !info->menuInfo.showShare && canCopyOut;
1305 manager->NotifyUpdateToolBar(true);1322 manager->NotifyUpdateToolBar(true);
1306 }1323 }
@@ -104,6 +104,7 @@ public:
104 void SetEditMenuOptions(SelectOverlayInfo& selectInfo);104 void SetEditMenuOptions(SelectOverlayInfo& selectInfo);
105 void UpdateSelectHandleInfo();105 void UpdateSelectHandleInfo();
106 bool IsSelectHandleReverse();106 bool IsSelectHandleReverse();
107+ bool IsNeedMenuShareForWeb();
107 // Check whether the handle status is valid.108 // Check whether the handle status is valid.
108 WebOverlayType GetTouchHandleOverlayType(109 WebOverlayType GetTouchHandleOverlayType(
109 std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> insertHandle,110 std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> insertHandle,
@@ -7089,6 +7089,110 @@ HWTEST_F(WebSelectOverlayTest, IsMouseInHandleRect, TestSize.Level1)
7089#endif7089#endif
7090}7090}
7091 7091 
7092+/**
7093+ * @tc.name: IsNeedMenuShareForWeb
7094+ * @tc.desc: Test IsNeedMenuShareForWeb.
7095+ * @tc.type: FUNC
7096+ */
7097+HWTEST_F(WebSelectOverlayTest, IsNeedMenuShareForWeb, TestSize.Level1)
7098+{
7099+#ifdef OHOS_STANDARD_SYSTEM
7100+ auto* stack = ViewStackProcessor::GetInstance();
7101+ ASSERT_NE(stack, nullptr);
7102+ auto nodeId = stack->ClaimNodeId();
7103+ auto frameNode =
7104+ FrameNode::GetOrCreateFrameNode(V2::WEB_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<WebPattern>(); });
7105+ stack->Push(frameNode);
7106+ auto webPattern = frameNode->GetPattern<WebPattern>();
7107+ ASSERT_NE(webPattern, nullptr);
7108+ webPattern->OnModifyDone();
7109+ WebSelectOverlay overlay(webPattern);
7110+ OHOS::Ace::SetReturnStatus("");
7111+ EXPECT_FALSE(overlay.IsNeedMenuShareForWeb());
7112+ OHOS::Ace::SetReturnStatus(" ");
7113+ EXPECT_FALSE(overlay.IsNeedMenuShareForWeb());
7114+ OHOS::Ace::SetReturnStatus("");
7115+#endif
7116+}
7117+ 
7118+/**
7119+ * @tc.name: IsNeedMenuShareForWeb_TrimInvariant
zhufenghao
zhufenghaozhufenghao2025年12月10日

TDD结果附一下

likedislike
7120+ * @tc.desc: Verify ASCII whitespace trimming does not change share eligibility.
7121+ * @tc.type: FUNC
7122+ */
7123+HWTEST_F(WebSelectOverlayTest, IsNeedMenuShareForWeb_TrimInvariant, TestSize.Level1)
7124+{
7125+#ifdef OHOS_STANDARD_SYSTEM
7126+ auto* stack = ViewStackProcessor::GetInstance();
7127+ ASSERT_NE(stack, nullptr);
7128+ auto nodeId = stack->ClaimNodeId();
7129+ auto frameNode =
7130+ FrameNode::GetOrCreateFrameNode(V2::WEB_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<WebPattern>(); });
zhufenghao
zhufenghaozhufenghao2025年12月10日

已review

likedislike
7131+ stack->Push(frameNode);
7132+ auto webPattern = frameNode->GetPattern<WebPattern>();
7133+ ASSERT_NE(webPattern, nullptr);
7134+ webPattern->OnModifyDone();
7135+ WebSelectOverlay overlay(webPattern);
7136+ OHOS::Ace::SetReturnStatus(" \t\nabc\r\f\v ");
7137+ bool resTrim = overlay.IsNeedMenuShareForWeb();
7138+ OHOS::Ace::SetReturnStatus("abc");
7139+ bool resPlain = overlay.IsNeedMenuShareForWeb();
7140+ EXPECT_EQ(resTrim, resPlain);
7141+ OHOS::Ace::SetReturnStatus("");
7142+#endif
7143+}
7144+ 
7145+/**
7146+ * @tc.name: IsNeedMenuShareForWeb_MonotonicByLength
7147+ * @tc.desc: If longer text is eligible for share, shorter text must also be eligible.
7148+ * @tc.type: FUNC
7149+ */
7150+HWTEST_F(WebSelectOverlayTest, IsNeedMenuShareForWeb_MonotonicByLength, TestSize.Level1)
7151+{
7152+#ifdef OHOS_STANDARD_SYSTEM
7153+ auto* stack = ViewStackProcessor::GetInstance();
7154+ ASSERT_NE(stack, nullptr);
7155+ auto nodeId = stack->ClaimNodeId();
7156+ auto frameNode =
7157+ FrameNode::GetOrCreateFrameNode(V2::WEB_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<WebPattern>(); });
7158+ stack->Push(frameNode);
7159+ auto webPattern = frameNode->GetPattern<WebPattern>();
7160+ ASSERT_NE(webPattern, nullptr);
7161+ webPattern->OnModifyDone();
7162+ WebSelectOverlay overlay(webPattern);
7163+ OHOS::Ace::SetReturnStatus("aa");
7164+ bool resLong = overlay.IsNeedMenuShareForWeb();
7165+ OHOS::Ace::SetReturnStatus("a");
7166+ bool resShort = overlay.IsNeedMenuShareForWeb();
7167+ EXPECT_TRUE(!resLong || resShort);
7168+ OHOS::Ace::SetReturnStatus("");
7169+#endif
7170+}
7171+ 
7172+/**
7173+ * @tc.name: IsNeedMenuShareForWeb_WhitespaceVariants
7174+ * @tc.desc: Only ASCII whitespace text should be ineligible for sharing.
7175+ * @tc.type: FUNC
7176+ */
7177+HWTEST_F(WebSelectOverlayTest, IsNeedMenuShareForWeb_WhitespaceVariants, TestSize.Level1)
7178+{
7179+#ifdef OHOS_STANDARD_SYSTEM
7180+ auto* stack = ViewStackProcessor::GetInstance();
7181+ ASSERT_NE(stack, nullptr);
7182+ auto nodeId = stack->ClaimNodeId();
7183+ auto frameNode =
7184+ FrameNode::GetOrCreateFrameNode(V2::WEB_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<WebPattern>(); });
7185+ stack->Push(frameNode);
7186+ auto webPattern = frameNode->GetPattern<WebPattern>();
7187+ ASSERT_NE(webPattern, nullptr);
7188+ webPattern->OnModifyDone();
7189+ WebSelectOverlay overlay(webPattern);
7190+ OHOS::Ace::SetReturnStatus("\t\n\r\f\v ");
7191+ EXPECT_FALSE(overlay.IsNeedMenuShareForWeb());
7192+ OHOS::Ace::SetReturnStatus("");
7193+#endif
7194+}
7195+ 
7092/**7196/**
7093 * @tc.name: OnOverlayMouseEvent7197 * @tc.name: OnOverlayMouseEvent
7094 * @tc.desc: Test OnOverlayMouseEvent.7198 * @tc.desc: Test OnOverlayMouseEvent.