• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components/web/render_web.h"
17 
18 #include <cinttypes>
19 #include <iomanip>
20 #include <sstream>
21 
22 #include "base/log/log.h"
23 #include "base/mousestyle/mouse_style.h"
24 #include "base/utils/linear_map.h"
25 #include "base/utils/utils.h"
26 #include "core/common/manager_interface.h"
27 #include "core/components/positioned/positioned_component.h"
28 #include "core/components/web/resource/web_resource.h"
29 #include "core/event/ace_events.h"
30 #include "core/event/ace_event_helper.h"
31 
32 namespace OHOS::Ace {
33 namespace {
34 const LinearEnumMapNode<OHOS::NWeb::CursorType, MouseFormat> g_cursorTypeMap[] = {
35     { OHOS::NWeb::CursorType::CT_CROSS, MouseFormat::CROSS },
36     { OHOS::NWeb::CursorType::CT_HAND, MouseFormat::HAND_POINTING },
37     { OHOS::NWeb::CursorType::CT_IBEAM, MouseFormat::TEXT_CURSOR },
38     { OHOS::NWeb::CursorType::CT_HELP, MouseFormat::HELP },
39     { OHOS::NWeb::CursorType::CT_EASTRESIZE, MouseFormat::WEST_EAST },
40     { OHOS::NWeb::CursorType::CT_NORTHRESIZE, MouseFormat::NORTH_SOUTH },
41     { OHOS::NWeb::CursorType::CT_NORTHEASTRESIZE, MouseFormat::NORTH_EAST_SOUTH_WEST },
42     { OHOS::NWeb::CursorType::CT_NORTHWESTRESIZE, MouseFormat::NORTH_WEST_SOUTH_EAST },
43     { OHOS::NWeb::CursorType::CT_SOUTHRESIZE, MouseFormat::NORTH_SOUTH },
44     { OHOS::NWeb::CursorType::CT_SOUTHEASTRESIZE, MouseFormat::NORTH_WEST_SOUTH_EAST },
45     { OHOS::NWeb::CursorType::CT_SOUTHWESTRESIZE, MouseFormat::NORTH_EAST_SOUTH_WEST },
46     { OHOS::NWeb::CursorType::CT_WESTRESIZE, MouseFormat::WEST_EAST },
47     { OHOS::NWeb::CursorType::CT_NORTHSOUTHRESIZE, MouseFormat::NORTH_SOUTH },
48     { OHOS::NWeb::CursorType::CT_EASTWESTRESIZE, MouseFormat::WEST_EAST },
49     { OHOS::NWeb::CursorType::CT_NORTHEASTSOUTHWESTRESIZE, MouseFormat::NORTH_EAST_SOUTH_WEST },
50     { OHOS::NWeb::CursorType::CT_NORTHWESTSOUTHEASTRESIZE, MouseFormat::NORTH_WEST_SOUTH_EAST },
51     { OHOS::NWeb::CursorType::CT_COLUMNRESIZE, MouseFormat::RESIZE_LEFT_RIGHT },
52     { OHOS::NWeb::CursorType::CT_ROWRESIZE, MouseFormat::RESIZE_UP_DOWN },
53     { OHOS::NWeb::CursorType::CT_MIDDLEPANNING, MouseFormat::MIDDLE_BTN_NORTH_SOUTH_WEST_EAST },
54     { OHOS::NWeb::CursorType::CT_EASTPANNING, MouseFormat::MIDDLE_BTN_EAST },
55     { OHOS::NWeb::CursorType::CT_NORTHPANNING, MouseFormat::MIDDLE_BTN_NORTH },
56     { OHOS::NWeb::CursorType::CT_NORTHEASTPANNING, MouseFormat::MIDDLE_BTN_NORTH_EAST },
57     { OHOS::NWeb::CursorType::CT_NORTHWESTPANNING, MouseFormat::MIDDLE_BTN_NORTH_WEST },
58     { OHOS::NWeb::CursorType::CT_SOUTHPANNING, MouseFormat::MIDDLE_BTN_SOUTH },
59     { OHOS::NWeb::CursorType::CT_SOUTHEASTPANNING, MouseFormat::MIDDLE_BTN_SOUTH_EAST },
60     { OHOS::NWeb::CursorType::CT_SOUTHWESTPANNING, MouseFormat::MIDDLE_BTN_SOUTH_WEST },
61     { OHOS::NWeb::CursorType::CT_WESTPANNING, MouseFormat::MIDDLE_BTN_WEST },
62     { OHOS::NWeb::CursorType::CT_MOVE, MouseFormat::CURSOR_MOVE },
63     { OHOS::NWeb::CursorType::CT_NODROP, MouseFormat::CURSOR_FORBID },
64     { OHOS::NWeb::CursorType::CT_COPY, MouseFormat::CURSOR_COPY },
65     { OHOS::NWeb::CursorType::CT_NOTALLOWED, MouseFormat::CURSOR_FORBID },
66     { OHOS::NWeb::CursorType::CT_ZOOMIN, MouseFormat::ZOOM_IN },
67     { OHOS::NWeb::CursorType::CT_ZOOMOUT, MouseFormat::ZOOM_OUT },
68     { OHOS::NWeb::CursorType::CT_GRAB, MouseFormat::HAND_OPEN },
69     { OHOS::NWeb::CursorType::CT_GRABBING, MouseFormat::HAND_GRABBING },
70     { OHOS::NWeb::CursorType::CT_MIDDLE_PANNING_VERTICAL, MouseFormat::MIDDLE_BTN_NORTH_SOUTH },
71     { OHOS::NWeb::CursorType::CT_MIDDLE_PANNING_HORIZONTAL, MouseFormat::MIDDLE_BTN_NORTH_SOUTH_WEST_EAST },
72 };
73 } // namespace
74 
75 constexpr int32_t SINGLE_CLICK_NUM = 1;
76 constexpr int32_t DOUBLE_CLICK_NUM = 2;
77 constexpr int32_t DEFAULT_NUMS_ONE = 1;
78 constexpr double DEFAULT_DBCLICK_INTERVAL = 0.5f;
79 constexpr double DEFAULT_AXIS_RATIO = -0.06f;
80 
RenderWeb()81 RenderWeb::RenderWeb() : RenderNode(true)
82 {
83 #ifdef OHOS_STANDARD_SYSTEM
84     InitEnhanceSurfaceFlag();
85     Initialize();
86 #endif
87 }
88 
InitEnhanceSurfaceFlag()89 void RenderWeb::InitEnhanceSurfaceFlag()
90 {
91     if (SystemProperties::GetExtSurfaceEnabled()) {
92         isEnhanceSurface_ = true;
93     } else {
94         isEnhanceSurface_ = false;
95     }
96 }
97 
OnAttachContext()98 void RenderWeb::OnAttachContext()
99 {
100     auto pipelineContext = context_.Upgrade();
101     if (!pipelineContext) {
102         return;
103     }
104     if (delegate_) {
105         // web component is displayed in full screen by default.
106         drawSize_ = Size(pipelineContext->GetRootWidth(), pipelineContext->GetRootHeight());
107         drawSizeCache_ = drawSize_;
108         position_ = Offset(0, 0);
109         delegate_->SetEnhanceSurfaceFlag(isEnhanceSurface_);
110         delegate_->SetDrawSize(drawSize_);
111 #ifdef OHOS_STANDARD_SYSTEM
112         delegate_->InitOHOSWeb(context_);
113 #else
114         delegate_->CreatePlatformResource(drawSize_, position_, context_);
115 #endif
116     }
117 }
118 
RegistVirtualKeyBoardListener()119 void RenderWeb::RegistVirtualKeyBoardListener()
120 {
121     if (!needUpdateWeb_) {
122         return;
123     }
124     auto pipelineContext = context_.Upgrade();
125     if (!pipelineContext) {
126         return;
127     }
128     pipelineContext->SetVirtualKeyBoardCallback(
129         [weak = AceType::WeakClaim(this)](int32_t width, int32_t height, double keyboard) {
130             auto renderWeb = weak.Upgrade();
131             if (renderWeb) {
132                 return renderWeb->ProcessVirtualKeyBoard(width, height, keyboard);
133             }
134             return false;
135         });
136     needUpdateWeb_ = false;
137 }
138 
Update(const RefPtr<Component> & component)139 void RenderWeb::Update(const RefPtr<Component>& component)
140 {
141     const RefPtr<WebComponent> web = AceType::DynamicCast<WebComponent>(component);
142     if (!web) {
143         return;
144     }
145 
146     onMouse_ = web->GetOnMouseEventCallback();
147     onKeyEvent_ = web->GetOnKeyEventCallback();
148     onPreKeyEvent_ = web->GetOnInterceptKeyEventCallback();
149     RegistVirtualKeyBoardListener();
150 #ifdef OHOS_STANDARD_SYSTEM
151     InitPanEvent();
152 #endif
153     web_ = web;
154     if (delegate_) {
155         delegate_->SetComponent(web);
156         delegate_->UpdateJavaScriptEnabled(web->GetJsEnabled());
157         delegate_->UpdateBlockNetworkImage(web->GetOnLineImageAccessEnabled());
158         delegate_->UpdateAllowFileAccess(web->GetFileAccessEnabled());
159         delegate_->UpdateLoadsImagesAutomatically(web->GetImageAccessEnabled());
160         delegate_->UpdateMixedContentMode(web->GetMixedMode());
161         delegate_->UpdateSupportZoom(web->GetZoomAccessEnabled());
162         delegate_->UpdateDomStorageEnabled(web->GetDomStorageAccessEnabled());
163         delegate_->UpdateGeolocationEnabled(web->GetGeolocationAccessEnabled());
164         delegate_->UpdateCacheMode(web->GetCacheMode());
165         delegate_->UpdateOverviewModeEnabled(web->GetOverviewModeAccessEnabled());
166         delegate_->UpdateFileFromUrlEnabled(web->GetFileFromUrlAccessEnabled());
167         delegate_->UpdateDatabaseEnabled(web->GetDatabaseAccessEnabled());
168         delegate_->UpdateTextZoomRatio(web->GetTextZoomRatio());
169         delegate_->UpdateWebDebuggingAccess(web->GetWebDebuggingAccessEnabled());
170         delegate_->UpdateMediaPlayGestureAccess(web->IsMediaPlayGestureAccess());
171         delegate_->UpdatePinchSmoothModeEnabled(web->GetPinchSmoothModeEnabled());
172         delegate_->UpdateMultiWindowAccess(web->GetMultiWindowAccessEnabled());
173         delegate_->UpdateAllowWindowOpenMethod(web->GetAllowWindowOpenMethod());
174         auto userAgent = web->GetUserAgent();
175         if (!userAgent.empty()) {
176             delegate_->UpdateUserAgent(userAgent);
177         }
178         if (web->GetBackgroundColorEnabled()) {
179             delegate_->UpdateBackgroundColor(web->GetBackgroundColor());
180         }
181         if (web->GetIsInitialScaleSet()) {
182             delegate_->UpdateInitialScale(web->GetInitialScale());
183         }
184         delegate_->SetRenderWeb(AceType::WeakClaim(this));
185         onDragStart_ = web->GetOnDragStartId();
186         onDragEnter_ = web->GetOnDragEnterId();
187         onDragMove_ = web->GetOnDragMoveId();
188         onDragLeave_ = web->GetOnDragLeaveId();
189         onDrop_ = web->GetOnDropId();
190     }
191     MarkNeedLayout();
192 }
193 
ProcessVirtualKeyBoard(int32_t width,int32_t height,double keyboard)194 bool RenderWeb::ProcessVirtualKeyBoard(int32_t width, int32_t height, double keyboard)
195 {
196     if (delegate_) {
197         offsetFix_ = 0;
198         if (!isFocus_) {
199             if (isVirtualKeyBoardShow_ == VkState::VK_SHOW) {
200                 drawSize_.SetSize(drawSizeCache_);
201                 delegate_->SetBoundsOrResize(drawSize_, GetGlobalOffset());
202                 SyncGeometryProperties();
203                 SetRootView(width, height, 0);
204                 isVirtualKeyBoardShow_ = VkState::VK_HIDE;
205             }
206             return false;
207         }
208         if (NearZero(keyboard)) {
209             drawSize_.SetSize(drawSizeCache_);
210             delegate_->SetBoundsOrResize(drawSize_, GetGlobalOffset());
211             SyncGeometryProperties();
212             SetRootView(width, height, 0);
213             isVirtualKeyBoardShow_ = VkState::VK_HIDE;
214         } else if (isVirtualKeyBoardShow_ != VkState::VK_SHOW) {
215             drawSizeCache_.SetSize(drawSize_);
216             if (drawSize_.Height() <= (height - keyboard - GetCoordinatePoint().GetY())) {
217                 SetRootView(width, height, 0);
218                 isVirtualKeyBoardShow_ = VkState::VK_SHOW;
219                 return true;
220             }
221             if (height - GetCoordinatePoint().GetY() < keyboard) {
222                 return true;
223             }
224             drawSize_.SetHeight(height - keyboard - GetCoordinatePoint().GetY());
225             delegate_->SetBoundsOrResize(drawSize_, GetGlobalOffset());
226             SyncGeometryProperties();
227             SetRootView(width, height, DEFAULT_NUMS_ONE);
228             isVirtualKeyBoardShow_ = VkState::VK_SHOW;
229         }
230     }
231     return true;
232 }
233 
SetRootView(int32_t width,int32_t height,int32_t offset)234 void RenderWeb::SetRootView(int32_t width, int32_t height, int32_t offset)
235 {
236     auto pipelineContext = context_.Upgrade();
237     if (!pipelineContext) {
238         return;
239     }
240     pipelineContext->SetRootRect(width, height, offset);
241 }
242 
SendDoubleClickEvent(const MouseClickInfo & info)243 void RenderWeb::SendDoubleClickEvent(const MouseClickInfo& info)
244 {
245     if (!delegate_) {
246         return;
247     }
248     delegate_->OnMouseEvent(info.x,
249         info.y, MouseButton::LEFT_BUTTON, MouseAction::PRESS, DOUBLE_CLICK_NUM);
250 }
251 
HandleDoubleClickEvent(const MouseEvent & event)252 bool RenderWeb::HandleDoubleClickEvent(const MouseEvent& event)
253 {
254     if (event.button != MouseButton::LEFT_BUTTON || event.action != MouseAction::PRESS) {
255         return false;
256     }
257     auto localLocation = event.GetOffset() - Offset(GetCoordinatePoint().GetX(), GetCoordinatePoint().GetY());
258     MouseClickInfo info;
259     info.x = localLocation.GetX();
260     info.y = localLocation.GetY();
261     info.start = event.time;
262     if (doubleClickQueue_.empty()) {
263         doubleClickQueue_.push(info);
264         return false;
265     }
266     std::chrono::duration<float> timeout_ = info.start - doubleClickQueue_.back().start;
267     if (timeout_.count() < DEFAULT_DBCLICK_INTERVAL) {
268         SendDoubleClickEvent(info);
269         std::queue<MouseClickInfo> empty;
270         swap(empty, doubleClickQueue_);
271         return true;
272     }
273     if (doubleClickQueue_.size() == 1) {
274         doubleClickQueue_.push(info);
275         return false;
276     }
277     doubleClickQueue_.pop();
278     doubleClickQueue_.push(info);
279     return false;
280 }
281 
OnMouseEvent(const MouseEvent & event)282 void RenderWeb::OnMouseEvent(const MouseEvent& event)
283 {
284     if (!delegate_) {
285         return;
286     }
287 
288     if (web_ && event.action == MouseAction::RELEASE) {
289         web_->RequestFocus();
290     }
291 
292     auto localLocation = event.GetOffset() - Offset(GetCoordinatePoint().GetX(), GetCoordinatePoint().GetY());
293     if (!HandleDoubleClickEvent(event)) {
294         delegate_->OnMouseEvent(localLocation.GetX(),
295             localLocation.GetY(), event.button, event.action, SINGLE_CLICK_NUM);
296     }
297 
298     // clear the recording position, for not move content when virtual keyboard popup when web get focused.
299     auto context = GetContext().Upgrade();
300     if (context && context->GetTextFieldManager()) {
301         context->GetTextFieldManager()->SetClickPosition(Offset());
302     }
303 }
304 
HandleMouseEvent(const MouseEvent & event)305 bool RenderWeb::HandleMouseEvent(const MouseEvent& event)
306 {
307     OnMouseEvent(event);
308     if (!onMouse_) {
309         return false;
310     }
311 
312     MouseInfo info;
313     info.SetButton(event.button);
314     info.SetAction(event.action);
315     info.SetGlobalLocation(event.GetOffset());
316     info.SetLocalLocation(event.GetOffset() - Offset(GetCoordinatePoint().GetX(), GetCoordinatePoint().GetY()));
317     info.SetScreenLocation(event.GetScreenOffset());
318     info.SetTimeStamp(event.time);
319     info.SetDeviceId(event.deviceId);
320     info.SetSourceDevice(event.sourceType);
321     onMouse_(info);
322     return info.IsStopPropagation();
323 }
324 
HandleKeyEvent(const KeyEvent & keyEvent)325 bool RenderWeb::HandleKeyEvent(const KeyEvent& keyEvent)
326 {
327     KeyEventInfo info(keyEvent);
328     if (onKeyEvent_) {
329         onKeyEvent_(info);
330     }
331     if (onPreKeyEvent_) {
332         return onPreKeyEvent_(info);
333     }
334     return false;
335 }
336 
PerformLayout()337 void RenderWeb::PerformLayout()
338 {
339     if (!NeedLayout()) {
340         return;
341     }
342 
343     // render web do not support child.
344     drawSize_ = Size(GetLayoutParam().GetMaxSize().Width(), GetLayoutParam().GetMaxSize().Height());
345     drawSizeCache_ = drawSize_;
346     SetLayoutSize(drawSize_);
347     SetNeedLayout(false);
348     MarkNeedRender();
349 }
350 
351 #ifdef OHOS_STANDARD_SYSTEM
OnAppShow()352 void RenderWeb::OnAppShow()
353 {
354     RenderNode::OnAppShow();
355     if (delegate_) {
356         delegate_->ShowWebView();
357     }
358 }
359 
OnAppHide()360 void RenderWeb::OnAppHide()
361 {
362     RenderNode::OnAppHide();
363     needOnFocus_ = false;
364     if (delegate_) {
365         delegate_->HideWebView();
366     }
367 }
368 
OnGlobalPositionChanged()369 void RenderWeb::OnGlobalPositionChanged()
370 {
371     UpdateGlobalPos();
372     if (!textOverlay_ || !updateHandlePosition_) {
373         return;
374     }
375     OnTouchSelectionChanged(insertHandle_, startSelectionHandle_, endSelectionHandle_);
376 }
377 
OnPositionChanged()378 void RenderWeb::OnPositionChanged()
379 {
380     PopTextOverlay();
381 }
382 
OnSizeChanged()383 void RenderWeb::OnSizeChanged()
384 {
385     if (drawSize_.IsWidthInfinite() || drawSize_.IsHeightInfinite() ||
386         drawSize_.Width() == 0 || drawSize_.Height() == 0) {
387         return;
388     }
389     auto context = context_.Upgrade();
390     if (!context) {
391         return;
392     }
393     UpdateGlobalPos();
394     if (delegate_ && !isUrlLoaded_) {
395         delegate_->SetBoundsOrResize(drawSize_, GetGlobalOffset());
396         if (!delegate_->LoadDataWithRichText()) {
397             delegate_->LoadUrl();
398         }
399         isUrlLoaded_ = true;
400     }
401 }
402 
Initialize()403 void RenderWeb::Initialize()
404 {
405     touchRecognizer_ = AceType::MakeRefPtr<RawRecognizer>();
406     touchRecognizer_->SetOnTouchDown([weakItem = AceType::WeakClaim(this)](const TouchEventInfo& info) {
407         auto item = weakItem.Upgrade();
408         if (item) {
409             item->HandleTouchDown(info, false);
410         }
411     });
412     touchRecognizer_->SetOnTouchUp([weakItem = AceType::WeakClaim(this)](const TouchEventInfo& info) {
413         auto item = weakItem.Upgrade();
414         if (item) {
415             item->HandleTouchUp(info, false);
416         }
417     });
418     touchRecognizer_->SetOnTouchMove([weakItem = AceType::WeakClaim(this)](const TouchEventInfo& info) {
419         auto item = weakItem.Upgrade();
420         if (item) {
421             item->HandleTouchMove(info, false);
422         }
423     });
424     touchRecognizer_->SetOnTouchCancel([weakItem = AceType::WeakClaim(this)](const TouchEventInfo& info) {
425         auto item = weakItem.Upgrade();
426         if (item) {
427             item->HandleTouchCancel(info);
428         }
429     });
430 }
431 
InitPanEvent()432 void RenderWeb::InitPanEvent()
433 {
434     auto context = context_.Upgrade();
435     if (panRecognizer_ || !context) {
436         return;
437     }
438     PanDirection panDirection;
439     panDirection.type = PanDirection::VERTICAL;
440     panRecognizer_ = AceType::MakeRefPtr<PanRecognizer>(
441         context, DEFAULT_PAN_FINGER, panDirection, DEFAULT_PAN_DISTANCE.ConvertToPx());
442     panRecognizer_->SetOnActionUpdate([weakItem = AceType::WeakClaim(this)](const GestureEvent& event) {
443         auto item = weakItem.Upgrade();
444         if (item) {
445             item->HandleDragMove(event);
446         }
447     });
448 }
449 
HandleDragMove(const GestureEvent & event)450 void RenderWeb::HandleDragMove(const GestureEvent& event)
451 {
452     if (event.GetInputEventType() == InputEventType::AXIS) {
453         if (!delegate_) {
454             return;
455         }
456         auto localLocation = event.GetLocalLocation();
457         delegate_->HandleAxisEvent(
458             localLocation.GetX(), localLocation.GetY(),
459             event.GetDelta().GetX() * DEFAULT_AXIS_RATIO,
460             event.GetDelta().GetY() * DEFAULT_AXIS_RATIO);
461     }
462 }
463 
HandleTouchDown(const TouchEventInfo & info,bool fromOverlay)464 void RenderWeb::HandleTouchDown(const TouchEventInfo& info, bool fromOverlay)
465 {
466     if (!delegate_) {
467         return;
468     }
469     Offset touchOffset = Offset(0, 0);
470     std::list<TouchInfo> touchInfos;
471     if (!ParseTouchInfo(info, touchInfos, TouchType::DOWN)) {
472         TAG_LOGW(AceLogTag::ACE_WEB, "Parse touch event down failed, This event will not be handled.");
473         return;
474     }
475     for (auto& touchPoint : touchInfos) {
476         if (fromOverlay) {
477             touchPoint.x -= GetGlobalOffset().GetX();
478             touchPoint.y -= GetGlobalOffset().GetY() + offsetFix_;
479         }
480         touchOffset = Offset(touchPoint.x, touchPoint.y);
481         delegate_->HandleTouchDown(touchPoint.id, touchPoint.x, touchPoint.y, fromOverlay);
482     }
483     // clear the recording position, for not move content when virtual keyboard popup when web get focused.
484     auto context = GetContext().Upgrade();
485     if (context && context->GetTextFieldManager()) {
486         context->GetTextFieldManager()->SetClickPosition(Offset());
487     }
488 }
489 
HandleTouchUp(const TouchEventInfo & info,bool fromOverlay)490 void RenderWeb::HandleTouchUp(const TouchEventInfo& info, bool fromOverlay)
491 {
492     if (!delegate_) {
493         return;
494     }
495     std::list<TouchInfo> touchInfos;
496     if (!ParseTouchInfo(info, touchInfos, TouchType::UP)) {
497         TAG_LOGW(AceLogTag::ACE_WEB, "Parse touch event up failed, This event will not be handled.");
498         return;
499     }
500     for (auto& touchPoint : touchInfos) {
501         if (fromOverlay) {
502             touchPoint.x -= GetGlobalOffset().GetX();
503             touchPoint.y -= GetGlobalOffset().GetY() + offsetFix_;
504         }
505         delegate_->HandleTouchUp(touchPoint.id, touchPoint.x, touchPoint.y, fromOverlay);
506     }
507     if (web_ && !touchInfos.empty()) {
508         web_->RequestFocus();
509     }
510 }
511 
HandleTouchMove(const TouchEventInfo & info,bool fromOverlay)512 void RenderWeb::HandleTouchMove(const TouchEventInfo& info, bool fromOverlay)
513 {
514     if (isDragging_) {
515         return;
516     }
517 
518     if (!delegate_) {
519         return;
520     }
521     std::list<TouchInfo> touchInfos;
522     if (!ParseTouchInfo(info, touchInfos, TouchType::MOVE)) {
523         return;
524     }
525     for (auto& touchPoint : touchInfos) {
526         if (fromOverlay) {
527             touchPoint.x -= GetGlobalOffset().GetX();
528             touchPoint.y -= GetGlobalOffset().GetY() + offsetFix_;
529         }
530         delegate_->HandleTouchMove(touchPoint.id, touchPoint.x, touchPoint.y, fromOverlay);
531     }
532 }
533 
HandleTouchCancel(const TouchEventInfo & info)534 void RenderWeb::HandleTouchCancel(const TouchEventInfo& info)
535 {
536     if (!delegate_) {
537         return;
538     }
539     delegate_->HandleTouchCancel();
540 }
541 
ParseTouchInfo(const TouchEventInfo & info,std::list<TouchInfo> & touchInfos,const TouchType & touchType)542 bool RenderWeb::ParseTouchInfo(const TouchEventInfo& info, std::list<TouchInfo>& touchInfos, const TouchType& touchType)
543 {
544     auto context = context_.Upgrade();
545     if (!context) {
546         return false;
547     }
548     auto viewScale = context->GetViewScale();
549     if (touchType == TouchType::DOWN) {
550         if (!info.GetTouches().empty()) {
551             for (auto& point : info.GetTouches()) {
552                 TouchInfo touchInfo;
553                 touchInfo.id = point.GetFingerId();
554                 Offset location = point.GetLocalLocation();
555                 touchInfo.x = location.GetX() * viewScale;
556                 touchInfo.y = location.GetY() * viewScale;
557                 touchInfos.emplace_back(touchInfo);
558             }
559         } else {
560             return false;
561         }
562     } else if (touchType == TouchType::MOVE) {
563         if (!info.GetChangedTouches().empty()) {
564             for (auto& point : info.GetChangedTouches()) {
565                 TouchInfo touchInfo;
566                 touchInfo.id = point.GetFingerId();
567                 Offset location = point.GetLocalLocation();
568                 touchInfo.x = location.GetX() * viewScale;
569                 touchInfo.y = location.GetY() * viewScale;
570                 touchInfos.emplace_back(touchInfo);
571             }
572         } else {
573             return false;
574         }
575     } else if (touchType == TouchType::UP) {
576         if (!info.GetChangedTouches().empty()) {
577             for (auto& point : info.GetChangedTouches()) {
578                 TouchInfo touchInfo;
579                 touchInfo.id = point.GetFingerId();
580                 Offset location = point.GetLocalLocation();
581                 touchInfo.x = location.GetX() * viewScale;
582                 touchInfo.y = location.GetY() * viewScale;
583                 touchInfos.emplace_back(touchInfo);
584             }
585         } else {
586             return false;
587         }
588     }
589     return true;
590 }
591 
SetUpdateHandlePosition(const std::function<void (const OverlayShowOption &,float,float)> & updateHandlePosition)592 void RenderWeb::SetUpdateHandlePosition(
593     const std::function<void(const OverlayShowOption&, float, float)>& updateHandlePosition)
594 {
595     updateHandlePosition_ = updateHandlePosition;
596 }
597 
OnTouchTestHit(const Offset & coordinateOffset,const TouchRestrict & touchRestrict,TouchTestResult & result)598 void RenderWeb::OnTouchTestHit(const Offset& coordinateOffset, const TouchRestrict& touchRestrict,
599     TouchTestResult& result)
600 {
601     if (dragDropGesture_) {
602         dragDropGesture_->SetCoordinateOffset(coordinateOffset);
603         result.emplace_back(dragDropGesture_);
604         MarkIsNotSiblingAddRecognizerToResult(true);
605     }
606 
607     if (panRecognizer_) {
608         panRecognizer_->SetCoordinateOffset(coordinateOffset);
609         result.emplace_back(panRecognizer_);
610     }
611 
612     if (!touchRecognizer_) {
613         return;
614     }
615 
616     if (touchRestrict.sourceType != SourceType::TOUCH) {
617         return;
618     }
619     touchRecognizer_->SetCoordinateOffset(coordinateOffset);
620     result.emplace_back(touchRecognizer_);
621 }
622 
IsAxisScrollable(AxisDirection direction)623 bool RenderWeb::IsAxisScrollable(AxisDirection direction)
624 {
625     return true;
626 }
627 
CheckAxisNode()628 WeakPtr<RenderNode> RenderWeb::CheckAxisNode()
629 {
630     return AceType::WeakClaim<RenderNode>(this);
631 }
632 
PushTextOverlayToStack()633 void RenderWeb::PushTextOverlayToStack()
634 {
635     if (!textOverlay_) {
636         return;
637     }
638 
639     auto context = context_.Upgrade();
640     if (!context) {
641         return;
642     }
643     auto lastStack = context->GetLastStack();
644     if (!lastStack) {
645         return;
646     }
647     lastStack->PushComponent(textOverlay_, false);
648     stackElement_ = WeakClaim(RawPtr(lastStack));
649 }
650 
TextOverlayMenuShouldShow() const651 bool RenderWeb::TextOverlayMenuShouldShow() const
652 {
653     return showTextOveralyMenu_;
654 }
655 
GetShowStartTouchHandle() const656 bool RenderWeb::GetShowStartTouchHandle() const
657 {
658     return showStartTouchHandle_;
659 }
660 
GetShowEndTouchHandle() const661 bool RenderWeb::GetShowEndTouchHandle() const
662 {
663     return showEndTouchHandle_;
664 }
665 
RunQuickMenu(std::shared_ptr<OHOS::NWeb::NWebQuickMenuParams> params,std::shared_ptr<OHOS::NWeb::NWebQuickMenuCallback> callback)666 bool RenderWeb::RunQuickMenu(
667     std::shared_ptr<OHOS::NWeb::NWebQuickMenuParams> params,
668     std::shared_ptr<OHOS::NWeb::NWebQuickMenuCallback> callback)
669 {
670     auto context = context_.Upgrade();
671     if (!context || !params || !callback) {
672         return false;
673     }
674 
675     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> insertTouchHandle =
676         params->GetTouchHandleState(OHOS::NWeb::NWebTouchHandleState::TouchHandleType::INSERT_HANDLE);
677     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> beginTouchHandle =
678         params->GetTouchHandleState(OHOS::NWeb::NWebTouchHandleState::TouchHandleType::SELECTION_BEGIN_HANDLE);
679     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endTouchHandle =
680         params->GetTouchHandleState(OHOS::NWeb::NWebTouchHandleState::TouchHandleType::SELECTION_END_HANDLE);
681     WebOverlayType overlayType = GetTouchHandleOverlayType(insertTouchHandle,
682                                                            beginTouchHandle,
683                                                            endTouchHandle);
684     insertHandle_ = insertTouchHandle;
685     startSelectionHandle_ = beginTouchHandle;
686     endSelectionHandle_ = endTouchHandle;
687     if (textOverlay_ || overlayType == INVALID_OVERLAY) {
688         PopTextOverlay();
689     }
690     textOverlay_ = CreateTextOverlay(insertTouchHandle, beginTouchHandle, endTouchHandle);
691     if (!textOverlay_) {
692         return false;
693     }
694 
695     showTextOveralyMenu_ = true;
696     showStartTouchHandle_ = (overlayType == INSERT_OVERLAY) ?
697         IsTouchHandleShow(insertTouchHandle) : IsTouchHandleShow(beginTouchHandle);
698     showEndTouchHandle_ = (overlayType == INSERT_OVERLAY) ?
699         IsTouchHandleShow(insertTouchHandle) : IsTouchHandleShow(endTouchHandle);
700 
701     RegisterTextOverlayCallback(params->GetEditStateFlags(), callback);
702     PushTextOverlayToStack();
703     return true;
704 }
705 
OnQuickMenuDismissed()706 void RenderWeb::OnQuickMenuDismissed()
707 {
708     PopTextOverlay();
709 }
710 
PopTextOverlay()711 void RenderWeb::PopTextOverlay()
712 {
713     auto context = context_.Upgrade();
714     if (!context) {
715         return;
716     }
717 
718     if (!textOverlay_) {
719         return;
720     }
721 
722     const auto& stackElement = stackElement_.Upgrade();
723     if (stackElement) {
724         stackElement->PopTextOverlay();
725     }
726 
727     textOverlay_ = nullptr;
728     showTextOveralyMenu_ = false;
729     showStartTouchHandle_ = false;
730     showEndTouchHandle_ = false;
731 }
732 
RegisterTextOverlayCallback(int32_t flags,std::shared_ptr<OHOS::NWeb::NWebQuickMenuCallback> callback)733 void RenderWeb::RegisterTextOverlayCallback(int32_t flags,
734     std::shared_ptr<OHOS::NWeb::NWebQuickMenuCallback> callback)
735 {
736     if (!callback || !textOverlay_) {
737         return;
738     }
739 
740     if (flags & OHOS::NWeb::NWebQuickMenuParams::QM_EF_CAN_CUT) {
741         textOverlay_->SetOnCut([weak = AceType::WeakClaim(this), callback] {
742             if (callback) {
743                 callback->Continue(OHOS::NWeb::NWebQuickMenuParams::QM_EF_CAN_CUT,
744                     OHOS::NWeb::MenuEventFlags::EF_LEFT_MOUSE_BUTTON);
745             }
746         });
747     }
748     if (flags & OHOS::NWeb::NWebQuickMenuParams::QM_EF_CAN_COPY) {
749         textOverlay_->SetOnCopy([weak = AceType::WeakClaim(this), callback] {
750             if (callback) {
751                 callback->Continue(OHOS::NWeb::NWebQuickMenuParams::QM_EF_CAN_COPY,
752                     OHOS::NWeb::MenuEventFlags::EF_LEFT_MOUSE_BUTTON);
753             }
754         });
755     }
756     if (flags & OHOS::NWeb::NWebQuickMenuParams::QM_EF_CAN_PASTE) {
757         textOverlay_->SetOnPaste([weak = AceType::WeakClaim(this), callback] {
758             if (callback) {
759                 callback->Continue(OHOS::NWeb::NWebQuickMenuParams::QM_EF_CAN_PASTE,
760                     OHOS::NWeb::MenuEventFlags::EF_LEFT_MOUSE_BUTTON);
761             }
762         });
763     }
764     if (flags & OHOS::NWeb::NWebQuickMenuParams::QM_EF_CAN_SELECT_ALL) {
765         textOverlay_->SetOnCopyAll(
766             [weak = AceType::WeakClaim(this), callback]
767             (const std::function<void(const Offset&, const Offset&)>& temp) {
768                 callback->Continue(OHOS::NWeb::NWebQuickMenuParams::QM_EF_CAN_SELECT_ALL,
769                     OHOS::NWeb::MenuEventFlags::EF_LEFT_MOUSE_BUTTON);
770             });
771     }
772 }
773 
774 
IsTouchHandleValid(std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> handle)775 bool RenderWeb::IsTouchHandleValid(
776     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> handle)
777 {
778     return (handle != nullptr) && (handle->IsEnable());
779 }
780 
IsTouchHandleShow(std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> handle)781 bool RenderWeb::IsTouchHandleShow(
782     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> handle)
783 {
784     if (handle->GetAlpha() > 0 &&
785         GreatOrEqual(handle->GetY(), static_cast<int32_t>(handle->GetEdgeHeight())) &&
786         GreatNotEqual(GetLayoutSize().Height(), handle->GetY())) {
787         return true;
788     }
789     return false;
790 }
791 
GetTouchHandleOverlayType(std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> insertHandle,std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> startSelectionHandle,std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endSelectionHandle)792 WebOverlayType RenderWeb::GetTouchHandleOverlayType(
793     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> insertHandle,
794     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> startSelectionHandle,
795     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endSelectionHandle)
796 {
797     if (IsTouchHandleValid(insertHandle) &&
798         !IsTouchHandleValid(startSelectionHandle) &&
799         !IsTouchHandleValid(endSelectionHandle)) {
800         return INSERT_OVERLAY;
801     }
802 
803     if (!IsTouchHandleValid(insertHandle) &&
804         IsTouchHandleValid(startSelectionHandle) &&
805         IsTouchHandleValid(endSelectionHandle)) {
806         return SELECTION_OVERLAY;
807     }
808 
809     return INVALID_OVERLAY;
810 }
811 
CreateTextOverlay(std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> insertHandle,std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> startSelectionHandle,std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endSelectionHandle)812 RefPtr<TextOverlayComponent> RenderWeb::CreateTextOverlay(
813     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> insertHandle,
814     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> startSelectionHandle,
815     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endSelectionHandle)
816 {
817     auto context = context_.Upgrade();
818     if (!context) {
819         return nullptr;
820     }
821 
822     WebOverlayType overlayType = GetTouchHandleOverlayType(insertHandle,
823                                                            startSelectionHandle,
824                                                            endSelectionHandle);
825     if (overlayType == INVALID_OVERLAY) {
826         return nullptr;
827     }
828 
829     RefPtr<TextOverlayComponent> textOverlay =
830         AceType::MakeRefPtr<TextOverlayComponent>(context->GetThemeManager(), context->GetAccessibilityManager());
831     if (!textOverlay) {
832         return nullptr;
833     }
834 
835     Offset startOffset;
836     Offset endOffset;
837     float startEdgeHeight;
838     float endEdgeHeight;
839     if (overlayType == INSERT_OVERLAY) {
840         float lineHeight = GreatNotEqual(insertHandle->GetEdgeHeight(), insertHandle->GetY()) ?
841             insertHandle->GetY() : insertHandle->GetEdgeHeight();
842         startOffset = NormalizeTouchHandleOffset(insertHandle->GetX()+1, insertHandle->GetY());
843         endOffset = startOffset;
844         startEdgeHeight = lineHeight;
845         endEdgeHeight = lineHeight;
846     } else {
847         startOffset = NormalizeTouchHandleOffset(startSelectionHandle->GetX(), startSelectionHandle->GetY());
848         endOffset = NormalizeTouchHandleOffset(endSelectionHandle->GetX(), endSelectionHandle->GetY());
849         startEdgeHeight = startSelectionHandle->GetEdgeHeight();
850         endEdgeHeight = endSelectionHandle->GetEdgeHeight();
851     }
852     textOverlay->SetWeakWeb(WeakClaim(this));
853     textOverlay->SetIsSingleHandle(false);
854     Rect clipRect(0.0, 0.0, Size::INFINITE_SIZE, Size::INFINITE_SIZE);
855     textOverlay->SetLineHeight(startEdgeHeight);
856     textOverlay->SetStartHandleHeight(startEdgeHeight);
857     textOverlay->SetEndHandleHeight(endEdgeHeight);
858     textOverlay->SetClipRect(clipRect);
859     textOverlay->SetNeedCilpRect(false);
860     textOverlay->SetStartHandleOffset(startOffset);
861     textOverlay->SetEndHandleOffset(endOffset);
862     textOverlay->SetTextDirection(TextDirection::LTR);
863     textOverlay->SetRealTextDirection(TextDirection::LTR);
864     textOverlay->SetContext(context_);
865     textOverlay->SetIsUsingMouse(false);
866     return textOverlay;
867 }
868 
NormalizeTouchHandleOffset(float x,float y)869 Offset RenderWeb::NormalizeTouchHandleOffset(float x, float y)
870 {
871     Offset renderWebOffset = GetGlobalOffset();
872     Size renderWebSize = GetLayoutSize();
873     float resultX;
874     float resultY;
875     if (x < 0) {
876         resultX = x;
877     } else if (x > renderWebSize.Width()) {
878         resultX = renderWebOffset.GetX() + renderWebSize.Width();
879     } else {
880         resultX = x + renderWebOffset.GetX();
881     }
882 
883     if (y < 0) {
884         resultY = renderWebOffset.GetY();
885     } else if (y > renderWebSize.Height()) {
886         resultY = renderWebOffset.GetY() + renderWebSize.Height();
887     } else {
888         resultY = y + renderWebOffset.GetY();
889     }
890     resultY += offsetFix_;
891     return {resultX, resultY};
892 }
893 
OnTouchSelectionChanged(std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> insertHandle,std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> startSelectionHandle,std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endSelectionHandle)894 void RenderWeb::OnTouchSelectionChanged(
895     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> insertHandle,
896     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> startSelectionHandle,
897     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endSelectionHandle)
898 {
899     auto context = context_.Upgrade();
900     if (!context) {
901         return;
902     }
903 
904     WebOverlayType overlayType = GetTouchHandleOverlayType(insertHandle,
905                                                            startSelectionHandle,
906                                                            endSelectionHandle);
907     insertHandle_ = insertHandle;
908     startSelectionHandle_ = startSelectionHandle;
909     endSelectionHandle_ = endSelectionHandle;
910     if (overlayType == INVALID_OVERLAY) {
911         PopTextOverlay();
912         return;
913     }
914 
915     if (!textOverlay_) {
916         if (overlayType == INSERT_OVERLAY) {
917             showTextOveralyMenu_ = false;
918             showStartTouchHandle_ = IsTouchHandleShow(insertHandle);
919             showEndTouchHandle_ = IsTouchHandleShow(insertHandle);
920             if (!showStartTouchHandle_) {
921                 return;
922             }
923             textOverlay_ = CreateTextOverlay(insertHandle, startSelectionHandle, endSelectionHandle);
924             PushTextOverlayToStack();
925         }
926         return;
927     }
928 
929     if (overlayType == INSERT_OVERLAY) {
930         showStartTouchHandle_ = IsTouchHandleShow(insertHandle);
931         showEndTouchHandle_ = IsTouchHandleShow(insertHandle);
932         if (!showStartTouchHandle_) {
933             PopTextOverlay();
934             return;
935         }
936         float lineHeight = GreatNotEqual(insertHandle->GetEdgeHeight(), insertHandle->GetY()) ?
937             insertHandle->GetY() : insertHandle->GetEdgeHeight();
938         textOverlay_->SetStartHandleHeight(lineHeight);
939         showTextOveralyMenu_ = false;
940         OverlayShowOption option {
941             .showMenu = showTextOveralyMenu_,
942             .isSingleHandle = true,
943             .startHandleOffset = NormalizeTouchHandleOffset(insertHandle->GetX() + 1, insertHandle->GetY()),
944             .endHandleOffset = NormalizeTouchHandleOffset(insertHandle->GetX() + 1, insertHandle->GetY()),
945             .showStartHandle = showStartTouchHandle_,
946             .showEndHandle = showEndTouchHandle_,
947         };
948         if (updateHandlePosition_) {
949             updateHandlePosition_(option, lineHeight, lineHeight);
950         }
951     } else {
952         showStartTouchHandle_ = IsTouchHandleShow(startSelectionHandle);
953         showEndTouchHandle_ = IsTouchHandleShow(endSelectionHandle);
954         textOverlay_->SetStartHandleHeight(startSelectionHandle->GetEdgeHeight());
955         textOverlay_->SetEndHandleHeight(endSelectionHandle->GetEdgeHeight());
956         OverlayShowOption option {
957             .showMenu = true,
958             .isSingleHandle = false,
959             .startHandleOffset = NormalizeTouchHandleOffset(startSelectionHandle->GetX(), startSelectionHandle->GetY()),
960             .endHandleOffset = NormalizeTouchHandleOffset(endSelectionHandle->GetX(), endSelectionHandle->GetY()),
961             .showStartHandle = showStartTouchHandle_,
962             .showEndHandle = showEndTouchHandle_,
963         };
964         if (updateHandlePosition_) {
965             updateHandlePosition_(option, startSelectionHandle->GetEdgeHeight(), endSelectionHandle->GetEdgeHeight());
966         }
967     }
968 }
969 
OnCursorChange(const OHOS::NWeb::CursorType & type,const OHOS::NWeb::NWebCursorInfo & info)970 bool RenderWeb::OnCursorChange(const OHOS::NWeb::CursorType& type, const OHOS::NWeb::NWebCursorInfo& info)
971 {
972     (void)info;
973     auto context = GetContext().Upgrade();
974     if (!context) {
975         return false;
976     }
977     auto windowId = context->GetWindowId();
978     auto mouseStyle = MouseStyle::CreateMouseStyle();
979     int32_t curPointerStyle = 0;
980     if (mouseStyle->GetPointerStyle(windowId, curPointerStyle) == -1) {
981         return false;
982     }
983     MouseFormat pointStyle = MouseFormat::DEFAULT;
984     int64_t idx = BinarySearchFindIndex(g_cursorTypeMap, ArraySize(g_cursorTypeMap), type);
985     if (idx >= 0) {
986         pointStyle = g_cursorTypeMap[idx].value;
987     }
988     if ((int32_t)pointStyle != curPointerStyle) {
989         mouseStyle->SetPointerStyle(windowId, pointStyle);
990     }
991     return true;
992 }
993 
GenerateDragItemInfo(const RefPtr<PipelineContext> & context,const GestureEvent & info)994 DragItemInfo RenderWeb::GenerateDragItemInfo(const RefPtr<PipelineContext>& context, const GestureEvent& info)
995 {
996     DragItemInfo itemInfo;
997     if (delegate_) {
998         itemInfo.pixelMap =  delegate_->GetDragPixelMap();
999     }
1000 
1001     if (itemInfo.pixelMap) {
1002         isW3cDragEvent_ = true;
1003         return itemInfo;
1004     }
1005 
1006     if (onDragStart_) {
1007         isW3cDragEvent_ = false;
1008         RefPtr<DragEvent> event = AceType::MakeRefPtr<DragEvent>();
1009         event->SetX(context->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
1010         event->SetY(context->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
1011         selectedItemSize_ = GetLayoutSize();
1012         auto extraParams = JsonUtil::Create(true);
1013         return onDragStart_(event, extraParams->ToString());
1014     }
1015 
1016     return itemInfo;
1017 }
1018 
OnDragWindowStartEvent(RefPtr<PipelineContext> pipelineContext,const GestureEvent & info,const DragItemInfo & dragItemInfo)1019 void RenderWeb::OnDragWindowStartEvent(RefPtr<PipelineContext> pipelineContext, const GestureEvent& info,
1020     const DragItemInfo& dragItemInfo)
1021 {
1022     auto rect = pipelineContext->GetCurrentWindowRect();
1023     int32_t globalX = static_cast<int32_t>(info.GetGlobalPoint().GetX());
1024     int32_t globalY = static_cast<int32_t>(info.GetGlobalPoint().GetY());
1025     dragWindow_ = DragWindow::CreateDragWindow("APP_DRAG_WINDOW", globalX + rect.Left(), globalY + rect.Top(),
1026         dragItemInfo.pixelMap->GetWidth(), dragItemInfo.pixelMap->GetHeight());
1027     dragWindow_->SetOffset(rect.Left(), rect.Top());
1028     dragWindow_->DrawPixelMap(dragItemInfo.pixelMap);
1029     if (isW3cDragEvent_ && delegate_) {
1030         auto viewScale = pipelineContext->GetViewScale();
1031         int32_t localX = static_cast<int32_t>(globalX - GetCoordinatePoint().GetX());
1032         int32_t localY = static_cast<int32_t>(globalY - GetCoordinatePoint().GetY());
1033         delegate_->HandleDragEvent(localX * viewScale, localY * viewScale, DragAction::DRAG_ENTER);
1034     }
1035 }
1036 
PanOnActionStart(const GestureEvent & info)1037 void RenderWeb::PanOnActionStart(const GestureEvent& info)
1038 {
1039     auto pipelineContext = context_.Upgrade();
1040     if (!pipelineContext) {
1041         return;
1042     }
1043 
1044     isDragging_ = true;
1045     GestureEvent newInfo = info;
1046     newInfo.SetGlobalPoint(startPoint_);
1047     auto dragItemInfo = GenerateDragItemInfo(pipelineContext, newInfo);
1048 #if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM)
1049     if (dragItemInfo.pixelMap) {
1050         auto initRenderNode = AceType::Claim(this);
1051         isDragDropNode_  = true;
1052         pipelineContext->SetInitRenderNode(initRenderNode);
1053         AddDataToClipboard(pipelineContext, dragItemInfo.extraInfo, "", "");
1054         if (!dragWindow_) {
1055             OnDragWindowStartEvent(pipelineContext, info, dragItemInfo);
1056         }
1057         return;
1058     }
1059 #endif
1060     if (!dragItemInfo.customComponent) {
1061         isDragging_ = false;
1062         return;
1063     }
1064 
1065     hasDragItem_ = true;
1066     auto positionedComponent = AceType::MakeRefPtr<PositionedComponent>(dragItemInfo.customComponent);
1067     positionedComponent->SetTop(Dimension(GetGlobalOffset().GetY()));
1068     positionedComponent->SetLeft(Dimension(GetGlobalOffset().GetX()));
1069     SetLocalPoint(info.GetGlobalPoint() - GetGlobalOffset());
1070     auto updatePosition = [renderBox = AceType::Claim(this)](
1071                                 const std::function<void(const Dimension&, const Dimension&)>& func) {
1072         if (!renderBox) {
1073             return;
1074         }
1075         renderBox->SetUpdateBuilderFuncId(func);
1076     };
1077     positionedComponent->SetUpdatePositionFuncId(updatePosition);
1078     auto stackElement = pipelineContext->GetLastStack();
1079     stackElement->PushComponent(positionedComponent);
1080 }
1081 
OnDragWindowMoveEvent(RefPtr<PipelineContext> pipelineContext,const GestureEvent & info)1082 void RenderWeb::OnDragWindowMoveEvent(RefPtr<PipelineContext> pipelineContext, const GestureEvent& info)
1083 {
1084     int32_t globalX = static_cast<int32_t>(info.GetGlobalPoint().GetX());
1085     int32_t globalY = static_cast<int32_t>(info.GetGlobalPoint().GetY());
1086     dragWindow_->MoveTo(globalX, globalY);
1087     if (isW3cDragEvent_ && delegate_) {
1088         auto viewScale = pipelineContext->GetViewScale();
1089         int32_t localX = static_cast<int32_t>(globalX - GetCoordinatePoint().GetX());
1090         int32_t localY = static_cast<int32_t>(globalY - GetCoordinatePoint().GetY());
1091         delegate_->HandleDragEvent(localX * viewScale, localY * viewScale, DragAction::DRAG_OVER);
1092     }
1093 }
1094 
PanOnActionUpdate(const GestureEvent & info)1095 void RenderWeb::PanOnActionUpdate(const GestureEvent& info)
1096 {
1097     auto pipelineContext = context_.Upgrade();
1098     if (!pipelineContext) {
1099         return;
1100     }
1101 
1102 #if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM)
1103     if (isDragDropNode_  && dragWindow_) {
1104         OnDragWindowMoveEvent(pipelineContext, info);
1105         return;
1106     }
1107 #endif
1108 
1109     RefPtr<DragEvent> event = AceType::MakeRefPtr<DragEvent>();
1110     event->SetX(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
1111     event->SetY(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
1112 
1113     Offset offset = info.GetGlobalPoint() - GetLocalPoint();
1114     if (GetUpdateBuilderFuncId()) {
1115         GetUpdateBuilderFuncId()(Dimension(offset.GetX()), Dimension(offset.GetY()));
1116     }
1117 
1118     auto extraParams = JsonUtil::Create(true);
1119     auto targetDragDropNode = FindDragDropNode(pipelineContext, info);
1120     auto preDragDropNode = GetPreDragDropNode();
1121     if (preDragDropNode == targetDragDropNode) {
1122         if (targetDragDropNode && targetDragDropNode->GetOnDragMove()) {
1123             (targetDragDropNode->GetOnDragMove())(event, extraParams->ToString());
1124         }
1125         return;
1126     }
1127     if (preDragDropNode && preDragDropNode->GetOnDragLeave()) {
1128         (preDragDropNode->GetOnDragLeave())(event, extraParams->ToString());
1129     }
1130     if (targetDragDropNode && targetDragDropNode->GetOnDragEnter()) {
1131         (targetDragDropNode->GetOnDragEnter())(event, extraParams->ToString());
1132     }
1133     SetPreDragDropNode(targetDragDropNode);
1134 }
1135 
OnDragWindowDropEvent(RefPtr<PipelineContext> pipelineContext,const GestureEvent & info)1136 void RenderWeb::OnDragWindowDropEvent(RefPtr<PipelineContext> pipelineContext, const GestureEvent& info)
1137 {
1138     if (GetOnDrop()) {
1139         RefPtr<DragEvent> event = AceType::MakeRefPtr<DragEvent>();
1140         RefPtr<PasteData> pasteData = AceType::MakeRefPtr<PasteData>();
1141         event->SetPasteData(pasteData);
1142         event->SetX(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
1143         event->SetY(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
1144 
1145         auto extraParams = JsonUtil::Create(true);
1146         (GetOnDrop())(event, extraParams->ToString());
1147         pipelineContext->SetInitRenderNode(nullptr);
1148     }
1149 
1150     if (isW3cDragEvent_ && delegate_) {
1151         auto viewScale = pipelineContext->GetViewScale();
1152         int32_t localX = static_cast<int32_t>(info.GetGlobalPoint().GetX() - GetCoordinatePoint().GetX());
1153         int32_t localY = static_cast<int32_t>(info.GetGlobalPoint().GetY() - GetCoordinatePoint().GetY());
1154         delegate_->HandleDragEvent(localX * viewScale, localY * viewScale, DragAction::DRAG_DROP);
1155         delegate_->HandleDragEvent(localX * viewScale, localY * viewScale, DragAction::DRAG_END);
1156     }
1157 }
1158 
PanOnActionEnd(const GestureEvent & info)1159 void RenderWeb::PanOnActionEnd(const GestureEvent& info)
1160 {
1161     isDragging_ = false;
1162     auto pipelineContext = context_.Upgrade();
1163     if (!pipelineContext) {
1164         return;
1165     }
1166 #if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM)
1167     if (isDragDropNode_) {
1168         isDragDropNode_  = false;
1169         RestoreCilpboardData(pipelineContext);
1170         OnDragWindowDropEvent(pipelineContext, info);
1171     }
1172 
1173     if (dragWindow_) {
1174         dragWindow_->Destroy();
1175         dragWindow_ = nullptr;
1176         return;
1177     }
1178 #endif
1179 
1180     RefPtr<DragEvent> event = AceType::MakeRefPtr<DragEvent>();
1181     RefPtr<PasteData> pasteData = AceType::MakeRefPtr<PasteData>();
1182     event->SetPasteData(pasteData);
1183     event->SetX(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
1184     event->SetY(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
1185 
1186     Offset offset = info.GetGlobalPoint() - GetLocalPoint();
1187     if (GetUpdateBuilderFuncId()) {
1188         GetUpdateBuilderFuncId()(Dimension(offset.GetX()), Dimension(offset.GetY()));
1189     }
1190     if (hasDragItem_) {
1191         auto stackElement = pipelineContext->GetLastStack();
1192         stackElement->PopComponent();
1193     }
1194     hasDragItem_ = false;
1195 
1196     ACE_DCHECK(GetPreDragDropNode() == FindTargetRenderNode<DragDropEvent>(pipelineContext, info));
1197     auto targetDragDropNode = GetPreDragDropNode();
1198     if (!targetDragDropNode) {
1199         return;
1200     }
1201     if (targetDragDropNode->GetOnDrop()) {
1202         auto extraParams = JsonUtil::Create(true);
1203         (targetDragDropNode->GetOnDrop())(event, extraParams->ToString());
1204     }
1205     SetPreDragDropNode(nullptr);
1206 }
1207 
PanOnActionCancel()1208 void RenderWeb::PanOnActionCancel()
1209 {
1210     isDragging_ = false;
1211     auto pipelineContext = context_.Upgrade();
1212     if (!pipelineContext) {
1213         return;
1214     }
1215 
1216 #if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM)
1217     if (isDragDropNode_) {
1218         RestoreCilpboardData(pipelineContext);
1219         isDragDropNode_ = false;
1220         if (isW3cDragEvent_ && delegate_) {
1221             delegate_->HandleDragEvent(0, 0, DragAction::DRAG_CANCEL);
1222         }
1223     }
1224 
1225     if (dragWindow_) {
1226         dragWindow_->Destroy();
1227         dragWindow_ = nullptr;
1228     }
1229 #endif
1230 
1231     if (hasDragItem_) {
1232         auto stackElement = pipelineContext->GetLastStack();
1233         stackElement->PopComponent();
1234         hasDragItem_ = false;
1235     }
1236     SetPreDragDropNode(nullptr);
1237 }
1238 
UpdateGlobalPos()1239 void RenderWeb::UpdateGlobalPos()
1240 {
1241     auto position = GetGlobalOffset();
1242     if (delegate_) {
1243         delegate_->SetWebRendeGlobalPos(position);
1244     }
1245 }
1246 
BuildSelectMenu(const std::string & value)1247 RefPtr<OptionComponent> RenderWeb::BuildSelectMenu(const std::string& value)
1248 {
1249     auto context = context_.Upgrade();
1250     if (!context) {
1251         return nullptr;
1252     }
1253     if (!themeManager_) {
1254         themeManager_ = context->GetThemeManager();
1255     }
1256     if (!accessibilityManager_) {
1257         accessibilityManager_ = context->GetAccessibilityManager();
1258     }
1259     auto optionComponent = AceType::MakeRefPtr<OptionComponent>();
1260     if (!optionComponent) {
1261         return nullptr;
1262     }
1263     optionComponent->SetNeedDrawDividerLine(false);
1264     auto textComponent = AceType::MakeRefPtr<TextComponent>(value);
1265     optionComponent->SetText(textComponent);
1266     optionComponent->SetValue(value);
1267     optionComponent->InitTheme(themeManager_);
1268     optionComponent->Initialize(accessibilityManager_);
1269     return optionComponent;
1270 }
1271 
OnSelectPopupMenu(std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuParam> params,std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuCallback> callback)1272 void RenderWeb::OnSelectPopupMenu(
1273     std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuParam> params,
1274     std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuCallback> callback)
1275 {
1276     auto context = context_.Upgrade();
1277     if (!context || !params || !callback) {
1278         return;
1279     }
1280     const auto pipeline = context_.Upgrade();
1281     if (!pipeline) {
1282         return;
1283     }
1284     auto stackElement = pipeline->GetLastStack();
1285     if (!stackElement) {
1286         return;
1287     }
1288     popup_ = AceType::MakeRefPtr<SelectPopupComponent>();
1289     auto themeManager = context->GetThemeManager();
1290     popup_->InitTheme(themeManager);
1291     for (size_t index = 0; index < params->menuItems.size(); index++) {
1292         RefPtr<OptionComponent> option = BuildSelectMenu(params->menuItems[index].label);
1293         if (!option) {
1294             continue;
1295         }
1296         popup_->AppendSelectOption(option);
1297         if (index == params->selectedItem) {
1298             option->SetSelected(true);
1299         }
1300     }
1301     popup_->SetOptionClickedCallback([callback](std::size_t index) {
1302         std::vector<int32_t> indices { static_cast<int32_t>(index) };
1303         callback->Continue(indices);
1304     });
1305     popup_->SetPopupCanceledCallback([callback]() {
1306         callback->Cancel();
1307     });
1308 
1309     Offset leftTop = { params->bounds.x + GetGlobalOffset().GetX(),
1310                        params->bounds.y + GetGlobalOffset().GetY() };
1311     Offset rightBottom = { params->bounds.x + GetGlobalOffset().GetX() + params->bounds.width,
1312                            params->bounds.y + GetGlobalOffset().GetY() + params->bounds.height };
1313     popup_->ShowDialog(stackElement, leftTop, rightBottom, false);
1314 }
1315 #endif
1316 } // namespace OHOS::Ace
1317