已合并
新增nestedScroll接口,web适配嵌套滚动父组件优先 #21217
zhufenghao创建于 2023年11月2日
新增nestedScroll接口,web适配嵌套滚动父组件优先 #21217
已合并
zhufenghao创建于 2023年11月2日
从refs/pull/21217/head合入到master
共 11 个文件变更+125-5
@@ -1640,6 +1640,7 @@ void JSWeb::JSBind(BindingTarget globalObj)
1640 JSClass<JSWeb>::StaticMethod("onOverScroll", &JSWeb::OnOverScroll);1640 JSClass<JSWeb>::StaticMethod("onOverScroll", &JSWeb::OnOverScroll);
1641 JSClass<JSWeb>::StaticMethod("onScreenCaptureRequest", &JSWeb::OnScreenCaptureRequest);1641 JSClass<JSWeb>::StaticMethod("onScreenCaptureRequest", &JSWeb::OnScreenCaptureRequest);
1642 JSClass<JSWeb>::StaticMethod("wrapContent", &JSWeb::WrapContent);1642 JSClass<JSWeb>::StaticMethod("wrapContent", &JSWeb::WrapContent);
1643+ JSClass<JSWeb>::StaticMethod("nestedScroll", &JSWeb::SetNestedScroll);
1643 JSClass<JSWeb>::InheritAndBind<JSViewAbstract>(globalObj);1644 JSClass<JSWeb>::InheritAndBind<JSViewAbstract>(globalObj);
1644 JSWebDialog::JSBind(globalObj);1645 JSWebDialog::JSBind(globalObj);
1645 JSWebGeolocation::JSBind(globalObj);1646 JSWebGeolocation::JSBind(globalObj);
@@ -3574,4 +3575,33 @@ void JSWeb::WrapContent(bool isWrapContentEnabled)
3574{3575{
3575 WebModel::GetInstance()->SetWrapContent(isWrapContentEnabled);3576 WebModel::GetInstance()->SetWrapContent(isWrapContentEnabled);
3576}3577}
3578+ 
3579+void JSWeb::SetNestedScroll(const JSCallbackInfo& args)
3580+{
3581+ NestedScrollOptions nestedOpt = {
3582+ .forward = NestedScrollMode::SELF_ONLY,
3583+ .backward = NestedScrollMode::SELF_ONLY,
3584+ };
3585+ if (args.Length() < 1 || !args[0]->IsObject()) {
3586+ WebModel::GetInstance()->SetNestedScroll(nestedOpt);
3587+ return;
3588+ }
3589+ JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
3590+ int32_t froward = 0;
3591+ JSViewAbstract::ParseJsInt32(obj->GetProperty("scrollForward"), froward);
3592+ if (froward < static_cast<int32_t>(NestedScrollMode::SELF_ONLY) ||
3593+ froward > static_cast<int32_t>(NestedScrollMode::PARALLEL)) {
3594+ froward = 0;
3595+ }
3596+ int32_t backward = 0;
3597+ JSViewAbstract::ParseJsInt32(obj->GetProperty("scrollBackward"), backward);
3598+ if (backward < static_cast<int32_t>(NestedScrollMode::SELF_ONLY) ||
3599+ backward > static_cast<int32_t>(NestedScrollMode::PARALLEL)) {
3600+ backward = 0;
3601+ }
3602+ nestedOpt.forward = static_cast<NestedScrollMode>(froward);
3603+ nestedOpt.backward = static_cast<NestedScrollMode>(backward);
3604+ WebModel::GetInstance()->SetNestedScroll(nestedOpt);
3605+ args.ReturnSelf();
3606+}
3577} // namespace OHOS::Ace::Framework3607} // namespace OHOS::Ace::Framework
@@ -129,6 +129,7 @@ public:
129 static void OnControllerAttached(const JSCallbackInfo& args);129 static void OnControllerAttached(const JSCallbackInfo& args);
130 static void OnOverScroll(const JSCallbackInfo& args);130 static void OnOverScroll(const JSCallbackInfo& args);
131 static void WrapContent(bool isWrapContentEnabled);131 static void WrapContent(bool isWrapContentEnabled);
132+ static void SetNestedScroll(const JSCallbackInfo& info);
132 // Enable or disable debugging of web content133 // Enable or disable debugging of web content
133 static bool webDebuggingAccess_;134 static bool webDebuggingAccess_;
134 static JSwebEventCallback OnControllerAttachedCallback_;135 static JSwebEventCallback OnControllerAttachedCallback_;
@@ -848,4 +848,12 @@ void WebClientImpl::OnRootLayerChanged(int width, int height)
848 CHECK_NULL_VOID(delegate);848 CHECK_NULL_VOID(delegate);
849 delegate->OnRootLayerChanged(width, height);849 delegate->OnRootLayerChanged(width, height);
850}850}
851+ 
852+bool WebClientImpl::FilterScrollEvent(const float x, const float y, const float xVelocity, const float yVelocity)
LongLie
LongLieLongLie2023年11月2日

改回调是跑在主线程吗,不是的话,可能会有多线程问题

likedislike
853+{
854+ ContainerScope scope(instanceId_);
855+ auto delegate = webDelegate_.Upgrade();
856+ CHECK_NULL_RETURN(delegate, false);
857+ return delegate->FilterScrollEvent(x, y, xVelocity, yVelocity);
858+}
851} // namespace OHOS::Ace859} // namespace OHOS::Ace
@@ -192,6 +192,7 @@ public:
192 void OnOverScrollFlingEnd() override;192 void OnOverScrollFlingEnd() override;
193 void OnScrollState(bool scrollState) override;193 void OnScrollState(bool scrollState) override;
194 void OnRootLayerChanged(int width, int height) override;194 void OnRootLayerChanged(int width, int height) override;
195+ bool FilterScrollEvent(const float x, const float y, const float xVelocity, const float yVelocity) override;
195 196 
196 void SetWebDelegate(const WeakPtr<WebDelegate>& delegate)197 void SetWebDelegate(const WeakPtr<WebDelegate>& delegate)
197 {198 {
@@ -5431,4 +5431,17 @@ bool WebDelegate::ShouldVirtualKeyboardOverlay()
5431 }5431 }
5432 return false;5432 return false;
5433}5433}
5434+ 
5435+bool WebDelegate::FilterScrollEvent(const float x, const float y, const float xVelocity, const float yVelocity)
5436+{
5437+ auto webPattern = webPattern_.Upgrade();
5438+ CHECK_NULL_RETURN(webPattern, false);
5439+ return webPattern->FilterScrollEvent(x, y, xVelocity, yVelocity);
5440+}
5441+ 
5442+void WebDelegate::ScrollBy(float deltaX, float deltaY)
5443+{
5444+ CHECK_NULL_VOID(nweb_);
5445+ nweb_->ScrollBy(deltaX, deltaY);
5446+}
5434} // namespace OHOS::Ace5447} // namespace OHOS::Ace
@@ -598,6 +598,7 @@ public:
598 void OnOverScrollFlingVelocity(float xVelocity, float yVelocity, bool isFling);598 void OnOverScrollFlingVelocity(float xVelocity, float yVelocity, bool isFling);
599 void OnScrollState(bool scrollState);599 void OnScrollState(bool scrollState);
600 void OnRootLayerChanged(int width, int height);600 void OnRootLayerChanged(int width, int height);
601+ bool FilterScrollEvent(const float x, const float y, const float xVelocity, const float yVelocity);
601 602 
602 void SetNGWebPattern(const RefPtr<NG::WebPattern>& webPattern);603 void SetNGWebPattern(const RefPtr<NG::WebPattern>& webPattern);
603 void RequestFocus();604 void RequestFocus();
@@ -635,6 +636,7 @@ public:
635 void SetToken();636 void SetToken();
636 void SetVirtualKeyBoardArg(int32_t width, int32_t height, double keyboard);637 void SetVirtualKeyBoardArg(int32_t width, int32_t height, double keyboard);
637 bool ShouldVirtualKeyboardOverlay();638 bool ShouldVirtualKeyboardOverlay();
639+ void ScrollBy(float deltaX, float deltaY);
638private:640private:
639 void InitWebEvent();641 void InitWebEvent();
640 void RegisterWebEvent();642 void RegisterWebEvent();
@@ -140,7 +140,8 @@ public:
140 virtual void SetOverScrollId(std::function<void(const BaseEventInfo* info)>&& jsCallback) = 0;140 virtual void SetOverScrollId(std::function<void(const BaseEventInfo* info)>&& jsCallback) = 0;
141 141 
142 virtual void SetScreenCaptureRequestEventId(std::function<void(const BaseEventInfo* info)>&& jsCallback) {};142 virtual void SetScreenCaptureRequestEventId(std::function<void(const BaseEventInfo* info)>&& jsCallback) {};
143- virtual void SetWrapContent(bool isWrapContentEnabled) {};143+ virtual void SetWrapContent(bool isWrapContentEnabled) {}
144+ virtual void SetNestedScroll(const NestedScrollOptions& nestedOpt) {}
144 145 
145private:146private:
146 static std::unique_ptr<WebModel> instance_;147 static std::unique_ptr<WebModel> instance_;
@@ -847,4 +847,11 @@ void WebModelNG::SetWrapContent(bool isWrapContentEnabled)
847 CHECK_NULL_VOID(webPattern);847 CHECK_NULL_VOID(webPattern);
848 webPattern->SetWrapContent(isWrapContentEnabled);848 webPattern->SetWrapContent(isWrapContentEnabled);
849}849}
850+ 
851+void WebModelNG::SetNestedScroll(const NestedScrollOptions& nestedOpt)
852+{
853+ auto webPattern = ViewStackProcessor::GetInstance()->GetMainFrameNodePattern<WebPattern>();
854+ CHECK_NULL_VOID(webPattern);
855+ webPattern->SetNestedScroll(nestedOpt);
856+}
850} // namespace OHOS::Ace::NG857} // namespace OHOS::Ace::NG
@@ -143,6 +143,7 @@ public:
143 void SetAudioExclusive(bool audioExclusive) override;143 void SetAudioExclusive(bool audioExclusive) override;
144 void SetOverScrollId(std::function<void(const BaseEventInfo* info)>&& jsCallback) override;144 void SetOverScrollId(std::function<void(const BaseEventInfo* info)>&& jsCallback) override;
145 void SetWrapContent(bool isWrapContentEnabled) override;145 void SetWrapContent(bool isWrapContentEnabled) override;
146+ void SetNestedScroll(const NestedScrollOptions& nestedOpt) override;
146};147};
147} // namespace OHOS::Ace::NG148} // namespace OHOS::Ace::NG
148#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WEB_WEB_MODEL_NG_H149#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_WEB_WEB_MODEL_NG_H
@@ -2446,18 +2446,24 @@ void WebPattern::OnScrollEndRecursive()
2446void WebPattern::OnOverScrollFlingVelocity(float xVelocity, float yVelocity, bool isFling)2446void WebPattern::OnOverScrollFlingVelocity(float xVelocity, float yVelocity, bool isFling)
2447{2447{
2448 float velocity = GetAxis() == Axis::HORIZONTAL ? xVelocity : yVelocity;2448 float velocity = GetAxis() == Axis::HORIZONTAL ? xVelocity : yVelocity;
2449+ if (nestedScrollMode_ != NestedScrollMode::SELF_FIRST) {
2450+ return;
2451+ }
2449 if (isFling) {2452 if (isFling) {
2450- if (isFirstFlingScrollVelocity_) {2453+ if (velocity != 0 && isFirstFlingScrollVelocity_) {
2451 HandleScrollVelocity(velocity);2454 HandleScrollVelocity(velocity);
2452 isFirstFlingScrollVelocity_ = false;2455 isFirstFlingScrollVelocity_ = false;
2453 }2456 }
2454 } else {2457 } else {
2455- HandleScroll(-velocity, SCROLL_FROM_UPDATE, NestedState::CHILD_SCROLL);2458+ if (scrollState_) {
2459+ HandleScroll(-velocity, SCROLL_FROM_UPDATE, NestedState::CHILD_SCROLL);
2460+ }
2456 }2461 }
2457}2462}
2458 2463 
2459void WebPattern::OnScrollState(bool scrollState)2464void WebPattern::OnScrollState(bool scrollState)
2460{2465{
2466+ scrollState_ = scrollState;
2461 if (!scrollState) {2467 if (!scrollState) {
2462 OnScrollEndRecursive();2468 OnScrollEndRecursive();
2463 }2469 }
@@ -2468,7 +2474,8 @@ Axis WebPattern::GetParentAxis()
2468 auto parent = WebSearchParent();2474 auto parent = WebSearchParent();
2469 parent_ = parent;2475 parent_ = parent;
2470 CHECK_NULL_RETURN(parent, Axis::HORIZONTAL);2476 CHECK_NULL_RETURN(parent, Axis::HORIZONTAL);
2471- return parent->GetAxis();2477+ axis_ = parent->GetAxis();
2478+ return axis_;
2472}2479}
2473 2480 
2474RefPtr<NestableScrollContainer> WebPattern::WebSearchParent()2481RefPtr<NestableScrollContainer> WebPattern::WebSearchParent()
@@ -2497,4 +2504,48 @@ void WebPattern::OnRootLayerChanged(int width, int height)
2497 CHECK_NULL_VOID(frameNode);2504 CHECK_NULL_VOID(frameNode);
2498 frameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);2505 frameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
2499}2506}
2507+ 
2508+void WebPattern::SetNestedScroll(const NestedScrollOptions& nestedOpt)
2509+{
2510+ if (nestedOpt.forward == NestedScrollMode::SELF_ONLY &&
2511+ nestedOpt.backward == NestedScrollMode::SELF_ONLY) {
2512+ nestedScrollMode_ = NestedScrollMode::SELF_ONLY;
2513+ } else if (nestedOpt.forward == NestedScrollMode::SELF_FIRST &&
2514+ nestedOpt.backward == NestedScrollMode::SELF_FIRST) {
2515+ nestedScrollMode_ = NestedScrollMode::SELF_FIRST;
2516+ } else if (nestedOpt.forward == NestedScrollMode::PARENT_FIRST &&
2517+ nestedOpt.backward == NestedScrollMode::PARENT_FIRST) {
2518+ nestedScrollMode_ = NestedScrollMode::PARENT_FIRST;
2519+ } else if (nestedOpt.forward == NestedScrollMode::PARALLEL &&
2520+ nestedOpt.backward == NestedScrollMode::PARALLEL) {
2521+ nestedScrollMode_ = NestedScrollMode::PARALLEL;
2522+ }
2523+ TAG_LOGD(AceLogTag::ACE_WEB, "SetNestedScroll %{public}d", nestedScrollMode_);
周沺耳zhufenghao
周沺耳周沺耳2023年11月2日

如果没有forward和backward不一样的情况,是不是只要判断一个就可以了

likedislike
zhufenghaozhufenghao2023年11月2日

如果没有forward和backward不一样的情况,是不是只要判断一个就可以了

不一样默认SELF_ONLY,先这样判断吧,只判断一个感觉不太合理。

likedislike
2524+}
2525+ 
2526+bool WebPattern::FilterScrollEvent(const float x, const float y, const float xVelocity, const float yVelocity)
2527+{
2528+ float offset = GetAxis() == Axis::HORIZONTAL ? x : y;
2529+ float velocity = GetAxis() == Axis::HORIZONTAL ? xVelocity : yVelocity;
2530+ if (nestedScrollMode_ == NestedScrollMode::PARENT_FIRST) {
2531+ if (offset != 0) {
2532+ auto result = HandleScroll(offset, SCROLL_FROM_UPDATE, NestedState::CHILD_SCROLL);
2533+ float remainOffset = result.remain;
2534+ CHECK_NULL_RETURN(delegate_, true);
2535+ TAG_LOGD(AceLogTag::ACE_WEB, "FilterScrollEvent ScrollBy remainOffset = %{public}f", remainOffset);
2536+ GetAxis() == Axis::HORIZONTAL ? delegate_->ScrollBy(-remainOffset, 0)
2537+ : delegate_->ScrollBy(0, -remainOffset);
2538+ } else {
2539+ HandleScrollVelocity(velocity);
2540+ }
2541+ return true;
2542+ } else if (nestedScrollMode_ == NestedScrollMode::PARALLEL) {
2543+ if (offset != 0) {
2544+ HandleScroll(offset, SCROLL_FROM_UPDATE, NestedState::CHILD_SCROLL);
2545+ } else {
2546+ HandleScrollVelocity(velocity);
2547+ }
2548+ }
2549+ return false;
2550+}
2500} // namespace OHOS::Ace::NG2551} // namespace OHOS::Ace::NG
@@ -259,7 +259,7 @@ public:
259 */259 */
260 Axis GetAxis() const override260 Axis GetAxis() const override
261 {261 {
262- return Axis::FREE;262+ return axis_;
263 }263 }
264 ScrollResult HandleScroll(float offset, int32_t source, NestedState state) override;264 ScrollResult HandleScroll(float offset, int32_t source, NestedState state) override;
265 bool HandleScrollVelocity(float velocity) override;265 bool HandleScrollVelocity(float velocity) override;
@@ -267,6 +267,7 @@ public:
267 void OnScrollEndRecursive() override;267 void OnScrollEndRecursive() override;
268 Axis GetParentAxis();268 Axis GetParentAxis();
269 RefPtr<NestableScrollContainer> WebSearchParent();269 RefPtr<NestableScrollContainer> WebSearchParent();
270+ void SetNestedScroll(const NestedScrollOptions& nestedOpt);
270 /**271 /**
271 * End of NestableScrollContainer implementations272 * End of NestableScrollContainer implementations
272 */273 */
@@ -381,6 +382,7 @@ public:
381 {382 {
382 return rootLayerHeight_;383 return rootLayerHeight_;
383 }384 }
385+ bool FilterScrollEvent(const float x, const float y, const float xVelocity, const float yVelocity);
384 386 
385private:387private:
386 void RegistVirtualKeyBoardListener();388 void RegistVirtualKeyBoardListener();
@@ -588,6 +590,9 @@ private:
588 bool isMemoryLevelEnable_ = true;590 bool isMemoryLevelEnable_ = true;
589 bool isFirstFlingScrollVelocity_ = true;591 bool isFirstFlingScrollVelocity_ = true;
590 bool isWrapContentEnabled_ = false;592 bool isWrapContentEnabled_ = false;
593+ bool scrollState_ = false;
594+ NestedScrollMode nestedScrollMode_ = NestedScrollMode::SELF_ONLY;
周沺耳zhufenghao
周沺耳周沺耳2023年11月2日

这个为啥不直接用枚举

likedislike
zhufenghaozhufenghao2023年11月2日

这个为啥不直接用枚举

已修改

likedislike
595+ Axis axis_ = Axis::FREE;
591 int32_t rootLayerWidth_ = 0;596 int32_t rootLayerWidth_ = 0;
周沺耳zhufenghao
周沺耳周沺耳2023年11月2日

这个和scrollMode作用看起来是一样的?

likedislike
zhufenghaozhufenghao2023年11月2日

已修改

likedislike
592 int32_t rootLayerHeight_ = 0;597 int32_t rootLayerHeight_ = 0;
593 WeakPtr<NestableScrollContainer> parent_;598 WeakPtr<NestableScrollContainer> parent_;