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