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