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