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