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