• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2024 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_ng/pattern/web/web_pattern.h"
17 
18 #include <securec.h>
19 #include <algorithm>
20 #include <vector>
21 
22 #include "file_uri.h"
23 #include "image_source.h"
24 #include "input_method_controller.h"
25 #include "parameters.h"
26 
27 #if !defined(PREVIEW) && !defined(ACE_UNITTEST)
28 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
29 #endif
30 
31 #include "auto_fill_type.h"
32 #include "page_node_info.h"
33 
34 #include "adapter/ohos/capability/html/span_to_html.h"
35 #include "base/geometry/ng/offset_t.h"
36 #include "base/geometry/rect.h"
37 #include "base/image/file_uri_helper.h"
38 #include "base/mousestyle/mouse_style.h"
39 #include "base/utils/date_util.h"
40 #include "base/utils/linear_map.h"
41 #include "base/utils/time_util.h"
42 #include "base/utils/utils.h"
43 #include "core/common/ace_engine_ext.h"
44 #include "core/common/ai/data_detector_mgr.h"
45 #include "core/common/ai/image_analyzer_manager.h"
46 #include "core/common/ime/input_method_manager.h"
47 #include "core/common/udmf/udmf_client.h"
48 #include "core/common/udmf/unified_data.h"
49 #include "core/common/vibrator/vibrator_utils.h"
50 #include "core/components/dialog/dialog_theme.h"
51 #include "core/components/picker/picker_data.h"
52 #include "core/components/text_overlay/text_overlay_theme.h"
53 #include "core/components/web/resource/web_delegate.h"
54 #include "core/components/web/web_property.h"
55 #include "core/components_ng/base/view_stack_processor.h"
56 #include "core/components_ng/pattern/dialog/dialog_pattern.h"
57 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
58 #include "core/components_ng/pattern/list/list_pattern.h"
59 #include "core/components_ng/pattern/menu/menu_view.h"
60 #include "core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.h"
61 #include "core/components_ng/pattern/overlay/overlay_manager.h"
62 #include "core/components_ng/pattern/refresh/refresh_pattern.h"
63 #include "core/components_ng/pattern/select_overlay/select_overlay_pattern.h"
64 #include "core/components_ng/pattern/swiper/swiper_pattern.h"
65 #include "core/components_ng/pattern/text/text_pattern.h"
66 #include "core/components_ng/pattern/text_field/text_field_manager.h"
67 #include "core/components_ng/pattern/web/web_event_hub.h"
68 #include "core/event/key_event.h"
69 #include "core/event/touch_event.h"
70 #include "core/pipeline_ng/pipeline_context.h"
71 #include "frameworks/base/utils/system_properties.h"
72 #include "frameworks/core/components_ng/base/ui_node.h"
73 #include "display_manager.h"
74 
75 namespace OHOS::Ace::NG {
76 namespace {
77 const std::string IMAGE_POINTER_CONTEXT_MENU_PATH = "etc/webview/ohos_nweb/context-menu.svg";
78 const std::string IMAGE_POINTER_ALIAS_PATH = "etc/webview/ohos_nweb/alias.svg";
79 const std::string WEB_INFO_PC = "8";
80 const std::string WEB_INFO_TABLET = "4";
81 const std::string WEB_INFO_PHONE = "2";
82 const std::string WEB_INFO_DEFAULT = "1";
83 const std::string AUTO_FILL_VIEW_DATA_PAGE_URL = "autofill_viewdata_origin_pageurl";
84 const std::string AUTO_FILL_VIEW_DATA_OTHER_ACCOUNT = "autofill_viewdata_other_account";
85 constexpr int32_t AUTOFILL_DELAY_TIME = 200;
86 constexpr int32_t TOUCH_EVENT_MAX_SIZE = 5;
87 constexpr int32_t IMAGE_POINTER_CUSTOM_CHANNEL = 4;
88 constexpr int32_t KEYEVENT_MAX_NUM = 1000;
89 constexpr float SELECT_MENE_HEIGHT = 140.0f;
90 constexpr int32_t RESERVED_DEVICEID = 0xAAAAAAFF;
91 const LinearEnumMapNode<OHOS::NWeb::CursorType, MouseFormat> g_cursorTypeMap[] = {
92     { OHOS::NWeb::CursorType::CT_CROSS, MouseFormat::CROSS },
93     { OHOS::NWeb::CursorType::CT_HAND, MouseFormat::HAND_POINTING },
94     { OHOS::NWeb::CursorType::CT_IBEAM, MouseFormat::TEXT_CURSOR },
95     { OHOS::NWeb::CursorType::CT_WAIT, MouseFormat::LOADING },
96     { OHOS::NWeb::CursorType::CT_HELP, MouseFormat::HELP },
97     { OHOS::NWeb::CursorType::CT_EASTRESIZE, MouseFormat::WEST_EAST },
98     { OHOS::NWeb::CursorType::CT_NORTHRESIZE, MouseFormat::NORTH_SOUTH },
99     { OHOS::NWeb::CursorType::CT_NORTHEASTRESIZE, MouseFormat::NORTH_EAST_SOUTH_WEST },
100     { OHOS::NWeb::CursorType::CT_NORTHWESTRESIZE, MouseFormat::NORTH_WEST_SOUTH_EAST },
101     { OHOS::NWeb::CursorType::CT_SOUTHRESIZE, MouseFormat::NORTH_SOUTH },
102     { OHOS::NWeb::CursorType::CT_SOUTHEASTRESIZE, MouseFormat::NORTH_WEST_SOUTH_EAST },
103     { OHOS::NWeb::CursorType::CT_SOUTHWESTRESIZE, MouseFormat::NORTH_EAST_SOUTH_WEST },
104     { OHOS::NWeb::CursorType::CT_WESTRESIZE, MouseFormat::WEST_EAST },
105     { OHOS::NWeb::CursorType::CT_NORTHSOUTHRESIZE, MouseFormat::NORTH_SOUTH },
106     { OHOS::NWeb::CursorType::CT_EASTWESTRESIZE, MouseFormat::WEST_EAST },
107     { OHOS::NWeb::CursorType::CT_NORTHEASTSOUTHWESTRESIZE, MouseFormat::NORTH_EAST_SOUTH_WEST },
108     { OHOS::NWeb::CursorType::CT_NORTHWESTSOUTHEASTRESIZE, MouseFormat::NORTH_WEST_SOUTH_EAST },
109     { OHOS::NWeb::CursorType::CT_COLUMNRESIZE, MouseFormat::RESIZE_LEFT_RIGHT },
110     { OHOS::NWeb::CursorType::CT_ROWRESIZE, MouseFormat::RESIZE_UP_DOWN },
111     { OHOS::NWeb::CursorType::CT_MIDDLEPANNING, MouseFormat::MIDDLE_BTN_NORTH_SOUTH_WEST_EAST },
112     { OHOS::NWeb::CursorType::CT_EASTPANNING, MouseFormat::MIDDLE_BTN_EAST },
113     { OHOS::NWeb::CursorType::CT_NORTHPANNING, MouseFormat::MIDDLE_BTN_NORTH },
114     { OHOS::NWeb::CursorType::CT_NORTHEASTPANNING, MouseFormat::MIDDLE_BTN_NORTH_EAST },
115     { OHOS::NWeb::CursorType::CT_NORTHWESTPANNING, MouseFormat::MIDDLE_BTN_NORTH_WEST },
116     { OHOS::NWeb::CursorType::CT_SOUTHPANNING, MouseFormat::MIDDLE_BTN_SOUTH },
117     { OHOS::NWeb::CursorType::CT_SOUTHEASTPANNING, MouseFormat::MIDDLE_BTN_SOUTH_EAST },
118     { OHOS::NWeb::CursorType::CT_SOUTHWESTPANNING, MouseFormat::MIDDLE_BTN_SOUTH_WEST },
119     { OHOS::NWeb::CursorType::CT_WESTPANNING, MouseFormat::MIDDLE_BTN_WEST },
120     { OHOS::NWeb::CursorType::CT_MOVE, MouseFormat::CURSOR_MOVE },
121     { OHOS::NWeb::CursorType::CT_VERTICALTEXT, MouseFormat::HORIZONTAL_TEXT_CURSOR },
122     { OHOS::NWeb::CursorType::CT_CELL, MouseFormat::CURSOR_CROSS },
123     { OHOS::NWeb::CursorType::CT_PROGRESS, MouseFormat::RUNNING },
124     { OHOS::NWeb::CursorType::CT_NODROP, MouseFormat::CURSOR_FORBID },
125     { OHOS::NWeb::CursorType::CT_COPY, MouseFormat::CURSOR_COPY },
126     { OHOS::NWeb::CursorType::CT_NONE, MouseFormat::CURSOR_NONE },
127     { OHOS::NWeb::CursorType::CT_NOTALLOWED, MouseFormat::CURSOR_FORBID },
128     { OHOS::NWeb::CursorType::CT_ZOOMIN, MouseFormat::ZOOM_IN },
129     { OHOS::NWeb::CursorType::CT_ZOOMOUT, MouseFormat::ZOOM_OUT },
130     { OHOS::NWeb::CursorType::CT_GRAB, MouseFormat::HAND_OPEN },
131     { OHOS::NWeb::CursorType::CT_GRABBING, MouseFormat::HAND_GRABBING },
132     { OHOS::NWeb::CursorType::CT_MIDDLE_PANNING_VERTICAL, MouseFormat::MIDDLE_BTN_NORTH_SOUTH },
133     { OHOS::NWeb::CursorType::CT_MIDDLE_PANNING_HORIZONTAL, MouseFormat::MIDDLE_BTN_NORTH_SOUTH_WEST_EAST },
134 };
135 
136 constexpr Dimension OPTION_MARGIN = 8.0_vp;
137 constexpr Dimension CALIBERATE_X = 4.0_vp;
138 constexpr Color SELECTED_OPTION_FONT_COLOR = Color(0xff0a59f7);
139 constexpr Color SELECTED_OPTION_BACKGROUND_COLOR = Color(0x19254FF7);
140 
141 constexpr Dimension SELECT_HANDLE_DEFAULT_HEIGHT = 16.0_vp;
142 constexpr int32_t HALF = 2;
143 constexpr int32_t AI_TIMEOUT_LIMIT = 200;
144 
ParseDateTimeJson(const std::string & timeJson,NWeb::DateTime & result)145 bool ParseDateTimeJson(const std::string& timeJson, NWeb::DateTime& result)
146 {
147     auto sourceJson = JsonUtil::ParseJsonString(timeJson);
148     if (!sourceJson || sourceJson->IsNull()) {
149         return false;
150     }
151 
152     auto year = sourceJson->GetValue("year");
153     if (year && year->IsNumber()) {
154         result.year = year->GetInt();
155     }
156     auto month = sourceJson->GetValue("month");
157     if (month && month->IsNumber()) {
158         result.month = month->GetInt();
159     }
160     auto day = sourceJson->GetValue("day");
161     if (day && day->IsNumber()) {
162         result.day = day->GetInt();
163     }
164     auto hour = sourceJson->GetValue("hour");
165     if (hour && hour->IsNumber()) {
166         result.hour = hour->GetInt();
167     }
168     auto minute = sourceJson->GetValue("minute");
169     if (minute && minute->IsNumber()) {
170         result.minute = minute->GetInt();
171     }
172     return true;
173 }
174 
ParseTextJsonValue(const std::string & textJson)175 std::string ParseTextJsonValue(const std::string& textJson)
176 {
177     auto sourceJson = JsonUtil::ParseJsonString(textJson);
178     if (!sourceJson || sourceJson->IsNull()) {
179         return "";
180     }
181     auto value = sourceJson->GetValue("value");
182     if (value && value->IsString()) {
183         return value->GetString();
184     }
185     return "";
186 }
187 
188 const std::map<std::string, AceAutoFillType> NWEB_AUTOFILL_TYPE_TO_ACE = {
189     {OHOS::NWeb::NWEB_AUTOFILL_STREET_ADDRESS, AceAutoFillType::ACE_FULL_STREET_ADDRESS},
190     {OHOS::NWeb::NWEB_AUTOFILL_ADDRESS_LEVEL_3, AceAutoFillType::ACE_DISTRICT_ADDRESS},
191     {OHOS::NWeb::NWEB_AUTOFILL_ADDRESS_LEVEL_2, AceAutoFillType::ACE_CITY_ADDRESS},
192     {OHOS::NWeb::NWEB_AUTOFILL_ADDRESS_LEVEL_1, AceAutoFillType::ACE_PROVINCE_ADDRESS},
193     {OHOS::NWeb::NWEB_AUTOFILL_COUNTRY, AceAutoFillType::ACE_COUNTRY_ADDRESS},
194     {OHOS::NWeb::NWEB_AUTOFILL_NAME, AceAutoFillType::ACE_PERSON_FULL_NAME},
195     {OHOS::NWeb::NWEB_AUTOFILL_FAMILY_NAME, AceAutoFillType::ACE_PERSON_LAST_NAME},
196     {OHOS::NWeb::NWEB_AUTOFILL_GIVEN_NAME, AceAutoFillType::ACE_PERSON_FIRST_NAME},
197     {OHOS::NWeb::NWEB_AUTOFILL_TEL_NATIONAL, AceAutoFillType::ACE_PHONE_NUMBER},
198     {OHOS::NWeb::NWEB_AUTOFILL_TEL, AceAutoFillType::ACE_FULL_PHONE_NUMBER},
199     {OHOS::NWeb::NWEB_AUTOFILL_TEL_COUNTRY_CODE, AceAutoFillType::ACE_PHONE_COUNTRY_CODE},
200     {OHOS::NWeb::NWEB_AUTOFILL_EMAIL, AceAutoFillType::ACE_EMAIL_ADDRESS},
201     {OHOS::NWeb::NWEB_AUTOFILL_CC_NUMBER, AceAutoFillType::ACE_BANK_CARD_NUMBER},
202     {OHOS::NWeb::NWEB_AUTOFILL_ID_CARD_NUMBER, AceAutoFillType::ACE_ID_CARD_NUMBER},
203     {OHOS::NWeb::NWEB_AUTOFILL_DETAIL_INFO_WITHOUT_STREET, AceAutoFillType::ACE_DETAIL_INFO_WITHOUT_STREET},
204     {OHOS::NWeb::NWEB_AUTOFILL_FORMAT_ADDRESS, AceAutoFillType::ACE_FORMAT_ADDRESS},
205     {OHOS::NWeb::NWEB_AUTOFILL_NICKNAME, AceAutoFillType::ACE_NICKNAME},
206     {OHOS::NWeb::NWEB_AUTOFILL_USERNAME, AceAutoFillType::ACE_USER_NAME},
207     {OHOS::NWeb::NWEB_AUTOFILL_PASSWORD, AceAutoFillType::ACE_PASSWORD},
208     {OHOS::NWeb::NWEB_AUTOFILL_NEW_PASSWORD, AceAutoFillType::ACE_NEW_PASSWORD},
209 };
210 
211 const std::map<AceAutoFillType, std::string> ACE_AUTOFILL_TYPE_TO_NWEB = {
212     {AceAutoFillType::ACE_FULL_STREET_ADDRESS, OHOS::NWeb::NWEB_AUTOFILL_STREET_ADDRESS},
213     {AceAutoFillType::ACE_DISTRICT_ADDRESS, OHOS::NWeb::NWEB_AUTOFILL_ADDRESS_LEVEL_3},
214     {AceAutoFillType::ACE_CITY_ADDRESS, OHOS::NWeb::NWEB_AUTOFILL_ADDRESS_LEVEL_2},
215     {AceAutoFillType::ACE_PROVINCE_ADDRESS, OHOS::NWeb::NWEB_AUTOFILL_ADDRESS_LEVEL_1},
216     {AceAutoFillType::ACE_COUNTRY_ADDRESS, OHOS::NWeb::NWEB_AUTOFILL_COUNTRY},
217     {AceAutoFillType::ACE_PERSON_FULL_NAME, OHOS::NWeb::NWEB_AUTOFILL_NAME},
218     {AceAutoFillType::ACE_PERSON_LAST_NAME, OHOS::NWeb::NWEB_AUTOFILL_FAMILY_NAME},
219     {AceAutoFillType::ACE_PERSON_FIRST_NAME, OHOS::NWeb::NWEB_AUTOFILL_GIVEN_NAME},
220     {AceAutoFillType::ACE_PHONE_NUMBER, OHOS::NWeb::NWEB_AUTOFILL_TEL_NATIONAL},
221     {AceAutoFillType::ACE_FULL_PHONE_NUMBER, OHOS::NWeb::NWEB_AUTOFILL_TEL},
222     {AceAutoFillType::ACE_PHONE_COUNTRY_CODE, OHOS::NWeb::NWEB_AUTOFILL_TEL_COUNTRY_CODE},
223     {AceAutoFillType::ACE_EMAIL_ADDRESS, OHOS::NWeb::NWEB_AUTOFILL_EMAIL},
224     {AceAutoFillType::ACE_BANK_CARD_NUMBER, OHOS::NWeb::NWEB_AUTOFILL_CC_NUMBER},
225     {AceAutoFillType::ACE_ID_CARD_NUMBER, OHOS::NWeb::NWEB_AUTOFILL_ID_CARD_NUMBER},
226     {AceAutoFillType::ACE_DETAIL_INFO_WITHOUT_STREET, OHOS::NWeb::NWEB_AUTOFILL_DETAIL_INFO_WITHOUT_STREET},
227     {AceAutoFillType::ACE_FORMAT_ADDRESS, OHOS::NWeb::NWEB_AUTOFILL_FORMAT_ADDRESS},
228     {AceAutoFillType::ACE_NICKNAME, OHOS::NWeb::NWEB_AUTOFILL_NICKNAME},
229     {AceAutoFillType::ACE_USER_NAME, OHOS::NWeb::NWEB_AUTOFILL_USERNAME},
230     {AceAutoFillType::ACE_PASSWORD, OHOS::NWeb::NWEB_AUTOFILL_PASSWORD},
231     {AceAutoFillType::ACE_NEW_PASSWORD, OHOS::NWeb::NWEB_AUTOFILL_NEW_PASSWORD},
232 };
233 
234 const std::map<std::string, OHOS::NWeb::NWebAutofillEvent> NWEB_AUTOFILL_EVENTS = {
235     {OHOS::NWeb::NWEB_AUTOFILL_EVENT_SAVE, OHOS::NWeb::NWebAutofillEvent::SAVE},
236     {OHOS::NWeb::NWEB_AUTOFILL_EVENT_FILL, OHOS::NWeb::NWebAutofillEvent::FILL},
237     {OHOS::NWeb::NWEB_AUTOFILL_EVENT_UPDATE, OHOS::NWeb::NWebAutofillEvent::UPDATE},
238     {OHOS::NWeb::NWEB_AUTOFILL_EVENT_CLOSE, OHOS::NWeb::NWebAutofillEvent::CLOSE},
239 };
240 } // namespace
241 
242 constexpr int32_t SINGLE_CLICK_NUM = 1;
243 constexpr int32_t DOUBLE_CLICK_NUM = 2;
244 constexpr double DEFAULT_DBCLICK_INTERVAL = 0.5;
245 constexpr double DEFAULT_DBCLICK_OFFSET = 2.0;
246 constexpr double DEFAULT_AXIS_RATIO = -0.06;
247 constexpr double DEFAULT_WEB_WIDTH = 100.0;
248 constexpr double DEFAULT_WEB_HEIGHT = 80.0;
249 constexpr Dimension TOOLTIP_BORDER_WIDTH = 1.0_vp;
250 constexpr Dimension TOOLTIP_FONT_SIZE = 14.0_vp;
251 constexpr Dimension TOOLTIP_PADDING = 8.0_vp;
252 constexpr float TOOLTIP_MAX_PORTION = 0.35f;
253 constexpr float TOOLTIP_MARGIN = 10.0f;
254 constexpr float TOOLTIP_DELAY_MS = 1000;
255 constexpr uint32_t ADJUST_WEB_DRAW_LENGTH = 3000;
256 constexpr int32_t FIT_CONTENT_LIMIT_LENGTH = 8000;
257 const std::string PATTERN_TYPE_WEB = "WEBPATTERN";
258 const std::string DEFAULT_WEB_TEXT_ENCODING_FORMAT = "UTF-8";
259 constexpr int32_t SYNC_SURFACE_QUEUE_SIZE = 8;
260 constexpr int32_t ASYNC_SURFACE_QUEUE_SIZE_FOR_PHONE = 5;
261 constexpr int32_t ASYNC_SURFACE_QUEUE_SIZE_FOR_OTHERS = 4;
262 constexpr uint32_t DEBUG_DRAGMOVEID_TIMER = 30;
263 // web feature params
264 constexpr char VISIBLE_ACTIVE_ENABLE[] = "persist.web.visible_active_enable";
265 constexpr char MEMORY_LEVEL_ENABEL[] = "persist.web.memory_level_enable";
266 const std::vector<std::string> SYNC_RENDER_SLIDE {V2::LIST_ETS_TAG, V2::SCROLL_ETS_TAG};
267 
268 constexpr int32_t DEFAULT_PINCH_FINGER = 2;
269 constexpr double DEFAULT_PINCH_DISTANCE = 5.0;
270 constexpr double DEFAULT_PINCH_SCALE = 1.0;
271 constexpr double DEFAULT_PINCH_SCALE_MAX = 5.0;
272 constexpr double DEFAULT_PINCH_SCALE_MIN = 0.32;
273 constexpr int32_t PINCH_INDEX_ONE = 1;
274 constexpr int32_t STATUS_ZOOMIN = 1;
275 constexpr int32_t STATUS_ZOOMOUT = 2;
276 constexpr int32_t ZOOM_ERROR_COUNT_MAX = 5;
277 constexpr double ZOOMIN_SMOOTH_SCALE = 0.99;
278 constexpr int32_t POPUP_CALCULATE_RATIO = 2;
279 
280 constexpr char ACCESSIBILITY_GENERIC_CONTAINER[] = "genericContainer";
281 constexpr char ACCESSIBILITY_IMAGE[] = "image";
282 constexpr char ACCESSIBILITY_PARAGRAPH[] = "paragraph";
283 constexpr char WEB_NODE_URL[] = "url";
284 
285 const std::string IS_HINT_TYPE = "{\"isHint2Type\": true}";
286 const std::string STRING_LF = "\n";
287 
288 #define WEB_ACCESSIBILITY_DELAY_TIME 100
289 
290 class WebAccessibilityChildTreeCallback : public AccessibilityChildTreeCallback {
291 public:
WebAccessibilityChildTreeCallback(const WeakPtr<WebPattern> & weakPattern,int64_t accessibilityId)292     WebAccessibilityChildTreeCallback(const WeakPtr<WebPattern> &weakPattern, int64_t accessibilityId)
293         : AccessibilityChildTreeCallback(accessibilityId), weakPattern_(weakPattern)
294     {}
295 
296     ~WebAccessibilityChildTreeCallback() override = default;
297 
OnRegister(uint32_t windowId,int32_t treeId)298     bool OnRegister(uint32_t windowId, int32_t treeId) override
299     {
300         auto pattern = weakPattern_.Upgrade();
301         if (pattern == nullptr) {
302             return false;
303         }
304         if (isReg_) {
305             return true;
306         }
307         if (!pattern->OnAccessibilityChildTreeRegister()) {
308             return false;
309         }
310         pattern->SetAccessibilityState(true);
311         isReg_ = true;
312         return true;
313     }
314 
OnDeregister()315     bool OnDeregister() override
316     {
317         auto pattern = weakPattern_.Upgrade();
318         if (pattern == nullptr) {
319             return false;
320         }
321         if (!isReg_) {
322             return true;
323         }
324         if (!pattern->OnAccessibilityChildTreeDeregister()) {
325             return false;
326         }
327         pattern->SetAccessibilityState(false);
328         isReg_ = false;
329         return true;
330     }
331 
OnSetChildTree(int32_t childWindowId,int32_t childTreeId)332     bool OnSetChildTree(int32_t childWindowId, int32_t childTreeId) override
333     {
334         auto pattern = weakPattern_.Upgrade();
335         if (pattern == nullptr) {
336             return false;
337         }
338         pattern->OnSetAccessibilityChildTree(childWindowId, childTreeId);
339         return true;
340     }
341 
OnDumpChildInfo(const std::vector<std::string> & params,std::vector<std::string> & info)342     bool OnDumpChildInfo(const std::vector<std::string>& params, std::vector<std::string>& info) override
343     {
344         return false;
345     }
346 
OnClearRegisterFlag()347     void OnClearRegisterFlag() override
348     {
349         auto pattern = weakPattern_.Upgrade();
350         if (pattern == nullptr) {
351             return;
352         }
353         isReg_ = false;
354     }
355 
356 private:
357     bool isReg_ = false;
358     WeakPtr<WebPattern> weakPattern_;
359 };
360 
361 WebPattern::WebPattern() = default;
362 
WebPattern(const std::string & webSrc,const RefPtr<WebController> & webController,RenderMode renderMode,bool incognitoMode,const std::string & sharedRenderProcessToken)363 WebPattern::WebPattern(const std::string& webSrc, const RefPtr<WebController>& webController, RenderMode renderMode,
364     bool incognitoMode, const std::string& sharedRenderProcessToken)
365     : webSrc_(std::move(webSrc)), webController_(webController), renderMode_(renderMode), incognitoMode_(incognitoMode),
366       sharedRenderProcessToken_(sharedRenderProcessToken)
367 {}
368 
WebPattern(const std::string & webSrc,const SetWebIdCallback & setWebIdCallback,RenderMode renderMode,bool incognitoMode,const std::string & sharedRenderProcessToken)369 WebPattern::WebPattern(const std::string& webSrc, const SetWebIdCallback& setWebIdCallback, RenderMode renderMode,
370     bool incognitoMode, const std::string& sharedRenderProcessToken)
371     : webSrc_(std::move(webSrc)), setWebIdCallback_(setWebIdCallback), renderMode_(renderMode),
372       incognitoMode_(incognitoMode), sharedRenderProcessToken_(sharedRenderProcessToken)
373 {}
374 
~WebPattern()375 WebPattern::~WebPattern()
376 {
377     TAG_LOGI(AceLogTag::ACE_WEB, "NWEB ~WebPattern start");
378     UninitTouchEventListener();
379     if (delegate_) {
380         TAG_LOGD(AceLogTag::ACE_WEB, "NWEB ~WebPattern delegate_ start SetAudioMuted");
381         delegate_->SetAudioMuted(true);
382     }
383 
384     if (observer_) {
385         TAG_LOGD(AceLogTag::ACE_WEB, "NWEB ~WebPattern observer_ start NotifyDestory");
386         observer_->NotifyDestory();
387     }
388     if (isActive_) {
389         TAG_LOGD(AceLogTag::ACE_WEB, "NWEB ~WebPattern isActive_ start OnInActive");
390         OnInActive();
391     }
392     if (imageAnalyzerManager_) {
393         imageAnalyzerManager_->ReleaseImageAnalyzer();
394     }
395     UninitializeAccessibility();
396     auto pipeline = PipelineBase::GetCurrentContextSafely();
397     if (pipeline) {
398         pipeline->UnregisterDensityChangedCallback(densityCallbackId_);
399     }
400 }
401 
ShowContextSelectOverlay(const RectF & firstHandle,const RectF & secondHandle,TextResponseType responseType,bool handleReverse)402 void WebPattern::ShowContextSelectOverlay(const RectF& firstHandle, const RectF& secondHandle,
403     TextResponseType responseType, bool handleReverse)
404 {
405     if (contextSelectOverlay_) {
406         contextSelectOverlay_->ProcessOverlay({ .animation = true });
407     }
408 }
409 
CloseContextSelectionMenu()410 void WebPattern::CloseContextSelectionMenu()
411 {
412     if (contextSelectOverlay_ && contextSelectOverlay_->IsCurrentMenuVisibile()) {
413         contextSelectOverlay_->CloseOverlay(true, CloseReason::CLOSE_REASON_NORMAL);
414     }
415 }
416 
RemovePreviewMenuNode()417 void WebPattern::RemovePreviewMenuNode()
418 {
419     if (!previewImageNodeId_.has_value()) {
420         return;
421     }
422     TAG_LOGI(AceLogTag::ACE_WEB, "RemovePreviewMenuNode");
423     curContextMenuResult_ = false;
424     auto previewNode =
425         FrameNode::GetFrameNode(V2::IMAGE_ETS_TAG, previewImageNodeId_.value());
426     CHECK_NULL_VOID(previewNode);
427     auto parent = previewNode->GetParent();
428     CHECK_NULL_VOID(parent);
429     parent->RemoveChild(previewNode);
430     previewImageNodeId_.reset();
431     parent->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
432 }
433 
IsPreviewMenuNotNeedShowPreview()434 bool WebPattern::IsPreviewMenuNotNeedShowPreview()
435 {
436     if (!previewImageNodeId_.has_value()) {
437         return false;
438     }
439     auto previewNode =
440         FrameNode::GetFrameNode(V2::IMAGE_ETS_TAG, previewImageNodeId_.value());
441     CHECK_NULL_RETURN(previewNode, false);
442     auto previewRenderContext = previewNode->GetRenderContext();
443     CHECK_NULL_RETURN(previewRenderContext, false);
444     auto previewGesture = previewNode->GetOrCreateGestureEventHub();
445     CHECK_NULL_RETURN(previewGesture, false);
446     bool isNotNeedShowPreview = previewGesture->GetBindMenuStatus().IsNotNeedShowPreview();
447     TAG_LOGI(AceLogTag::ACE_DRAG, "IsPreviewMenuNotNeedShowPreview:%{public}d", isNotNeedShowPreview);
448     return isNotNeedShowPreview;
449 }
450 
SetPreviewSelectionMenu(const std::shared_ptr<WebPreviewSelectionMenuParam> & param)451 void WebPattern::SetPreviewSelectionMenu(const std::shared_ptr<WebPreviewSelectionMenuParam>& param)
452 {
453     CHECK_NULL_VOID(param);
454     auto onPreviewMenuDisappear = [weak = AceType::WeakClaim(this),
455                                    onDisappear = std::move(param->menuParam.onDisappear)]() {
456         TAG_LOGD(AceLogTag::ACE_WEB, "onPreviewMenuDisappear");
457         if (onDisappear) {
458             onDisappear();
459         }
460         auto webPattern = weak.Upgrade();
461         CHECK_NULL_VOID(webPattern);
462         webPattern->RemovePreviewMenuNode();
463         CHECK_NULL_VOID(webPattern->contextMenuResult_);
464         webPattern->contextMenuResult_->Cancel();
465     };
466     param->menuParam.onDisappear = std::move(onPreviewMenuDisappear);
467     auto key = std::make_pair(param->type, param->responseType);
468     auto it = previewSelectionMenuMap_.find(key);
469     if (it != previewSelectionMenuMap_.end()) {
470         if (param->menuBuilder == nullptr) {
471             previewSelectionMenuMap_.erase(it);
472             return;
473         }
474         it->second = param;
475         return;
476     }
477     previewSelectionMenuMap_[key] = param;
478 }
479 
GetPreviewSelectionMenuParams(const WebElementType & type,const ResponseType & responseType)480 std::shared_ptr<WebPreviewSelectionMenuParam> WebPattern::GetPreviewSelectionMenuParams(
481     const WebElementType& type, const ResponseType& responseType)
482 {
483     auto key = std::make_pair(type, responseType);
484     auto it = previewSelectionMenuMap_.find(key);
485     if (it != previewSelectionMenuMap_.end()) {
486         return it->second;
487     }
488 
489     TAG_LOGD(AceLogTag::ACE_WEB, "The key not in previewSelectionMenuMap_");
490     return nullptr;
491 }
492 
GetPreviewImageOffsetAndSize(bool isImage,Offset & previewOffset,SizeF & previewSize)493 void WebPattern::GetPreviewImageOffsetAndSize(bool isImage, Offset& previewOffset, SizeF& previewSize)
494 {
495     if (isImage) {
496         CHECK_NULL_VOID(contextMenuParam_);
497         int32_t x = 0;
498         int32_t y = 0;
499         int32_t width = 0;
500         int32_t height = 0;
501         contextMenuParam_->GetImageRect(x, y, width, height);
502         previewOffset.SetX((float)x);
503         previewOffset.SetY((float)y);
504         previewSize.SetWidth((float)width);
505         previewSize.SetHeight((float)height);
506     } else {
507         previewSize.SetWidth(drawSize_.Width());
508         previewSize.SetHeight(drawSize_.Height());
509     }
510     auto host = GetHost();
511     CHECK_NULL_VOID(host);
512     auto pipeline = host->GetContextRefPtr();
513     CHECK_NULL_VOID(pipeline);
514     previewSize.SetWidth(previewSize.Width() / pipeline->GetDipScale());
515     previewSize.SetHeight(previewSize.Height() / pipeline->GetDipScale());
516 }
517 
CreatePreviewImageFrameNode(bool isImage)518 RefPtr<FrameNode> WebPattern::CreatePreviewImageFrameNode(bool isImage)
519 {
520     RemovePreviewMenuNode();
521     previewImageNodeId_ = ElementRegister::GetInstance()->MakeUniqueId();
522     auto previewNode = FrameNode::GetOrCreateFrameNode(
523         V2::IMAGE_ETS_TAG, previewImageNodeId_.value(), []() { return AceType::MakeRefPtr<ImagePattern>(); });
524     CHECK_NULL_RETURN(previewNode, nullptr);
525     auto previewRenderContext = previewNode->GetRenderContext();
526     CHECK_NULL_RETURN(previewRenderContext, nullptr);
527     auto previewGesture = previewNode->GetOrCreateGestureEventHub();
528     CHECK_NULL_RETURN(previewGesture, nullptr);
529 
530     previewNode->SetDraggable(false);
531     previewGesture->SetDragEvent(nullptr, { PanDirection::DOWN }, 0, Dimension(0));
532 
533     Offset previewOffset(0, 0);
534     SizeF previewSize;
535     GetPreviewImageOffsetAndSize(isImage, previewOffset, previewSize);
536     if (previewSize.Width() <= 0 || previewSize.Height() <= 0) {
537         TAG_LOGI(AceLogTag::ACE_WEB, "CreatePreviewImageFrameNode get preview size(%{public}f, %{public}f) error",
538             previewSize.Width(), previewSize.Height());
539         return nullptr;
540     }
541     previewRenderContext->UpdatePosition(
542         OffsetT<Dimension>(Dimension(previewOffset.GetX()), Dimension(previewOffset.GetY())));
543 
544     auto previewProperty = previewNode->GetLayoutProperty<ImageLayoutProperty>();
545     previewProperty->UpdateAutoResize(false);
546     previewProperty->UpdateMarginSelfIdealSize(previewSize);
547     MeasureProperty layoutConstraint;
548     CalcSize idealSize = { CalcLength(Dimension(previewSize.Width(), DimensionUnit::VP).ConvertToPx()),
549         CalcLength(Dimension(previewSize.Height(), DimensionUnit::VP).ConvertToPx()) };
550     layoutConstraint.selfIdealSize = idealSize;
551     layoutConstraint.maxSize = idealSize;
552     previewNode->UpdateLayoutConstraint(layoutConstraint);
553     TAG_LOGI(AceLogTag::ACE_WEB,
554         "CreatePreviewImageFrameNode offset:%{public}f, %{public}f; size:%{public}f, %{public}f",
555         previewOffset.GetX(), previewOffset.GetY(), previewSize.Width(), previewSize.Height());
556     needUpdateImagePreviewParam_ = true;
557     curContextMenuResult_ = true;
558     return previewNode;
559 }
560 
UpdateImagePreviewParam()561 void WebPattern::UpdateImagePreviewParam()
562 {
563     CHECK_NULL_VOID(needUpdateImagePreviewParam_);
564     needUpdateImagePreviewParam_ = false;
565     if (!previewImageNodeId_.has_value()) {
566         return;
567     }
568     TAG_LOGI(AceLogTag::ACE_WEB, "UpdateImagePreviewParam");
569     auto params = GetPreviewSelectionMenuParams(curElementType_, curResponseType_);
570     if (!params) {
571         RemovePreviewMenuNode();
572         return;
573     }
574 #ifndef ACE_UNITTEST
575     auto previewNode =
576         FrameNode::GetFrameNode(V2::IMAGE_ETS_TAG, previewImageNodeId_.value());
577     CHECK_NULL_VOID(previewNode);
578     ViewStackProcessor::GetInstance()->Push(previewNode);
579     ViewAbstractModel::GetInstance()->BindContextMenu(
580         curResponseType_, params->menuBuilder, params->menuParam, params->previewBuilder);
581     ViewAbstractModel::GetInstance()->BindDragWithContextMenuParams(params->menuParam);
582     ViewStackProcessor::GetInstance()->Finish();
583 #endif
584 }
585 
OnContextMenuShow(const std::shared_ptr<BaseEventInfo> & info,bool isRichtext,bool result)586 void WebPattern::OnContextMenuShow(const std::shared_ptr<BaseEventInfo>& info, bool isRichtext, bool result)
587 {
588     TAG_LOGI(AceLogTag::ACE_WEB,
589         "OnContextMenuShow result:%{public}d, isNewDragStyle_:%{public}d", result, isNewDragStyle_);
590     curContextMenuResult_ = result;
591     auto *eventInfo = TypeInfoHelper::DynamicCast<ContextMenuEvent>(info.get());
592     CHECK_NULL_VOID(eventInfo);
593     contextMenuParam_ = eventInfo->GetParam();
594     CHECK_NULL_VOID(contextMenuParam_);
595     contextMenuResult_ = eventInfo->GetContextMenuResult();
596     CHECK_NULL_VOID(contextMenuResult_);
597     if (isRichtext) {
598         if (!contextSelectOverlay_) {
599             contextSelectOverlay_ = AceType::MakeRefPtr<WebContextSelectOverlay>(WeakClaim(this));
600         }
601         ShowContextSelectOverlay(RectF(), RectF());
602         return;
603     }
604     CHECK_NULL_VOID(isNewDragStyle_ && result);
605     bool isImage = (contextMenuParam_->GetLinkUrl().empty() &&
606         (contextMenuParam_->GetMediaType() == OHOS::NWeb::NWebContextMenuParams::ContextMenuMediaType::CM_MT_IMAGE));
607     if (isImage) {
608         auto sourceType = contextMenuParam_->GetSourceType();
609         if (sourceType == OHOS::NWeb::NWebContextMenuParams::ContextMenuSourceType::CM_ST_MOUSE) {
610             curResponseType_ = ResponseType::RIGHT_CLICK;
611         } else if (sourceType == OHOS::NWeb::NWebContextMenuParams::ContextMenuSourceType::CM_ST_LONG_PRESS) {
612             curResponseType_ = ResponseType::LONG_PRESS;
613         } else {
614             return;
615         }
616         curElementType_ = WebElementType::IMAGE;
617         CHECK_NULL_VOID(GetPreviewSelectionMenuParams(curElementType_, curResponseType_));
618         auto host = GetHost();
619         if (!host) {
620             TAG_LOGE(AceLogTag::ACE_WEB, "GetHost failed");
621             delegate_->OnContextMenuHide("");
622             return;
623         }
624         auto previewNode = CreatePreviewImageFrameNode(isImage);
625         if (!previewNode) {
626             TAG_LOGI(AceLogTag::ACE_WEB, "CreatePreviewImageFrameNode failed");
627             delegate_->OnContextMenuHide("");
628             return;
629         }
630 
631         host->AddChild(previewNode);
632         previewNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
633         previewNode->MarkModifyDone();
634         host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
635         host->MarkModifyDone();
636     }
637 }
638 
OnContextMenuHide()639 void WebPattern::OnContextMenuHide()
640 {
641     TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern OnContextMenuHide");
642     if (webData_) {
643         CloseContextSelectionMenu();
644         return;
645     }
646     RemovePreviewMenuNode();
647     CHECK_NULL_VOID(contextMenuResult_);
648     contextMenuResult_->Cancel();
649     curContextMenuResult_ = false;
650 }
651 
NeedSoftKeyboard() const652 bool WebPattern::NeedSoftKeyboard() const
653 {
654     if (delegate_) {
655         return delegate_->NeedSoftKeyboard();
656     }
657     return false;
658 }
659 
OnAttachToFrameNode()660 void WebPattern::OnAttachToFrameNode()
661 {
662     auto host = GetHost();
663     CHECK_NULL_VOID(host);
664     auto pipeline = PipelineContext::GetCurrentContext();
665     CHECK_NULL_VOID(pipeline);
666     SetRotation(pipeline->GetTransformHint());
667 
668     host->GetRenderContext()->SetClipToFrame(true);
669     if (!renderContextForSurface_) {
670         renderContextForSurface_ = RenderContext::Create();
671         static RenderContext::ContextParam param = { RenderContext::ContextType::HARDWARE_SURFACE,
672             "RosenWeb" };
673         CHECK_NULL_VOID(renderContextForSurface_);
674         renderContextForSurface_->InitContext(false, param);
675         // Disable hardware composition when initializing to fix visual artifacts when switching to a new webview.
676         auto surfaceNode = OHOS::Rosen::RSBaseNode::ReinterpretCast<OHOS::Rosen::RSSurfaceNode>(GetSurfaceRSNode());
677         CHECK_NULL_VOID(surfaceNode);
678         TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnAttachToFrameNode, web id = %{public}d", GetWebId());
679         ACE_SCOPED_TRACE("WebPattern::OnAttachToFrameNode, web id = %d", GetWebId());
680         surfaceNode->SetHardwareEnabled(true, Rosen::SelfDrawingNodeType::DEFAULT, false);
681     }
682     host->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_PARENT);
683     pipeline->AddNodesToNotifyMemoryLevel(host->GetId());
684 
685     auto callbackId = pipeline->RegisterTransformHintChangeCallback([weak = WeakClaim(this)](uint32_t transform) {
686         auto pattern = weak.Upgrade();
687         if (pattern) {
688             TAG_LOGD(AceLogTag::ACE_WEB, "OnAttach to frame node, set transform:%{public}u", transform);
689             pattern->SetRotation(transform);
690         }
691     });
692     UpdateTransformHintChangedCallbackId(callbackId);
693 #if !defined(PREVIEW) && !defined(ACE_UNITTEST) && defined(OHOS_PLATFORM)
694     if (UiSessionManager::GetInstance().GetWebFocusRegistered()) {
695         auto callback = [](int64_t accessibilityId, const std::string data) {
696             UiSessionManager::GetInstance().ReportWebUnfocusEvent(accessibilityId, data);
697         };
698         RegisterTextBlurCallback(callback);
699     }
700 #endif
701 }
702 
OnDetachFromFrameNode(FrameNode * frameNode)703 void WebPattern::OnDetachFromFrameNode(FrameNode* frameNode)
704 {
705     CHECK_NULL_VOID(delegate_);
706     isFocus_ = false;
707     delegate_->OnBlur();
708     OnQuickMenuDismissed();
709 
710     auto id = frameNode->GetId();
711     auto pipeline = AceType::DynamicCast<PipelineContext>(PipelineBase::GetCurrentContext());
712     CHECK_NULL_VOID(pipeline);
713     pipeline->RemoveWindowStateChangedCallback(id);
714     pipeline->RemoveWindowSizeChangeCallback(id);
715     pipeline->RemoveNodesToNotifyMemoryLevel(id);
716 
717     if (HasTransformHintChangedCallbackId()) {
718         pipeline->UnregisterTransformHintChangedCallback(transformHintChangedCallbackId_.value_or(-1));
719     }
720 #if !defined(PREVIEW) && !defined(ACE_UNITTEST) && defined(OHOS_PLATFORM)
721     if (UiSessionManager::GetInstance().GetWebFocusRegistered()) {
722         UnRegisterTextBlurCallback();
723     }
724 #endif
725 }
726 
SetRotation(uint32_t rotation)727 void WebPattern::SetRotation(uint32_t rotation)
728 {
729     if (renderMode_ == RenderMode::SYNC_RENDER || rotation_ == rotation) {
730         return;
731     }
732     rotation_ = rotation;
733     CHECK_NULL_VOID(renderSurface_);
734     renderSurface_->SetTransformHint(rotation);
735 }
736 
OnAttachToMainTree()737 void WebPattern::OnAttachToMainTree()
738 {
739     isAttachedToMainTree_ = true;
740     InitSlideUpdateListener();
741     TAG_LOGD(AceLogTag::ACE_WEB, "OnAttachToMainTree");
742     // report component is in foreground.
743     delegate_->OnRenderToForeground();
744 }
745 
OnDetachFromMainTree()746 void WebPattern::OnDetachFromMainTree()
747 {
748     isAttachedToMainTree_ = false;
749     TAG_LOGD(AceLogTag::ACE_WEB, "OnDetachFromMainTree");
750     // report component is in background.
751     delegate_->OnRenderToBackground();
752 }
753 
InitEvent()754 void WebPattern::InitEvent()
755 {
756     auto host = GetHost();
757     CHECK_NULL_VOID(host);
758     auto eventHub = host->GetEventHub<WebEventHub>();
759     CHECK_NULL_VOID(eventHub);
760 
761     auto gestureHub = eventHub->GetOrCreateGestureEventHub();
762     CHECK_NULL_VOID(gestureHub);
763 
764     InitTouchEvent(gestureHub);
765     InitDragEvent(gestureHub);
766     InitPanEvent(gestureHub);
767     if (GetWebInfoType() == WebInfoType::TYPE_2IN1) {
768         InitPinchEvent(gestureHub);
769     }
770 
771     auto inputHub = eventHub->GetOrCreateInputEventHub();
772     CHECK_NULL_VOID(inputHub);
773     InitMouseEvent(inputHub);
774     InitHoverEvent(inputHub);
775 
776     auto focusHub = eventHub->GetOrCreateFocusHub();
777     CHECK_NULL_VOID(focusHub);
778     InitFocusEvent(focusHub);
779 }
780 
InitConfigChangeCallback(const RefPtr<PipelineContext> & context)781 void WebPattern::InitConfigChangeCallback(const RefPtr<PipelineContext> &context)
782 {
783     auto langTask = [weak = AceType::WeakClaim(this)]() {
784         auto WebPattern = weak.Upgrade();
785         CHECK_NULL_VOID(WebPattern);
786         WebPattern->UpdateLocale();
787     };
788     context->SetConfigChangedCallback(GetHost()->GetId(), std::move(langTask));
789 }
790 
InitFeatureParam()791 void WebPattern::InitFeatureParam()
792 {
793     isVisibleActiveEnable_ = system::GetBoolParameter(VISIBLE_ACTIVE_ENABLE, true);
794     isMemoryLevelEnable_ = system::GetBoolParameter(MEMORY_LEVEL_ENABEL, true);
795 }
796 
InitPanEvent(const RefPtr<GestureEventHub> & gestureHub)797 void WebPattern::InitPanEvent(const RefPtr<GestureEventHub>& gestureHub)
798 {
799     if (panEvent_) {
800         return;
801     }
802     auto actionStartTask = [weak = WeakClaim(this)](const GestureEvent& event) {
803         auto pattern = weak.Upgrade();
804         CHECK_NULL_VOID(pattern);
805         // Determine if there is already a fixed nested scroll mode.
806         if (!pattern->GetIsFixedNestedScrollMode() || !pattern->GetNestedScrollParent()) {
807             pattern->SetParentScrollable();
808         }
809         pattern->GetParentAxis();
810     };
811     auto actionUpdateTask = [weak = WeakClaim(this)](const GestureEvent& event) {
812         auto pattern = weak.Upgrade();
813         CHECK_NULL_VOID(pattern);
814         pattern->HandleDragMove(event);
815     };
816     auto actionEndTask = [weak = WeakClaim(this)](const GestureEvent& info) {
817         auto pattern = weak.Upgrade();
818         CHECK_NULL_VOID(pattern);
819         pattern->HandleFlingMove(info);
820     };
821     auto actionCancelTask = [weak = WeakClaim(this)]() { return; };
822     PanDirection panDirection;
823     panDirection.type = PanDirection::ALL;
824     panEvent_ = MakeRefPtr<PanEvent>(
825         std::move(actionStartTask), std::move(actionUpdateTask), std::move(actionEndTask), std::move(actionCancelTask));
826     gestureHub->AddPanEvent(panEvent_, panDirection, DEFAULT_PAN_FINGER, DEFAULT_PAN_DISTANCE);
827     gestureHub->SetPanEventType(GestureTypeName::WEBSCROLL);
828     gestureHub->SetOnGestureJudgeNativeBegin([](const RefPtr<NG::GestureInfo>& gestureInfo,
829                                                 const std::shared_ptr<BaseGestureEvent>& info) -> GestureJudgeResult {
830             if (!gestureInfo) {
831                 // info is null, default case to continue
832                 return GestureJudgeResult::CONTINUE;
833             }
834             if (gestureInfo->GetType() != GestureTypeName::WEBSCROLL) {
835                 // not web pan event type, continue
836                 return GestureJudgeResult::CONTINUE;
837             }
838 
839             auto inputEventType = gestureInfo->GetInputEventType();
840             if (inputEventType == InputEventType::AXIS) {
841                 // axis event type of web pan, dispatch to panEvent to process
842                 return GestureJudgeResult::CONTINUE;
843             } else if (inputEventType == InputEventType::MOUSE_BUTTON) {
844                 // mouse button event type of web pan, dispatch to DragEvent to process
845                 return GestureJudgeResult::REJECT;
846             }
847             // In other cases, the panEvent is used by default
848             return GestureJudgeResult::CONTINUE;
849         });
850 }
851 
HandleFlingMove(const GestureEvent & event)852 void WebPattern::HandleFlingMove(const GestureEvent& event)
853 {
854     if ((event.GetInputEventType() == InputEventType::AXIS) &&
855         (event.GetSourceTool() == SourceTool::TOUCHPAD)) {
856         CHECK_NULL_VOID(delegate_);
857         std::vector<int32_t> pressedCodes;
858         auto gesturePressedCodes = event.GetPressedKeyCodes();
859         for (auto pCode : gesturePressedCodes) {
860             pressedCodes.push_back(static_cast<int32_t>(pCode));
861         }
862         auto localLocation = event.GetLocalLocation();
863         TAG_LOGI(AceLogTag::ACE_WEB, "web touchpad fling event, vx: %{public}f, vy: %{public}f",
864                  event.GetVelocity().GetVelocityX(), event.GetVelocity().GetVelocityY());
865         delegate_->WebHandleTouchpadFlingEvent(localLocation.GetX(), localLocation.GetY(),
866                                                event.GetVelocity().GetVelocityX(),
867                                                event.GetVelocity().GetVelocityY(),
868                                                pressedCodes);
869     }
870 }
871 
HandleDragMove(const GestureEvent & event)872 void WebPattern::HandleDragMove(const GestureEvent& event)
873 {
874     if (event.GetInputEventType() == InputEventType::AXIS) {
875         CHECK_NULL_VOID(delegate_);
876         auto localLocation = event.GetLocalLocation();
877         std::vector<int32_t> pressedCodes;
878         auto gesturePressedCodes = event.GetPressedKeyCodes();
879         for (auto pCode : gesturePressedCodes) {
880             pressedCodes.push_back(static_cast<int32_t>(pCode));
881         }
882         delegate_->WebHandleAxisEvent(localLocation.GetX(), localLocation.GetY(),
883             event.GetDelta().GetX() * DEFAULT_AXIS_RATIO, event.GetDelta().GetY() * DEFAULT_AXIS_RATIO,
884             pressedCodes);
885     }
886 }
887 
InitPinchEvent(const RefPtr<GestureEventHub> & gestureHub)888 void WebPattern::InitPinchEvent(const RefPtr<GestureEventHub>& gestureHub)
889 {
890     if (pinchGesture_) {
891         return;
892     }
893     auto actionStartTask = [weak = WeakClaim(this)](const GestureEvent& event) {
894         auto pattern = weak.Upgrade();
895         CHECK_NULL_VOID(pattern);
896         pattern->startPinchScale_ = event.GetScale();
897         pattern->preScale_ = event.GetScale();
898         pattern->pinchIndex_ = 0;
899         pattern->zoomOutSwitch_ = false;
900         pattern->zoomStatus_ = 0;
901         pattern->zoomErrorCount_ = 0;
902         TAG_LOGI(AceLogTag::ACE_WEB, "InitPinchEvent StartScale: %{public}f", pattern->startPinchScale_);
903 
904         return;
905     };
906     auto actionUpdateTask = [weak = WeakClaim(this)](const GestureEvent& event) {
907         ACE_SCOPED_TRACE("WebPattern::InitPinchEvent actionUpdateTask");
908         auto pattern = weak.Upgrade();
909         CHECK_NULL_VOID(pattern);
910         if (event.GetSourceTool() == SourceTool::TOUCHPAD) {
911             pattern->HandleScaleGestureChange(event);
912             TAG_LOGD(AceLogTag::ACE_WEB, "InitPinchEvent actionUpdateTask event scale:%{public}f: ",
913                 event.GetScale());
914         }
915     };
916     auto actionEndTask = [weak = WeakClaim(this)](const GestureEvent& event) { return; };
917     auto actionCancelTask = [weak = WeakClaim(this)]() { return; };
918 
919     pinchGesture_ = MakeRefPtr<PinchGesture>(DEFAULT_PINCH_FINGER, DEFAULT_PINCH_DISTANCE);
920     pinchGesture_->SetPriority(GesturePriority::Parallel);
921     pinchGesture_->SetOnActionStartId(actionStartTask);
922     pinchGesture_->SetOnActionUpdateId(actionUpdateTask);
923     pinchGesture_->SetOnActionEndId(actionEndTask);
924     pinchGesture_->SetOnActionCancelId(actionCancelTask);
925     gestureHub->AddGesture(pinchGesture_);
926 }
927 
CheckZoomStatus(const double & curScale)928 bool WebPattern::CheckZoomStatus(const double& curScale)
929 {
930     int32_t curScaleNew = (int32_t) (curScale * 100);
931     int32_t preScaleNew = (int32_t) (preScale_ * 100);
932 
933     TAG_LOGI(AceLogTag::ACE_WEB,
934         "HandleScaleGestureChange curScaleNew:%{public}d preScaleNew: %{public}d",
935         curScaleNew, preScaleNew);
936 
937     // check zoom status
938     if ((zoomStatus_ == STATUS_ZOOMOUT && curScaleNew - preScaleNew < 0)
939             && zoomErrorCount_ < ZOOM_ERROR_COUNT_MAX) {
940         zoomErrorCount_++;
941         TAG_LOGI(AceLogTag::ACE_WEB, "HandleScaleGestureChange zoomStatus = zoomout && curScale < preScale,"
942             "ignore date.");
943         return false;
944     } else if ((zoomStatus_ == STATUS_ZOOMIN && curScaleNew - preScaleNew > 0)
945                 && zoomErrorCount_ < ZOOM_ERROR_COUNT_MAX) {
946         zoomErrorCount_++;
947         TAG_LOGI(AceLogTag::ACE_WEB, "HandleScaleGestureChange zoomStatus = zoomin && curScale >= preScale,"
948             "ignore date.");
949         return false;
950     } else {
951         // nothing
952     }
953     return true;
954 }
955 
ZoomOutAndIn(const double & curScale,double & scale)956 bool WebPattern::ZoomOutAndIn(const double& curScale, double& scale)
957 {
958     int32_t curScaleNew = (int32_t)(curScale * 100);
959     int32_t preScaleNew = (int32_t)(preScale_ * 100);
960 
961     // zoom out
962     if (curScale - preScale_ >= 0) {
963         if (preScale_ >= DEFAULT_PINCH_SCALE) {
964             if (startPinchScale_ >= DEFAULT_PINCH_SCALE) {
965                 scale = curScale;
966             } else {
967                 scale = DEFAULT_PINCH_SCALE + (curScale - startPinchScale_);
968             }
969 
970             // Prevent shaking in index 1
971             if (pinchIndex_ == PINCH_INDEX_ONE) {
972                 pageScale_ = scale;
973             }
974         } else {
975             // The scale is from 0.4 to 0.5, the scale conversion should be from 1.0 to 1.1
976             if (pageScale_ < DEFAULT_PINCH_SCALE) {
977                 TAG_LOGI(AceLogTag::ACE_WEB, "HandleScaleGestureChange Switch from zoomin to zoomout.");
978                 // must be page scale form 0.4 to 1
979                 scale = DEFAULT_PINCH_SCALE;
980                 // reset
981                 startPinchScale_ = preScale_;
982                 pageScale_ = scale;
983                 zoomOutSwitch_ = true;
984             } else {
985                 scale = DEFAULT_PINCH_SCALE + (curScale - startPinchScale_);
986                 zoomOutSwitch_ = false;
987             }
988         }
989         zoomStatus_ = STATUS_ZOOMOUT;
990         // zoom in
991     } else {
992         // When zooming in from a scale less than 1,
993         // the current scale must be greater than the previous scale value
994         if (zoomOutSwitch_) {
995             TAG_LOGI(AceLogTag::ACE_WEB, "HandleScaleGestureChange the current scale must be greater "
996                                          "than the previous scale value, ignore data.");
997             return false;
998         }
999 
1000         if (curScaleNew == preScaleNew) {
1001             return false;
1002         }
1003 
1004         scale = ZOOMIN_SMOOTH_SCALE;
1005 
1006         zoomStatus_ = STATUS_ZOOMIN;
1007     }
1008     return true;
1009 }
1010 
HandleScaleGestureChange(const GestureEvent & event)1011 void WebPattern::HandleScaleGestureChange(const GestureEvent& event)
1012 {
1013     CHECK_NULL_VOID(delegate_);
1014 
1015     double curScale = event.GetScale();
1016     if (std::fabs(curScale - preScale_) <= std::numeric_limits<double>::epsilon()) {
1017         TAG_LOGI(AceLogTag::ACE_WEB, "HandleScaleGestureChange curScale == preScale");
1018         return;
1019     }
1020 
1021     if (!CheckZoomStatus(curScale)) {
1022         return;
1023     }
1024     zoomErrorCount_ = 0;
1025 
1026     pinchIndex_++;
1027 
1028     double scale = 0.0;
1029     if (!ZoomOutAndIn(curScale, scale)) {
1030         return;
1031     }
1032     double newScale = GetNewScale(scale);
1033 
1034     double centerX = event.GetPinchCenter().GetX();
1035     double centerY = event.GetPinchCenter().GetY();
1036     auto frameNode = GetHost();
1037     CHECK_NULL_VOID(frameNode);
1038     auto offset = frameNode->GetOffsetRelativeToWindow();
1039     TAG_LOGD(AceLogTag::ACE_WEB,
1040         "HandleScaleGestureChange curScale:%{public}f pageScale: %{public}f newScale: %{public}f centerX: "
1041         "%{public}f centerY: %{public}f offset X: %{public}f offset Y: %{public}f",
1042         curScale, scale, newScale, centerX, centerY, offset.GetX(), offset.GetY());
1043     delegate_->ScaleGestureChange(newScale, centerX - offset.GetX(), centerY - offset.GetY());
1044 
1045     preScale_ = curScale;
1046     pageScale_ = scale;
1047 }
1048 
GetNewScale(double & scale) const1049 double WebPattern::GetNewScale(double& scale) const
1050 {
1051     double newScale = 0.0;
1052     if (scale >= DEFAULT_PINCH_SCALE) {
1053         // In order to achieve a sequence similar to scale, eg. 1.1, 1.2, 1.3
1054         newScale = scale / pageScale_;
1055         // scale max
1056         if (newScale > DEFAULT_PINCH_SCALE_MAX) {
1057             newScale = DEFAULT_PINCH_SCALE_MAX;
1058             scale = DEFAULT_PINCH_SCALE_MAX;
1059         }
1060     } else {
1061         newScale = scale;
1062         // scale min
1063         if (newScale < DEFAULT_PINCH_SCALE_MIN) {
1064             newScale = DEFAULT_PINCH_SCALE_MIN;
1065             scale = DEFAULT_PINCH_SCALE_MIN;
1066         }
1067     }
1068 
1069     return newScale;
1070 }
1071 
InitTouchEvent(const RefPtr<GestureEventHub> & gestureHub)1072 void WebPattern::InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub)
1073 {
1074     if (touchEvent_) {
1075         return;
1076     }
1077 
1078     auto touchTask = [weak = WeakClaim(this)](const TouchEventInfo& info) {
1079         auto pattern = weak.Upgrade();
1080         CHECK_NULL_VOID(pattern);
1081         pattern->OnTooltip("");
1082         if (info.GetChangedTouches().empty()) {
1083             return;
1084         }
1085 
1086         // only handle touch event
1087         if (info.GetSourceDevice() != SourceType::TOUCH) {
1088             return;
1089         }
1090         pattern->touchEventInfo_ = info;
1091         pattern->isMouseEvent_ = false;
1092         const auto& changedPoint = info.GetChangedTouches().front();
1093         if (changedPoint.GetTouchType() == TouchType::DOWN ||
1094             changedPoint.GetTouchType() == TouchType::UP) {
1095             if (pattern->touchEventQueue_.size() < TOUCH_EVENT_MAX_SIZE) {
1096                 pattern->touchEventQueue_.push(info);
1097             }
1098         }
1099 
1100         if (changedPoint.GetTouchType() == TouchType::DOWN) {
1101             pattern->HandleTouchDown(info, false);
1102             return;
1103         }
1104         if (changedPoint.GetTouchType() == TouchType::MOVE) {
1105             pattern->HandleTouchMove(info, false);
1106             return;
1107         }
1108         if (changedPoint.GetTouchType() == TouchType::UP) {
1109             pattern->HandleTouchUp(info, false);
1110             return;
1111         }
1112         if (changedPoint.GetTouchType() == TouchType::CANCEL) {
1113             pattern->HandleTouchCancel(info);
1114             return;
1115         }
1116     };
1117     touchEvent_ = MakeRefPtr<TouchEventImpl>(std::move(touchTask));
1118     gestureHub->AddTouchEvent(touchEvent_);
1119 }
1120 
InitMouseEvent(const RefPtr<InputEventHub> & inputHub)1121 void WebPattern::InitMouseEvent(const RefPtr<InputEventHub>& inputHub)
1122 {
1123     if (mouseEvent_) {
1124         return;
1125     }
1126 
1127     auto mouseTask = [weak = WeakClaim(this)](MouseInfo& info) {
1128         auto pattern = weak.Upgrade();
1129         CHECK_NULL_VOID(pattern);
1130         pattern->HandleMouseEvent(info);
1131     };
1132 
1133     mouseEvent_ = MakeRefPtr<InputEvent>(std::move(mouseTask));
1134     inputHub->AddOnMouseEvent(mouseEvent_);
1135 }
1136 
InitHoverEvent(const RefPtr<InputEventHub> & inputHub)1137 void WebPattern::InitHoverEvent(const RefPtr<InputEventHub>& inputHub)
1138 {
1139     if (hoverEvent_) {
1140         return;
1141     }
1142 
1143     auto hoverTask = [weak = WeakClaim(this)](bool isHover) {
1144         auto pattern = weak.Upgrade();
1145         CHECK_NULL_VOID(pattern);
1146         MouseInfo info;
1147         info.SetAction(isHover ? MouseAction::HOVER : MouseAction::HOVER_EXIT);
1148         pattern->SetMouseHoverExit(!isHover);
1149         if (!isHover) {
1150             TAG_LOGI(AceLogTag::ACE_WEB,
1151                 "Set cursor to pointer when mouse pointer is leave.");
1152             pattern->OnCursorChange(OHOS::NWeb::CursorType::CT_POINTER, nullptr);
1153         }
1154         pattern->WebOnMouseEvent(info);
1155     };
1156 
1157     hoverEvent_ = MakeRefPtr<InputEvent>(std::move(hoverTask));
1158     inputHub->AddOnHoverEvent(hoverEvent_);
1159 }
1160 
HandleMouseEvent(MouseInfo & info)1161 void WebPattern::HandleMouseEvent(MouseInfo& info)
1162 {
1163     isMouseEvent_ = true;
1164     WebOnMouseEvent(info);
1165 
1166     auto host = GetHost();
1167     CHECK_NULL_VOID(host);
1168     auto eventHub = host->GetEventHub<WebEventHub>();
1169     CHECK_NULL_VOID(eventHub);
1170     auto mouseEventCallback = eventHub->GetOnMouseEvent();
1171     CHECK_NULL_VOID(mouseEventCallback);
1172     mouseEventCallback(info);
1173 }
1174 
WebOnMouseEvent(const MouseInfo & info)1175 void WebPattern::WebOnMouseEvent(const MouseInfo& info)
1176 {
1177     if (mouseEventDeviceId_ != info.GetDeviceId()) {
1178         mouseEventDeviceId_ = info.GetDeviceId();
1179     }
1180     CHECK_NULL_VOID(delegate_);
1181     auto localLocation = info.GetLocalLocation();
1182     if ((mouseHoveredX_ != localLocation.GetX()) ||
1183         (mouseHoveredY_ != localLocation.GetY()) ||
1184         (info.GetAction() == MouseAction::PRESS) ||
1185         (info.GetButton() == MouseButton::LEFT_BUTTON) ||
1186         (info.GetButton() == MouseButton::RIGHT_BUTTON)) {
1187         OnTooltip("");
1188     }
1189     if (info.GetAction() == MouseAction::PRESS) {
1190         delegate_->OnContextMenuHide("");
1191         WebRequestFocus();
1192     }
1193 
1194     // set touchup false when using mouse
1195     isTouchUpEvent_ = false;
1196     if (info.GetButton() == MouseButton::LEFT_BUTTON && info.GetAction() == MouseAction::RELEASE) {
1197         if (isReceivedArkDrag_) {
1198             TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop Do not reset drag action when dragging,"
1199                 "drop/cancel/end event will do this");
1200             return;
1201         }
1202         ResetDragAction();
1203     }
1204     isHoverExit_ = false;
1205     if (info.GetAction() == MouseAction::HOVER_EXIT) {
1206         TAG_LOGI(AceLogTag::ACE_WEB,
1207             "Set cursor to pointer when mouse pointer is hover exit.");
1208         isHoverExit_ = true;
1209         OnCursorChange(OHOS::NWeb::CursorType::CT_POINTER, nullptr);
1210     }
1211 
1212     if (!HandleDoubleClickEvent(info)) {
1213         delegate_->OnMouseEvent(
1214             localLocation.GetX(), localLocation.GetY(), info.GetButton(), info.GetAction(), SINGLE_CLICK_NUM);
1215     }
1216 
1217     if (info.GetAction() == MouseAction::MOVE) {
1218         mouseHoveredX_ = localLocation.GetX();
1219         mouseHoveredY_ = localLocation.GetY();
1220     }
1221 }
1222 
ResetDragAction()1223 void WebPattern::ResetDragAction()
1224 {
1225     auto frameNode = GetHost();
1226     CHECK_NULL_VOID(frameNode);
1227     frameNode->SetDraggable(false);
1228     auto eventHub = frameNode->GetEventHub<WebEventHub>();
1229     CHECK_NULL_VOID(eventHub);
1230     auto gestureHub = eventHub->GetOrCreateGestureEventHub();
1231     CHECK_NULL_VOID(gestureHub);
1232     gestureHub->ResetDragActionForWeb();
1233 
1234     if (!isDragging_) {
1235         return;
1236     }
1237 
1238     isDragging_ = false;
1239     isReceivedArkDrag_ = false;
1240     // cancel drag action to avoid web kernel can't process other input event
1241     CHECK_NULL_VOID(delegate_);
1242     delegate_->HandleDragEvent(0, 0, DragAction::DRAG_CANCEL);
1243     gestureHub->CancelDragForWeb();
1244 }
1245 
GetDragOffset() const1246 Offset WebPattern::GetDragOffset() const
1247 {
1248     Offset webDragOffset;
1249     int x = 0;
1250     int y = 0;
1251     if (delegate_ && delegate_->dragData_) {
1252         delegate_->dragData_->GetDragStartPosition(x, y);
1253     }
1254 
1255     webDragOffset.SetX(x);
1256     webDragOffset.SetY(y);
1257 
1258     return webDragOffset;
1259 }
1260 
GetDragPixelMapSize() const1261 SizeF WebPattern::GetDragPixelMapSize() const
1262 {
1263     SizeF pixelMapSize;
1264     int32_t width = 0;
1265     int32_t height = 0;
1266     RefPtr<PixelMap> pixelMap = nullptr;
1267     if (delegate_) {
1268         pixelMap = delegate_->GetDragPixelMap();
1269     }
1270     if (pixelMap) {
1271         width = pixelMap->GetWidth();
1272         height = pixelMap->GetHeight();
1273     }
1274     pixelMapSize = SizeF(width, height);
1275     return pixelMapSize;
1276 }
1277 
HandleDoubleClickEvent(const MouseInfo & info)1278 bool WebPattern::HandleDoubleClickEvent(const MouseInfo& info)
1279 {
1280     if (info.GetButton() != MouseButton::LEFT_BUTTON || info.GetAction() != MouseAction::PRESS) {
1281         return false;
1282     }
1283     auto localLocation = info.GetLocalLocation();
1284     MouseClickInfo clickInfo;
1285     clickInfo.x = localLocation.GetX();
1286     clickInfo.y = localLocation.GetY();
1287     clickInfo.start = info.GetTimeStamp();
1288     if (doubleClickQueue_.empty()) {
1289         doubleClickQueue_.push(clickInfo);
1290         return false;
1291     }
1292     std::chrono::duration<float> timeout_ = clickInfo.start - doubleClickQueue_.back().start;
1293     double offsetX = clickInfo.x - doubleClickQueue_.back().x;
1294     double offsetY = clickInfo.y - doubleClickQueue_.back().y;
1295     double offset = sqrt(offsetX * offsetX + offsetY * offsetY);
1296     if (timeout_.count() < DEFAULT_DBCLICK_INTERVAL && offset < DEFAULT_DBCLICK_OFFSET) {
1297         SendDoubleClickEvent(clickInfo);
1298         std::queue<MouseClickInfo> empty;
1299         swap(empty, doubleClickQueue_);
1300         return true;
1301     }
1302     if (doubleClickQueue_.size() == 1) {
1303         doubleClickQueue_.push(clickInfo);
1304         return false;
1305     }
1306     doubleClickQueue_.pop();
1307     doubleClickQueue_.push(clickInfo);
1308     return false;
1309 }
1310 
SendDoubleClickEvent(const MouseClickInfo & info)1311 void WebPattern::SendDoubleClickEvent(const MouseClickInfo& info)
1312 {
1313     CHECK_NULL_VOID(delegate_);
1314     delegate_->OnMouseEvent(info.x, info.y, MouseButton::LEFT_BUTTON, MouseAction::PRESS, DOUBLE_CLICK_NUM);
1315 }
1316 
GenerateDragDropInfo(NG::DragDropInfo & dragDropInfo)1317 bool WebPattern::GenerateDragDropInfo(NG::DragDropInfo& dragDropInfo)
1318 {
1319     if (delegate_) {
1320         dragDropInfo.pixelMap = delegate_->GetDragPixelMap();
1321     }
1322 
1323     if (dragDropInfo.pixelMap) {
1324         isW3cDragEvent_ = true;
1325         return true;
1326     }
1327 
1328     return false;
1329 }
1330 
HandleOnDragStart(const RefPtr<OHOS::Ace::DragEvent> & info)1331 NG::DragDropInfo WebPattern::HandleOnDragStart(const RefPtr<OHOS::Ace::DragEvent>& info)
1332 {
1333     isDragging_ = true;
1334     isReceivedArkDrag_ = true;
1335     NG::DragDropInfo dragDropInfo;
1336     if (GenerateDragDropInfo(dragDropInfo)) {
1337         auto frameNode = GetHost();
1338         CHECK_NULL_RETURN(frameNode, dragDropInfo);
1339         CHECK_NULL_RETURN(delegate_, dragDropInfo);
1340         CHECK_NULL_RETURN(delegate_->dragData_, dragDropInfo);
1341         // get drag pixel map successfully, disable next drag util received web kernel drag callback
1342         frameNode->SetDraggable(false);
1343         RefPtr<UnifiedData> aceUnifiedData = UdmfClient::GetInstance()->CreateUnifiedData();
1344         std::string fileName = delegate_->dragData_->GetImageFileName();
1345         std::string plainContent = delegate_->dragData_->GetFragmentText();
1346         std::string htmlContent = delegate_->dragData_->GetFragmentHtml();
1347         std::string linkUrl = delegate_->dragData_->GetLinkURL();
1348         std::string linkTitle = delegate_->dragData_->GetLinkTitle();
1349         if (!fileName.empty()) {
1350             OnDragFileNameStart(aceUnifiedData, fileName);
1351         } else {
1352             TAG_LOGW(AceLogTag::ACE_WEB, "DragDrop event start, dragdata has no image file uri, just pass");
1353         }
1354         if (!plainContent.empty()) {
1355             isDragEndMenuShow_ = true;
1356             UdmfClient::GetInstance()->AddPlainTextRecord(aceUnifiedData, plainContent);
1357         }
1358         if (!htmlContent.empty()) {
1359             isDragEndMenuShow_ = true;
1360             UdmfClient::GetInstance()->AddHtmlRecord(aceUnifiedData, htmlContent, "");
1361         }
1362         if (!linkUrl.empty()) {
1363             isDragEndMenuShow_ = false;
1364             UdmfClient::GetInstance()->AddLinkRecord(aceUnifiedData, linkUrl, linkTitle);
1365             TAG_LOGI(AceLogTag::ACE_WEB, "web DragDrop event Start, linkUrl size:%{public}zu", linkUrl.size());
1366         }
1367         info->SetData(aceUnifiedData);
1368         HandleOnDragEnter(info);
1369         return dragDropInfo;
1370     }
1371     return dragDropInfo;
1372 }
1373 
OnDragFileNameStart(const RefPtr<UnifiedData> & aceUnifiedData,const std::string & fileName)1374 void WebPattern::OnDragFileNameStart(const RefPtr<UnifiedData>& aceUnifiedData, const std::string& fileName)
1375 {
1376     isDragEndMenuShow_ = false;
1377     std::string fullName;
1378     if (delegate_->tempDir_.empty()) {
1379         fullName = "/data/storage/el2/base/haps/entry/temp/dragdrop/" + fileName;
1380     } else {
1381         fullName = delegate_->tempDir_ + "/dragdrop/" + fileName;
1382     }
1383     AppFileService::ModuleFileUri::FileUri fileUri(fullName);
1384     TAG_LOGI(AceLogTag::ACE_WEB, "web DragDrop event Start, FileUri:%{public}s, image path:%{public}s",
1385         fileUri.ToString().c_str(), fullName.c_str());
1386     std::vector<std::string> urlVec;
1387     std::string udmfUri = fileUri.ToString();
1388     urlVec.emplace_back(udmfUri);
1389     UdmfClient::GetInstance()->AddFileUriRecord(aceUnifiedData, urlVec);
1390 }
1391 
HandleOnDropMove(const RefPtr<OHOS::Ace::DragEvent> & info)1392 void WebPattern::HandleOnDropMove(const RefPtr<OHOS::Ace::DragEvent>& info)
1393 {
1394     if (!isDragging_) {
1395         return;
1396     }
1397 
1398     if (!isW3cDragEvent_) {
1399         return;
1400     }
1401 
1402     CHECK_NULL_VOID(delegate_);
1403     auto host = GetHost();
1404     CHECK_NULL_VOID(host);
1405     auto pipelineContext = host->GetContextRefPtr();
1406     CHECK_NULL_VOID(pipelineContext);
1407     auto viewScale = pipelineContext->GetViewScale();
1408     int32_t globalX = static_cast<int32_t>(info->GetX()) * viewScale;
1409     int32_t globalY = static_cast<int32_t>(info->GetY()) * viewScale;
1410     auto offset = GetCoordinatePoint();
1411     globalX = static_cast<int32_t>(globalX - offset.value_or(OffsetF()).GetX());
1412     globalY = static_cast<int32_t>(globalY - offset.value_or(OffsetF()).GetY());
1413     delegate_->HandleDragEvent(globalX, globalY, DragAction::DRAG_OVER);
1414 }
1415 
InitCommonDragDropEvent(const RefPtr<GestureEventHub> & gestureHub)1416 void WebPattern::InitCommonDragDropEvent(const RefPtr<GestureEventHub>& gestureHub)
1417 {
1418     auto frameNode = GetHost();
1419     CHECK_NULL_VOID(frameNode);
1420     auto eventHub = frameNode->GetEventHub<WebEventHub>();
1421     CHECK_NULL_VOID(eventHub);
1422 
1423     isDisableDrag_ = false;
1424     // disable drag
1425     frameNode->SetDraggable(false);
1426     // init common drag drop event
1427     gestureHub->InitDragDropEvent();
1428     InitWebEventHubDragDropStart(eventHub);
1429     InitWebEventHubDragDropEnd(eventHub);
1430     InitWebEventHubDragMove(eventHub);
1431     TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop WebEventHub init drag event ok");
1432 }
1433 
InitWebEventHubDragDropStart(const RefPtr<WebEventHub> & eventHub)1434 void WebPattern::InitWebEventHubDragDropStart(const RefPtr<WebEventHub>& eventHub)
1435 {
1436     auto onDragStartId = [weak = WeakClaim(this)](const RefPtr<OHOS::Ace::DragEvent>& info,
1437                              const std::string& extraParams) -> NG::DragDropInfo {
1438         TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop WebEventHub drag start,"
1439             " x:%{public}lf, y:%{public}lf", info->GetX(), info->GetY());
1440         NG::DragDropInfo dragDropInfo;
1441         auto pattern = weak.Upgrade();
1442         if (pattern) {
1443             TAG_LOGI(AceLogTag::ACE_WEB,
1444                 "DragDrop event WebEventHub onDragStartId, x:%{public}lf, y:%{public}lf, webId:%{public}d",
1445                 info->GetX(), info->GetY(), pattern->GetWebId());
1446             pattern->dropX_ = 0;
1447             pattern->dropY_ = 0;
1448             return pattern->HandleOnDragStart(info);
1449         }
1450         return dragDropInfo;
1451     };
1452 
1453     auto onDragEnterId = [weak = WeakClaim(this)](const RefPtr<OHOS::Ace::DragEvent>& info,
1454                              const std::string& extraParams) {
1455         TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop WebEventHub drag enter,"
1456             " x:%{public}lf, y:%{public}lf", info->GetX(), info->GetY());
1457         auto pattern = weak.Upgrade();
1458         CHECK_NULL_VOID(pattern);
1459         TAG_LOGI(AceLogTag::ACE_WEB,
1460             "DragDrop event WebEventHub onDragEnterId, x:%{public}lf, y:%{public}lf, webId:%{public}d",
1461             info->GetX(), info->GetY(), pattern->GetWebId());
1462         pattern->isW3cDragEvent_ = true;
1463         pattern->isDragging_ = true;
1464         pattern->isReceivedArkDrag_ = true;
1465         pattern->dropX_ = 0;
1466         pattern->dropY_ = 0;
1467         return pattern->HandleOnDragEnter(info);
1468     };
1469 
1470     // set custom OnDragStart function
1471     eventHub->SetOnDragStart(std::move(onDragStartId));
1472     eventHub->SetOnDragEnter(std::move(onDragEnterId));
1473 }
1474 
InitWebEventHubDragMove(const RefPtr<WebEventHub> & eventHub)1475 void WebPattern::InitWebEventHubDragMove(const RefPtr<WebEventHub>& eventHub)
1476 {
1477     auto onDragMoveId = [weak = WeakClaim(this)](const RefPtr<OHOS::Ace::DragEvent>& info,
1478                              const std::string& extraParams) {
1479         static uint32_t dragMoveCnt = 0;
1480         if ((dragMoveCnt % DEBUG_DRAGMOVEID_TIMER) == 0) {
1481             TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop  WebEventHub drag move,"
1482                 " x:%{public}lf, y:%{public}lf", info->GetX(), info->GetY());
1483         }
1484         auto pattern = weak.Upgrade();
1485         CHECK_NULL_VOID(pattern);
1486         if ((dragMoveCnt++ % DEBUG_DRAGMOVEID_TIMER) == 0) {
1487             TAG_LOGI(AceLogTag::ACE_WEB,
1488                 "DragDrop event WebEventHub onDragMoveId, x:%{public}lf, y:%{public}lf, webId:%{public}d",
1489                 info->GetX(), info->GetY(), pattern->GetWebId());
1490         }
1491         if (!pattern->isDragging_) {
1492             return;
1493         }
1494 
1495         // update drag status
1496         info->SetResult(pattern->GetDragAcceptableStatus());
1497 
1498         pattern->HandleOnDropMove(info);
1499     };
1500     // set custom OnDragStart function
1501     eventHub->SetOnDragMove(std::move(onDragMoveId));
1502 }
1503 
InitWebEventHubDragDropEnd(const RefPtr<WebEventHub> & eventHub)1504 void WebPattern::InitWebEventHubDragDropEnd(const RefPtr<WebEventHub>& eventHub)
1505 {
1506     auto onDragDropId = [weak = WeakClaim(this)](const RefPtr<OHOS::Ace::DragEvent>& info,
1507                              const std::string& extraParams) {
1508         TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop WebEventHub drag drop,"
1509             " x:%{public}lf, y:%{public}lf", info->GetX(), info->GetY());
1510         auto pattern = weak.Upgrade();
1511         CHECK_NULL_VOID(pattern);
1512         TAG_LOGI(AceLogTag::ACE_WEB,
1513             "DragDrop event WebEventHub onDragDropId, x:%{public}lf, y:%{public}lf, webId:%{public}d",
1514             info->GetX(), info->GetY(), pattern->GetWebId());
1515         if (!pattern->isDragging_) {
1516             return;
1517         }
1518         pattern->dropX_ = info->GetX();
1519         pattern->dropY_ = info->GetY();
1520         pattern->HandleOnDragDrop(info);
1521     };
1522 
1523     auto onDragLeaveId = [weak = WeakClaim(this)](const RefPtr<OHOS::Ace::DragEvent>& info,
1524                              const std::string& extraParams) {
1525         TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop WebEventHub drag leave,"
1526             " x:%{public}lf, y:%{public}lf", info->GetX(), info->GetY());
1527         auto pattern = weak.Upgrade();
1528         CHECK_NULL_VOID(pattern);
1529         TAG_LOGI(AceLogTag::ACE_WEB,
1530             "DragDrop event WebEventHub onDragLeaveId, x:%{public}lf, y:%{public}lf, webId:%{public}d",
1531             info->GetX(), info->GetY(), pattern->GetWebId());
1532         pattern->HandleOnDragLeave(info->GetX(), info->GetY());
1533     };
1534 
1535     auto onDragEndId = [weak = WeakClaim(this)](const RefPtr<OHOS::Ace::DragEvent>& info) {
1536         TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop WebEventHub drag end,"
1537             " x:%{public}lf, y:%{public}lf", info->GetX(), info->GetY());
1538         auto pattern = weak.Upgrade();
1539         CHECK_NULL_VOID(pattern);
1540         TAG_LOGI(AceLogTag::ACE_WEB,
1541             "DragDrop event WebEventHub onDragEndId, x:%{public}lf, y:%{public}lf, webId:%{public}d",
1542             info->GetX(), info->GetY(), pattern->GetWebId());
1543         pattern->HandleDragEnd(pattern->dropX_, pattern->dropY_);
1544     };
1545     // set custom OnDragStart function
1546     eventHub->SetOnDragEnd(std::move(onDragEndId));
1547     eventHub->SetOnDragLeave(std::move(onDragLeaveId));
1548     eventHub->SetOnDrop(std::move(onDragDropId));
1549 }
1550 
IsImageDrag()1551 bool WebPattern::IsImageDrag()
1552 {
1553     if (delegate_) {
1554         return delegate_->IsImageDrag();
1555     }
1556     return false;
1557 }
1558 
GetDragAcceptableStatus()1559 DragRet WebPattern::GetDragAcceptableStatus()
1560 {
1561     OHOS::NWeb::NWebDragData::DragOperation status = delegate_->GetDragAcceptableStatus();
1562     if (status == OHOS::NWeb::NWebDragData::DragOperation::DRAG_OPERATION_MOVE ||
1563         status == OHOS::NWeb::NWebDragData::DragOperation::DRAG_OPERATION_LINK) {
1564         return DragRet::DRAG_DEFAULT;
1565     } else if (status == OHOS::NWeb::NWebDragData::DragOperation::DRAG_OPERATION_COPY) {
1566         return DragRet::DRAG_DEFAULT;
1567     }
1568     return DragRet::DRAG_DEFAULT;
1569 }
1570 
NotifyStartDragTask(bool isDelayed)1571 bool WebPattern::NotifyStartDragTask(bool isDelayed)
1572 {
1573     if (isDisableDrag_ || isTouchUpEvent_) {
1574         TAG_LOGW(AceLogTag::ACE_WEB, "DragDrop disable drag in web. isDisableDrag_:%{public}d,"
1575             "isTouchUpEvent_:%{public}d, isDelayed:%{public}d", isDisableDrag_, isTouchUpEvent_, isDelayed);
1576         if (isDelayed) {
1577             CHECK_NULL_RETURN(delegate_, false);
1578             delegate_->HandleDragEvent(0, 0, DragAction::DRAG_CANCEL);
1579         }
1580         return false;
1581     }
1582     isDragging_ = true;
1583     auto frameNode = GetHost();
1584     CHECK_NULL_RETURN(frameNode, false);
1585     auto eventHub = frameNode->GetEventHub<WebEventHub>();
1586     CHECK_NULL_RETURN(eventHub, false);
1587     auto gestureHub = eventHub->GetOrCreateGestureEventHub();
1588     CHECK_NULL_RETURN(gestureHub, false);
1589     CHECK_NULL_RETURN(delegate_, false);
1590     if (curContextMenuResult_ && (!isNewDragStyle_ || !previewImageNodeId_.has_value())) {
1591         TAG_LOGI(AceLogTag::ACE_WEB,
1592             "preview menu is not displayed, and the app is notified to close the long-press menu");
1593         delegate_->OnContextMenuHide("");
1594     }
1595     // received web kernel drag callback, enable drag
1596     frameNode->SetDraggable(true);
1597     gestureHub->SetPixelMap(delegate_->GetDragPixelMap());
1598     if (!isMouseEvent_) {
1599         // mouse drag does not need long press action
1600         bool isFloatImage = true;
1601         auto param = GetPreviewSelectionMenuParams(WebElementType::IMAGE, ResponseType::LONG_PRESS);
1602         if (isNewDragStyle_ && delegate_->IsImageDrag() && param && curContextMenuResult_) {
1603             isFloatImage = false;
1604         }
1605         gestureHub->StartLongPressActionForWeb(isFloatImage);
1606     }
1607     TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop enable drag and start drag task for web,"
1608         "is mouse event: %{public}d", isMouseEvent_);
1609     gestureHub->StartDragTaskForWeb();
1610     return true;
1611 }
1612 
InitDragEvent(const RefPtr<GestureEventHub> & gestureHub)1613 void WebPattern::InitDragEvent(const RefPtr<GestureEventHub>& gestureHub)
1614 {
1615     if (dragEvent_) {
1616         return;
1617     }
1618 
1619     auto host = GetHost();
1620     CHECK_NULL_VOID(host);
1621     auto eventHub = host->GetEventHub<WebEventHub>();
1622     CHECK_NULL_VOID(eventHub);
1623 
1624     auto userOnDragStartFunc = eventHub->GetOnDragStart();
1625     if (userOnDragStartFunc) {
1626         isDisableDrag_ = true;
1627         return;
1628     }
1629 
1630     InitCommonDragDropEvent(gestureHub);
1631 
1632     auto actionStartTask = [weak = WeakClaim(this)](const GestureEvent& info) {
1633         int32_t x = info.GetGlobalPoint().GetX();
1634         int32_t y = info.GetGlobalPoint().GetY();
1635         auto pattern = weak.Upgrade();
1636         CHECK_NULL_VOID(pattern);
1637         TAG_LOGI(AceLogTag::ACE_WEB,
1638             "DragDrop event gestureHub actionStartTask x:%{public}d, y:%{public}d, webId:%{public}d",
1639             x, y, pattern->GetWebId());
1640         pattern->HandleDragStart(x, y);
1641     };
1642 
1643     auto actionUpdateTask = [weak = WeakClaim(this)](const GestureEvent& info) {
1644         return;
1645     };
1646 
1647     auto actionEndTask = [weak = WeakClaim(this)](const GestureEvent& info) {
1648         int32_t x = info.GetGlobalPoint().GetX();
1649         int32_t y = info.GetGlobalPoint().GetY();
1650         auto pattern = weak.Upgrade();
1651         CHECK_NULL_VOID(pattern);
1652         TAG_LOGI(AceLogTag::ACE_WEB,
1653             "DragDrop event gestureHub actionEndTask x:%{public}d, y:%{public}d, webId:%{public}d",
1654             x, y, pattern->GetWebId());
1655         pattern->HandleDragEnd(x, y);
1656     };
1657 
1658     auto actionCancelTask = [weak = WeakClaim(this)]() {
1659     };
1660 
1661     dragEvent_ = MakeRefPtr<DragEvent>(
1662         std::move(actionStartTask), std::move(actionUpdateTask), std::move(actionEndTask), std::move(actionCancelTask));
1663     gestureHub->SetCustomDragEvent(dragEvent_, { PanDirection::ALL }, DEFAULT_PAN_FINGER, DEFAULT_PAN_DISTANCE);
1664 }
1665 
HandleDragStart(int32_t x,int32_t y)1666 void WebPattern::HandleDragStart(int32_t x, int32_t y)
1667 {
1668     TAG_LOGI(AceLogTag::ACE_WEB,
1669         "HandleDragStart DragDrop event gestureHub actionStart, isW3cDragEvent_:%{public}d, isMouseEvent_:%{public}d",
1670         (int)isW3cDragEvent_, (int)isMouseEvent_);
1671     if (!isW3cDragEvent_ && !isMouseEvent_) {
1672         auto frameNode = GetHost();
1673         CHECK_NULL_VOID(frameNode);
1674         frameNode->SetDraggable(false);
1675         auto eventHub = frameNode->GetEventHub<WebEventHub>();
1676         CHECK_NULL_VOID(eventHub);
1677         auto gestureHub = eventHub->GetOrCreateGestureEventHub();
1678         CHECK_NULL_VOID(gestureHub);
1679         gestureHub->ResetDragActionForWeb();
1680         isDragging_ = false;
1681         isReceivedArkDrag_ = false;
1682         // cancel drag action to avoid web kernel can't process other input event
1683         CHECK_NULL_VOID(delegate_);
1684         delegate_->HandleDragEvent(0, 0, DragAction::DRAG_CANCEL);
1685         gestureHub->CancelDragForWeb();
1686     }
1687 }
1688 
HandleOnDragEnter(const RefPtr<OHOS::Ace::DragEvent> & info)1689 void WebPattern::HandleOnDragEnter(const RefPtr<OHOS::Ace::DragEvent>& info)
1690 {
1691     if (!delegate_) {
1692         return;
1693     }
1694 
1695     auto host = GetHost();
1696     CHECK_NULL_VOID(host);
1697     auto pipelineContext = host->GetContextRefPtr();
1698     CHECK_NULL_VOID(pipelineContext);
1699     int32_t globalX = static_cast<int32_t>(info->GetX());
1700     int32_t globalY = static_cast<int32_t>(info->GetY());
1701     auto viewScale = pipelineContext->GetViewScale();
1702     auto offset = GetCoordinatePoint();
1703     int32_t localX = static_cast<int32_t>(globalX - offset.value_or(OffsetF()).GetX()) * viewScale;
1704     int32_t localY = static_cast<int32_t>(globalY - offset.value_or(OffsetF()).GetY()) * viewScale;
1705 
1706     // fake drag data when enter
1707     delegate_->GetOrCreateDragData();
1708     // use summary to set fake data
1709     ClearDragData();
1710     delegate_->HandleDragEvent(localX, localY, DragAction::DRAG_ENTER);
1711     // RequestFocus to show the carret frame_caret
1712     WebRequestFocus();
1713 }
1714 
HandleOnDragDropLink(RefPtr<UnifiedData> aceData)1715 void WebPattern::HandleOnDragDropLink(RefPtr<UnifiedData> aceData)
1716 {
1717     CHECK_NULL_VOID(aceData);
1718     CHECK_NULL_VOID(delegate_);
1719     CHECK_NULL_VOID(delegate_->dragData_);
1720     // hyperlink
1721     std::string linkUrl;
1722     std::string linkTitle;
1723     UdmfClient::GetInstance()->GetLinkRecord(aceData, linkUrl, linkTitle);
1724     if (!linkUrl.empty()) {
1725         delegate_->dragData_->SetLinkURL(linkUrl);
1726         delegate_->dragData_->SetLinkTitle(linkTitle);
1727         TAG_LOGI(AceLogTag::ACE_WEB,
1728             "DragDrop event WebEventHub onDragDropId, linkUrl size:%{public}zu", linkUrl.size());
1729     } else {
1730         TAG_LOGW(AceLogTag::ACE_WEB,
1731             "DragDrop event WebEventHub onDragDropId, linkUrl is empty");
1732     }
1733 }
1734 
HandleOnDragDropFile(RefPtr<UnifiedData> aceData)1735 void WebPattern::HandleOnDragDropFile(RefPtr<UnifiedData> aceData)
1736 {
1737     CHECK_NULL_VOID(aceData);
1738     CHECK_NULL_VOID(delegate_);
1739     CHECK_NULL_VOID(delegate_->dragData_);
1740     // file
1741     std::vector<std::string> urlVec;
1742     UdmfClient::GetInstance()->GetFileUriRecord(aceData, urlVec);
1743     TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop event WebEventHub onDragDropId,"
1744         "url array size is:%{public}zu", urlVec.size());
1745     delegate_->dragData_->ClearImageFileNames();
1746     for (std::string url : urlVec) {
1747         TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop event WebEventHub onDragDropId,"
1748             "url get from udmf:%{public}zu", url.length());
1749         AppFileService::ModuleFileUri::FileUri fileUri(url);
1750         TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop event WebEventHub onDragDropId,"
1751             "fileUri ToString:%{public}zu", fileUri.ToString().length());
1752         std::string uriRealPath = FileUriHelper::GetRealPath(url);
1753         if (!uriRealPath.empty() && access(uriRealPath.c_str(), F_OK) == 0) { // file exist
1754             TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop event WebEventHub onDragDropId,"
1755             "url real path:%{public}zu", uriRealPath.length());
1756             delegate_->dragData_->SetFileUri(uriRealPath);
1757         } else {
1758             TAG_LOGW(AceLogTag::ACE_WEB, "DragDrop event WebEventHub onDragDropId,"
1759                 "url is empty or not exist, uriRealPath:%{public}zu", uriRealPath.length());
1760         }
1761     }
1762 }
1763 
HandleOnDragDrop(const RefPtr<OHOS::Ace::DragEvent> & info)1764 void WebPattern::HandleOnDragDrop(const RefPtr<OHOS::Ace::DragEvent>& info)
1765 {
1766     isDragging_ = false;
1767     isReceivedArkDrag_ = false;
1768     isW3cDragEvent_ = false;
1769     CHECK_NULL_VOID(delegate_);
1770     auto host = GetHost();
1771     CHECK_NULL_VOID(host);
1772     auto pipelineContext = host->GetContextRefPtr();
1773     CHECK_NULL_VOID(pipelineContext);
1774     auto viewScale = pipelineContext->GetViewScale();
1775     auto offset = GetCoordinatePoint();
1776     int32_t localX = static_cast<int32_t>(info->GetX() - offset.value_or(OffsetF()).GetX()) * viewScale;
1777     int32_t localY = static_cast<int32_t>(info->GetY() - offset.value_or(OffsetF()).GetY()) * viewScale;
1778 
1779     RefPtr<UnifiedData> aceData = info->GetData();
1780     // get data from ace(from udmf), and send it to chromium
1781     if (aceData && aceData->GetSize() >= 1) {
1782         TAG_LOGI(AceLogTag::ACE_WEB,
1783             "DragDrop event WebEventHub onDragDropId, size:%{public}" PRId64 "", aceData->GetSize());
1784         CHECK_NULL_VOID(delegate_->dragData_);
1785         // plain text
1786         std::vector<std::string> plains = UdmfClient::GetInstance()->GetPlainTextRecords(aceData);
1787         if (!plains.empty() && !plains[0].empty()) {
1788             std::string plain = plains[0];
1789             delegate_->dragData_->SetFragmentText(plain);
1790             TAG_LOGI(AceLogTag::ACE_WEB,
1791                 "DragDrop event WebEventHub onDragDropId, plain size:%{public}zu", plain.size());
1792         }
1793         // html
1794         std::string htmlContent;
1795         std::string plainContent;
1796         UdmfClient::GetInstance()->GetHtmlRecord(aceData, htmlContent, plainContent);
1797         if (!htmlContent.empty()) {
1798             delegate_->dragData_->SetFragmentHtml(htmlContent);
1799             TAG_LOGI(AceLogTag::ACE_WEB,
1800                 "DragDrop event WebEventHub onDragDropId, htmlContent size:%{public}zu", htmlContent.size());
1801         }
1802         // spanstring
1803         std::vector<uint8_t> spanString = UdmfClient::GetInstance()->GetSpanStringRecord(aceData);
1804         if (!spanString.empty()) {
1805             std::string htmlStr = OHOS::Ace::SpanToHtml::ToHtml(spanString);
1806             delegate_->dragData_->SetFragmentHtml(htmlStr);
1807             TAG_LOGI(AceLogTag::ACE_WEB,
1808                 "DragDrop event WebEventHub onDragDropId, spanstring to html success, html size:%{public}zu",
1809                 htmlStr.size());
1810         }
1811         // link
1812         HandleOnDragDropLink(aceData);
1813         // file
1814         HandleOnDragDropFile(aceData);
1815     } else {
1816         TAG_LOGW(AceLogTag::ACE_WEB, "DragDrop event WebEventHub onDragDropId get data failed");
1817     }
1818 
1819     delegate_->HandleDragEvent(localX, localY, DragAction::DRAG_DROP);
1820 }
1821 
HandleOnDragLeave(int32_t x,int32_t y)1822 void WebPattern::HandleOnDragLeave(int32_t x, int32_t y)
1823 {
1824     CHECK_NULL_VOID(delegate_);
1825     isDragging_ = false;
1826     isW3cDragEvent_ = false;
1827     auto host = GetHost();
1828     CHECK_NULL_VOID(host);
1829     auto pipelineContext = host->GetContextRefPtr();
1830     CHECK_NULL_VOID(pipelineContext);
1831     auto viewScale = pipelineContext->GetViewScale();
1832     auto offset = GetCoordinatePoint();
1833     int32_t localX = static_cast<int32_t>(x - offset.value_or(OffsetF()).GetX());
1834     int32_t localY = static_cast<int32_t>(y - offset.value_or(OffsetF()).GetY());
1835     delegate_->HandleDragEvent(localX * viewScale, localY * viewScale, DragAction::DRAG_LEAVE);
1836 }
1837 
HandleDragEnd(int32_t x,int32_t y)1838 void WebPattern::HandleDragEnd(int32_t x, int32_t y)
1839 {
1840     CHECK_NULL_VOID(delegate_);
1841 
1842     isDragging_ = false;
1843     isReceivedArkDrag_ = false;
1844     isW3cDragEvent_ = false;
1845     ClearDragData();
1846 
1847     auto host = GetHost();
1848     CHECK_NULL_VOID(host);
1849     auto pipelineContext = host->GetContextRefPtr();
1850     CHECK_NULL_VOID(pipelineContext);
1851     auto viewScale = pipelineContext->GetViewScale();
1852     auto offset = GetCoordinatePoint();
1853     int32_t localX = static_cast<int32_t>(x - offset.value_or(OffsetF()).GetX()) * viewScale;
1854     int32_t localY = static_cast<int32_t>(y - offset.value_or(OffsetF()).GetY()) * viewScale;
1855     if (x == 0 && y == 0) {
1856         delegate_->HandleDragEvent(0, 0, DragAction::DRAG_END);
1857     } else {
1858         delegate_->HandleDragEvent(localX, localY, DragAction::DRAG_END);
1859     }
1860 }
1861 
HandleDragCancel()1862 void WebPattern::HandleDragCancel()
1863 {
1864     auto frameNode = GetHost();
1865     CHECK_NULL_VOID(frameNode);
1866     // disable drag
1867     frameNode->SetDraggable(false);
1868     CHECK_NULL_VOID(delegate_);
1869     isDragging_ = false;
1870     isReceivedArkDrag_ = false;
1871     isW3cDragEvent_ = false;
1872     ClearDragData();
1873     delegate_->HandleDragEvent(0, 0, DragAction::DRAG_CANCEL);
1874 }
1875 
ClearDragData()1876 void WebPattern::ClearDragData()
1877 {
1878     CHECK_NULL_VOID(delegate_);
1879     std::string plain = "";
1880     std::string htmlContent = "";
1881     std::string linkUrl = "";
1882     std::string linkTitle = "";
1883     if (delegate_->dragData_) {
1884         delegate_->dragData_->SetFragmentText(plain);
1885         delegate_->dragData_->SetFragmentHtml(htmlContent);
1886         delegate_->dragData_->SetLinkURL(linkUrl);
1887         delegate_->dragData_->SetLinkTitle(linkTitle);
1888     }
1889 }
1890 
InitFocusEvent(const RefPtr<FocusHub> & focusHub)1891 void WebPattern::InitFocusEvent(const RefPtr<FocusHub>& focusHub)
1892 {
1893     auto focusTask = [weak = WeakClaim(this)]() {
1894         auto pattern = weak.Upgrade();
1895         CHECK_NULL_VOID(pattern);
1896         pattern->HandleFocusEvent();
1897     };
1898     focusHub->SetOnFocusInternal(focusTask);
1899 
1900     auto blurTask = [weak = WeakClaim(this)](const BlurReason& blurReason) {
1901         auto pattern = weak.Upgrade();
1902         CHECK_NULL_VOID(pattern);
1903         pattern->HandleBlurEvent(blurReason);
1904     };
1905     focusHub->SetOnBlurReasonInternal(blurTask);
1906 
1907     auto keyTask = [weak = WeakClaim(this)](const KeyEvent& keyEvent) -> bool {
1908         auto pattern = weak.Upgrade();
1909         CHECK_NULL_RETURN(pattern, false);
1910         return pattern->HandleKeyEvent(keyEvent);
1911     };
1912     focusHub->SetOnKeyEventInternal(keyTask);
1913 }
1914 
HandleFocusEvent()1915 void WebPattern::HandleFocusEvent()
1916 {
1917     TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::HandleFocusEvent webId:%{public}d, needOnFocus: %{public}d.", GetWebId(),
1918         needOnFocus_);
1919     CHECK_NULL_VOID(delegate_);
1920     isFocus_ = true;
1921     if (needOnFocus_) {
1922         delegate_->OnFocus();
1923     } else {
1924         delegate_->OnFocus(OHOS::NWeb::FocusReason::FOCUS_DEFAULT);
1925         needOnFocus_ = true;
1926     }
1927 }
1928 
HandleBlurEvent(const BlurReason & blurReason)1929 void WebPattern::HandleBlurEvent(const BlurReason& blurReason)
1930 {
1931     TAG_LOGI(AceLogTag::ACE_WEB,
1932         "HandleBlurEvent webId:%{public}d, selectPopupMenuShowing: %{public}d, isReceivedArkDrag: %{public}d",
1933         GetWebId(), selectPopupMenuShowing_, isReceivedArkDrag_);
1934     CHECK_NULL_VOID(delegate_);
1935     isFocus_ = false;
1936 
1937     if (isReceivedArkDrag_) {
1938         return;
1939     }
1940     if (!selectPopupMenuShowing_) {
1941         delegate_->SetBlurReason(static_cast<OHOS::NWeb::BlurReason>(blurReason));
1942         delegate_->OnBlur();
1943     }
1944     OnQuickMenuDismissed();
1945     CloseContextSelectionMenu();
1946     if (!isVisible_ && isActive_ && IsDialogNested()) {
1947         TAG_LOGI(AceLogTag::ACE_WEB, "HandleBlurEvent, dialog nested blur but invisible while active, set inactive.");
1948         OnInActive();
1949     }
1950     HideMagnifier();
1951 }
1952 
HandleKeyEvent(const KeyEvent & keyEvent)1953 bool WebPattern::HandleKeyEvent(const KeyEvent& keyEvent)
1954 {
1955     bool ret = false;
1956 
1957     auto host = GetHost();
1958     CHECK_NULL_RETURN(host, ret);
1959     auto eventHub = host->GetEventHub<WebEventHub>();
1960     CHECK_NULL_RETURN(eventHub, ret);
1961 
1962     KeyEventInfo info(keyEvent);
1963     auto keyEventCallback = eventHub->GetOnKeyEvent();
1964     if (keyEventCallback) {
1965         keyEventCallback(info);
1966     }
1967 
1968     auto preKeyEventCallback = eventHub->GetOnPreKeyEvent();
1969     if (preKeyEventCallback) {
1970         ret = preKeyEventCallback(info);
1971         if (ret) {
1972             return ret;
1973         }
1974     }
1975 
1976     ret = WebOnKeyEvent(keyEvent);
1977     return ret;
1978 }
1979 
ClearKeyEventByKeyCode(int32_t keyCode)1980 void WebPattern::ClearKeyEventByKeyCode(int32_t keyCode)
1981 {
1982     auto keyEvent = webKeyEvent_.begin();
1983     for (; keyEvent != webKeyEvent_.end();) {
1984         if (static_cast<int32_t>(keyEvent->code) == keyCode) {
1985             keyEvent = webKeyEvent_.erase(keyEvent);
1986         } else {
1987             ++keyEvent;
1988         }
1989     }
1990 
1991     if (webKeyEvent_.size() >= KEYEVENT_MAX_NUM) {
1992         webKeyEvent_.clear();
1993         TAG_LOGW(AceLogTag::ACE_WEB,
1994             "WebPattern::ClearKeyEventByKeyCode clear all keyevent.");
1995     } else {
1996         TAG_LOGW(AceLogTag::ACE_WEB,
1997             "WebPattern::ClearKeyEventByKeyCode clear all tab keyevent.");
1998     }
1999 }
2000 
WebOnKeyEvent(const KeyEvent & keyEvent)2001 bool WebPattern::WebOnKeyEvent(const KeyEvent& keyEvent)
2002 {
2003     CHECK_NULL_RETURN(delegate_, false);
2004     if (webKeyEvent_.size() >= KEYEVENT_MAX_NUM) {
2005         ClearKeyEventByKeyCode(static_cast<int32_t>(KeyCode::KEY_TAB));
2006     }
2007     TAG_LOGD(AceLogTag::ACE_WEB,
2008         "WebPattern::WebOnKeyEvent keyEvent:%{public}s", keyEvent.ToString().c_str());
2009     webKeyEvent_.push_back(keyEvent);
2010     std::vector<int32_t> pressedCodes;
2011     for (auto pCode : keyEvent.pressedCodes) {
2012         pressedCodes.push_back(static_cast<int32_t>(pCode));
2013     }
2014     return delegate_->WebOnKeyEvent(static_cast<int32_t>(keyEvent.code),
2015         static_cast<int32_t>(keyEvent.action), pressedCodes);
2016 }
2017 
KeyboardReDispatch(const std::shared_ptr<OHOS::NWeb::NWebKeyEvent> & event,bool isUsed)2018 void WebPattern::KeyboardReDispatch(
2019     const std::shared_ptr<OHOS::NWeb::NWebKeyEvent>& event, bool isUsed)
2020 {
2021     CHECK_NULL_VOID(event);
2022     auto container = Container::Current();
2023     CHECK_NULL_VOID(container);
2024     auto host = GetHost();
2025     CHECK_NULL_VOID(host);
2026     auto pipelineContext = host->GetContext();
2027     CHECK_NULL_VOID(pipelineContext);
2028     auto taskExecutor = pipelineContext->GetTaskExecutor();
2029     CHECK_NULL_VOID(taskExecutor);
2030     auto keyEvent = webKeyEvent_.rbegin();
2031     for (; keyEvent != webKeyEvent_.rend(); ++keyEvent) {
2032         if (static_cast<int32_t>(keyEvent->code) == event->GetKeyCode() &&
2033             static_cast<int32_t>(keyEvent->action) == event->GetAction()) {
2034             break;
2035         }
2036     }
2037     if (keyEvent == webKeyEvent_.rend()) {
2038         TAG_LOGW(AceLogTag::ACE_WEB,
2039             "KeyEvent is not find keycode:%{public}d, action:%{public}d", event->GetKeyCode(), event->GetAction());
2040         return;
2041     }
2042     if (!isUsed) {
2043         taskExecutor->PostTask([context = AceType::WeakClaim(pipelineContext),
2044             event = *keyEvent] () {
2045             auto pipelineContext = context.Upgrade();
2046             CHECK_NULL_VOID(pipelineContext);
2047             TAG_LOGD(AceLogTag::ACE_WEB,
2048                 "WebPattern::KeyboardReDispatch key:%{public}s", event.ToString().c_str());
2049             pipelineContext->ReDispatch(const_cast<KeyEvent&>(event));
2050             },
2051             TaskExecutor::TaskType::UI, "ArkUIWebKeyboardReDispatch");
2052     }
2053     TAG_LOGD(AceLogTag::ACE_WEB,
2054         "WebPattern::KeyboardReDispatch erase key:%{public}s", keyEvent->ToString().c_str());
2055     webKeyEvent_.erase((++keyEvent).base());
2056 }
2057 
WebRequestFocus()2058 void WebPattern::WebRequestFocus()
2059 {
2060     auto host = GetHost();
2061     CHECK_NULL_VOID(host);
2062     auto eventHub = host->GetEventHub<WebEventHub>();
2063     CHECK_NULL_VOID(eventHub);
2064     auto focusHub = eventHub->GetOrCreateFocusHub();
2065     CHECK_NULL_VOID(focusHub);
2066 
2067     focusHub->RequestFocusImmediately();
2068 }
2069 
UpdateContentOffset(const RefPtr<LayoutWrapper> & dirty)2070 void WebPattern::UpdateContentOffset(const RefPtr<LayoutWrapper>& dirty)
2071 {
2072     CHECK_NULL_VOID(dirty);
2073     auto geometryNode = dirty->GetGeometryNode();
2074     CHECK_NULL_VOID(geometryNode);
2075     auto host = GetHost();
2076     CHECK_NULL_VOID(host);
2077     auto renderContext = host->GetRenderContext();
2078     CHECK_NULL_VOID(renderContext);
2079     auto paddingOffset = geometryNode->GetPaddingOffset();
2080     auto webContentSize = geometryNode->GetContentSize();
2081 
2082     auto positionProperty = renderContext->GetPropertyOfPosition();
2083     renderContext->SetBounds(
2084         paddingOffset.GetX() +  positionProperty.GetX(), paddingOffset.GetY() + positionProperty.GetY(),
2085         webContentSize.Width(), webContentSize.Height());
2086 }
2087 
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)2088 bool WebPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)
2089 {
2090     UpdateImagePreviewParam();
2091     if (!config.contentSizeChange || isInWindowDrag_) {
2092         if (isLayoutModeChanged_) {
2093             isLayoutModeChanged_ = false;
2094         } else {
2095             return false;
2096         }
2097     }
2098     CHECK_NULL_RETURN(delegate_, false);
2099     CHECK_NULL_RETURN(dirty, false);
2100 
2101     Size drawSize = Size(1, 1);
2102     auto frameNode = GetHost();
2103     CHECK_NULL_RETURN(frameNode, false);
2104     auto renderContext = frameNode->GetRenderContext();
2105     CHECK_NULL_RETURN(renderContext, false);
2106     auto rect = renderContext->GetPaintRectWithoutTransform();
2107     drawSize = Size(rect.Width(), rect.Height());
2108     if (drawSize.IsInfinite() || drawSize.IsEmpty()) {
2109         return false;
2110     }
2111 
2112     if (GreatOrEqual(drawSize.Width(), Infinity<double>())) {
2113         drawSize.SetWidth(DEFAULT_WEB_WIDTH);
2114     }
2115     if (GreatOrEqual(drawSize.Height(), Infinity<double>())) {
2116         drawSize.SetHeight(DEFAULT_WEB_HEIGHT);
2117     }
2118 
2119     drawSize_ = drawSize;
2120     drawSizeCache_ = drawSize_;
2121     auto offset = Offset(GetCoordinatePoint()->GetX(), GetCoordinatePoint()->GetY());
2122 
2123     if (!CheckSafeAreaIsExpand()) {
2124         TAG_LOGD(AceLogTag::ACE_WEB, "Not safe area, drawsize_ : %{public}s", drawSize_.ToString().c_str());
2125         delegate_->SetBoundsOrResize(drawSize_, offset, isKeyboardInSafeArea_);
2126         IsNeedResizeVisibleViewport();
2127         isKeyboardInSafeArea_ = false;
2128     } else {
2129         TAG_LOGD(AceLogTag::ACE_WEB, "OnDirtyLayoutWrapperSwap safeArea ins not set, no need setbouns");
2130     }
2131 
2132     if (offlineWebInited_ && !offlineWebRendered_) {
2133         TAG_LOGI(AceLogTag::ACE_WEB,
2134             "OnDirtyLayoutWrapperSwap; WebPattern is Offline Mode, WebId:%{public}d", GetWebId());
2135         offlineWebRendered_ = true;
2136         delegate_->ShowWebView();
2137     }
2138     // first update size to load url.
2139     if (!isUrlLoaded_) {
2140         isUrlLoaded_ = true;
2141         if (webSrc_) {
2142             delegate_->LoadUrl();
2143         } else if (webData_) {
2144             delegate_->LoadDataWithRichText();
2145         }
2146     }
2147     return false;
2148 }
2149 
BeforeSyncGeometryProperties(const DirtySwapConfig & config)2150 void WebPattern::BeforeSyncGeometryProperties(const DirtySwapConfig& config)
2151 {
2152     if (!config.contentSizeChange || isInWindowDrag_) {
2153         return;
2154     }
2155     auto frameNode = GetHost();
2156     CHECK_NULL_VOID(frameNode);
2157     auto renderContext = frameNode->GetRenderContext();
2158     CHECK_NULL_VOID(renderContext);
2159     auto rect = renderContext->GetPaintRectWithoutTransform();
2160     auto drawSize = Size(rect.Width(), rect.Height());
2161     if (drawSize.IsInfinite() || drawSize.IsEmpty()) {
2162         return;
2163     }
2164 
2165     if (GreatOrEqual(drawSize.Width(), Infinity<double>())) {
2166         drawSize.SetWidth(DEFAULT_WEB_WIDTH);
2167     }
2168     if (GreatOrEqual(drawSize.Height(), Infinity<double>())) {
2169         drawSize.SetHeight(DEFAULT_WEB_HEIGHT);
2170     }
2171 
2172     if (layoutMode_ != WebLayoutMode::FIT_CONTENT) {
2173         drawSize_ = drawSize;
2174         drawSizeCache_ = drawSize_;
2175     }
2176 
2177     TAG_LOGD(AceLogTag::ACE_WEB, "BeforeSync, drawsize_ : %{public}s", drawSize.ToString().c_str());
2178 }
2179 
UpdateLayoutAfterKeyboardShow(int32_t width,int32_t height,double keyboard,double oldWebHeight)2180 void WebPattern::UpdateLayoutAfterKeyboardShow(int32_t width, int32_t height, double keyboard, double oldWebHeight)
2181 {
2182     lastKeyboardHeight_ = keyboard;
2183     if (isVirtualKeyBoardShow_ != VkState::VK_SHOW) {
2184         return;
2185     }
2186 
2187     TAG_LOGI(AceLogTag::ACE_WEB,
2188         "KeyboardShow height:%{public}d, keyboard:%{public}f, offset:%{public}f, oldWebHeight:%{public}f",
2189         height, keyboard, GetCoordinatePoint()->GetY(), oldWebHeight);
2190     if (CheckSafeAreaKeyBoard()) {
2191         TAG_LOGI(AceLogTag::ACE_WEB, "CheckSafeAreaKeyBoard, no need resize");
2192         return;
2193     }
2194     if (GreatOrEqual(height, keyboard + GetCoordinatePoint()->GetY())) {
2195         double newHeight = height - keyboard - GetCoordinatePoint()->GetY();
2196         if (NearEqual(newHeight, oldWebHeight)) {
2197             return;
2198         }
2199         bool isUpdate = true;
2200         if (keyBoardAvoidMode_ == WebKeyboardAvoidMode::RESIZE_VISUAL) {
2201             visibleViewportSize_.SetWidth(drawSize_.Width());
2202             visibleViewportSize_.SetHeight(newHeight);
2203             isUpdate = false;
2204         } else if (keyBoardAvoidMode_ == WebKeyboardAvoidMode::OVERLAYS_CONTENT) {
2205             return;
2206         } else {
2207             TAG_LOGI(AceLogTag::ACE_WEB, "KeyboardShow newHeight: %{public}f", newHeight);
2208             drawSize_.SetHeight(newHeight);
2209             visibleViewportSize_.SetWidth(-1.0);
2210             visibleViewportSize_.SetHeight(-1.0);
2211         }
2212         UpdateWebLayoutSize(width, height, true, isUpdate);
2213     }
2214 }
2215 
OnAreaChangedInner()2216 void WebPattern::OnAreaChangedInner()
2217 {
2218     auto offset = GetCoordinatePoint().value_or(OffsetF());
2219     auto resizeOffset = Offset(offset.GetX(), offset.GetY());
2220 
2221     auto frameNode = GetHost();
2222     CHECK_NULL_VOID(frameNode);
2223     auto renderContext = frameNode->GetRenderContext();
2224     CHECK_NULL_VOID(renderContext);
2225 
2226     auto geometryNode = frameNode->GetGeometryNode();
2227     CHECK_NULL_VOID(geometryNode);
2228     auto rect = renderContext->GetPaintRectWithoutTransform();
2229     auto size = Size(rect.Width(), rect.Height());
2230     delegate_->OnAreaChange({ resizeOffset.GetX(), resizeOffset.GetY(), size.Width(), size.Height() });
2231     if (CheckSafeAreaIsExpand() &&
2232         ((size.Width() != areaChangeSize_.Width()) || (size.Height() != areaChangeSize_.Height()))) {
2233         TAG_LOGD(AceLogTag::ACE_WEB, "OnAreaChangedInner setbounds: height:%{public}f, offsetY:%{public}f",
2234             size.Height(), resizeOffset.GetY());
2235         areaChangeSize_ = size;
2236         drawSize_ = size;
2237         drawSizeCache_ = drawSize_;
2238         TAG_LOGD(AceLogTag::ACE_WEB, "Safe area, drawsize_ : %{public}s", drawSize_.ToString().c_str());
2239         delegate_->SetBoundsOrResize(drawSize_, resizeOffset, isKeyboardInSafeArea_);
2240         IsNeedResizeVisibleViewport();
2241         isKeyboardInSafeArea_ = false;
2242     }
2243     if (layoutMode_ == WebLayoutMode::NONE && renderMode_ == RenderMode::ASYNC_RENDER) {
2244         drawSize_ = size;
2245         if (webOffset_ == offset) {
2246             return;
2247         }
2248     }
2249     if (offset != webOffset_) {
2250         webOffset_ = offset;
2251         UpdateTouchHandleForOverlay();
2252     }
2253     if (isInWindowDrag_)
2254         return;
2255     TAG_LOGD(AceLogTag::ACE_WEB, "Normal state, drawsize_ : %{public}s", drawSize_.ToString().c_str());
2256     delegate_->SetBoundsOrResize(drawSize_, resizeOffset, isKeyboardInSafeArea_);
2257     IsNeedResizeVisibleViewport();
2258     isKeyboardInSafeArea_ = false;
2259     if (renderMode_ == RenderMode::SYNC_RENDER) {
2260         UpdateSlideOffset();
2261     }
2262 }
2263 
OnWebSrcUpdate()2264 void WebPattern::OnWebSrcUpdate()
2265 {
2266     if (delegate_ && isUrlLoaded_) {
2267         delegate_->LoadUrl();
2268     }
2269 }
2270 
OnWebDataUpdate()2271 void WebPattern::OnWebDataUpdate()
2272 {
2273     if (delegate_ && isUrlLoaded_) {
2274         delegate_->LoadDataWithRichText();
2275     }
2276 }
2277 
OnJsEnabledUpdate(bool value)2278 void WebPattern::OnJsEnabledUpdate(bool value)
2279 {
2280     if (delegate_) {
2281         delegate_->UpdateJavaScriptEnabled(value);
2282     }
2283 }
2284 
OnMediaPlayGestureAccessUpdate(bool value)2285 void WebPattern::OnMediaPlayGestureAccessUpdate(bool value)
2286 {
2287     if (delegate_) {
2288         delegate_->UpdateMediaPlayGestureAccess(value);
2289     }
2290 }
2291 
OnFileAccessEnabledUpdate(bool value)2292 void WebPattern::OnFileAccessEnabledUpdate(bool value)
2293 {
2294     if (delegate_) {
2295         delegate_->UpdateAllowFileAccess(value);
2296     }
2297 }
2298 
OnOnLineImageAccessEnabledUpdate(bool value)2299 void WebPattern::OnOnLineImageAccessEnabledUpdate(bool value)
2300 {
2301     if (delegate_) {
2302         delegate_->UpdateBlockNetworkImage(!value);
2303     }
2304 }
2305 
OnDomStorageAccessEnabledUpdate(bool value)2306 void WebPattern::OnDomStorageAccessEnabledUpdate(bool value)
2307 {
2308     if (delegate_) {
2309         delegate_->UpdateDomStorageEnabled(value);
2310     }
2311 }
2312 
OnImageAccessEnabledUpdate(bool value)2313 void WebPattern::OnImageAccessEnabledUpdate(bool value)
2314 {
2315     if (delegate_) {
2316         delegate_->UpdateLoadsImagesAutomatically(value);
2317     }
2318 }
2319 
OnMixedModeUpdate(MixedModeContent value)2320 void WebPattern::OnMixedModeUpdate(MixedModeContent value)
2321 {
2322     if (delegate_) {
2323         delegate_->UpdateMixedContentMode(value);
2324     }
2325 }
2326 
OnZoomAccessEnabledUpdate(bool value)2327 void WebPattern::OnZoomAccessEnabledUpdate(bool value)
2328 {
2329     if ((layoutMode_ == WebLayoutMode::FIT_CONTENT) || isEmbedModeEnabled_) {
2330         TAG_LOGI(AceLogTag::ACE_WEB, "When layoutMode is fit-content or EmbedMode is on, turn off zoom access.");
2331         value = false;
2332     }
2333     if (delegate_) {
2334         delegate_->UpdateSupportZoom(value);
2335     }
2336 }
2337 
OnGeolocationAccessEnabledUpdate(bool value)2338 void WebPattern::OnGeolocationAccessEnabledUpdate(bool value)
2339 {
2340     if (delegate_) {
2341         delegate_->UpdateGeolocationEnabled(value);
2342     }
2343 }
2344 
OnUserAgentUpdate(const std::string & value)2345 void WebPattern::OnUserAgentUpdate(const std::string& value)
2346 {
2347     if (delegate_) {
2348         delegate_->UpdateUserAgent(value);
2349     }
2350 }
2351 
OnCacheModeUpdate(WebCacheMode value)2352 void WebPattern::OnCacheModeUpdate(WebCacheMode value)
2353 {
2354     if (delegate_) {
2355         delegate_->UpdateCacheMode(value);
2356     }
2357 }
2358 
OnDarkModeUpdate(WebDarkMode mode)2359 void WebPattern::OnDarkModeUpdate(WebDarkMode mode)
2360 {
2361     if (delegate_) {
2362         delegate_->UpdateDarkMode(mode);
2363     }
2364 }
2365 
OnOverScrollModeUpdate(int mode)2366 void WebPattern::OnOverScrollModeUpdate(int mode)
2367 {
2368     if (delegate_) {
2369         delegate_->UpdateOverScrollMode(mode);
2370     }
2371 }
2372 
OnCopyOptionModeUpdate(int32_t mode)2373 void WebPattern::OnCopyOptionModeUpdate(int32_t mode)
2374 {
2375     if (delegate_) {
2376         delegate_->UpdateCopyOptionMode(mode);
2377     }
2378 }
2379 
OnMetaViewportUpdate(bool value)2380 void WebPattern::OnMetaViewportUpdate(bool value)
2381 {
2382     if (delegate_) {
2383         delegate_->UpdateMetaViewport(value);
2384     }
2385 }
2386 
OnForceDarkAccessUpdate(bool access)2387 void WebPattern::OnForceDarkAccessUpdate(bool access)
2388 {
2389     if (delegate_) {
2390         delegate_->UpdateForceDarkAccess(access);
2391     }
2392 }
2393 
OnAudioResumeIntervalUpdate(int32_t resumeInterval)2394 void WebPattern::OnAudioResumeIntervalUpdate(int32_t resumeInterval)
2395 {
2396     if (delegate_) {
2397         delegate_->UpdateAudioResumeInterval(resumeInterval);
2398     }
2399 }
2400 
OnAudioExclusiveUpdate(bool audioExclusive)2401 void WebPattern::OnAudioExclusiveUpdate(bool audioExclusive)
2402 {
2403     if (delegate_) {
2404         delegate_->UpdateAudioExclusive(audioExclusive);
2405     }
2406 }
2407 
OnOverviewModeAccessEnabledUpdate(bool value)2408 void WebPattern::OnOverviewModeAccessEnabledUpdate(bool value)
2409 {
2410     if (delegate_) {
2411         delegate_->UpdateOverviewModeEnabled(value);
2412     }
2413 }
2414 
OnFileFromUrlAccessEnabledUpdate(bool value)2415 void WebPattern::OnFileFromUrlAccessEnabledUpdate(bool value)
2416 {
2417     if (delegate_) {
2418         delegate_->UpdateFileFromUrlEnabled(value);
2419     }
2420 }
2421 
OnDatabaseAccessEnabledUpdate(bool value)2422 void WebPattern::OnDatabaseAccessEnabledUpdate(bool value)
2423 {
2424     if (delegate_) {
2425         delegate_->UpdateDatabaseEnabled(value);
2426     }
2427 }
2428 
OnTextZoomRatioUpdate(int32_t value)2429 void WebPattern::OnTextZoomRatioUpdate(int32_t value)
2430 {
2431     if (delegate_) {
2432         delegate_->UpdateTextZoomRatio(value);
2433     }
2434 }
2435 
OnWebDebuggingAccessEnabledUpdate(bool value)2436 void WebPattern::OnWebDebuggingAccessEnabledUpdate(bool value)
2437 {
2438     if (delegate_) {
2439         delegate_->UpdateWebDebuggingAccess(value);
2440     }
2441 }
2442 
OnPinchSmoothModeEnabledUpdate(bool value)2443 void WebPattern::OnPinchSmoothModeEnabledUpdate(bool value)
2444 {
2445     if (delegate_) {
2446         delegate_->UpdatePinchSmoothModeEnabled(value);
2447     }
2448 }
2449 
OnBackgroundColorUpdate(int32_t value)2450 void WebPattern::OnBackgroundColorUpdate(int32_t value)
2451 {
2452     UpdateBackgroundColorRightNow(value);
2453     if (delegate_) {
2454         delegate_->UpdateBackgroundColor(value);
2455     }
2456 }
2457 
OnInitialScaleUpdate(float value)2458 void WebPattern::OnInitialScaleUpdate(float value)
2459 {
2460     if ((layoutMode_ == WebLayoutMode::FIT_CONTENT) || isEmbedModeEnabled_) {
2461         TAG_LOGI(AceLogTag::ACE_WEB, "When layoutMode is fit-content or EmbedMode is on, Not allow to update scale.");
2462         return;
2463     }
2464     if (delegate_) {
2465         delegate_->UpdateInitialScale(value);
2466     }
2467 }
2468 
OnMultiWindowAccessEnabledUpdate(bool value)2469 void WebPattern::OnMultiWindowAccessEnabledUpdate(bool value)
2470 {
2471     if (delegate_) {
2472         delegate_->UpdateMultiWindowAccess(value);
2473     }
2474 }
2475 
OnAllowWindowOpenMethodUpdate(bool value)2476 void WebPattern::OnAllowWindowOpenMethodUpdate(bool value)
2477 {
2478     if (delegate_) {
2479         delegate_->UpdateAllowWindowOpenMethod(value);
2480     }
2481 }
2482 
OnWebCursiveFontUpdate(const std::string & value)2483 void WebPattern::OnWebCursiveFontUpdate(const std::string& value)
2484 {
2485     if (delegate_) {
2486         delegate_->UpdateWebCursiveFont(value);
2487     }
2488 }
2489 
OnWebFantasyFontUpdate(const std::string & value)2490 void WebPattern::OnWebFantasyFontUpdate(const std::string& value)
2491 {
2492     if (delegate_) {
2493         delegate_->UpdateWebFantasyFont(value);
2494     }
2495 }
2496 
OnWebFixedFontUpdate(const std::string & value)2497 void WebPattern::OnWebFixedFontUpdate(const std::string& value)
2498 {
2499     if (delegate_) {
2500         delegate_->UpdateWebFixedFont(value);
2501     }
2502 }
2503 
OnWebSansSerifFontUpdate(const std::string & value)2504 void WebPattern::OnWebSansSerifFontUpdate(const std::string& value)
2505 {
2506     if (delegate_) {
2507         delegate_->UpdateWebSansSerifFont(value);
2508     }
2509 }
2510 
OnWebSerifFontUpdate(const std::string & value)2511 void WebPattern::OnWebSerifFontUpdate(const std::string& value)
2512 {
2513     if (delegate_) {
2514         delegate_->UpdateWebSerifFont(value);
2515     }
2516 }
2517 
OnWebStandardFontUpdate(const std::string & value)2518 void WebPattern::OnWebStandardFontUpdate(const std::string& value)
2519 {
2520     if (delegate_) {
2521         delegate_->UpdateWebStandardFont(value);
2522     }
2523 }
2524 
OnDefaultFixedFontSizeUpdate(int32_t value)2525 void WebPattern::OnDefaultFixedFontSizeUpdate(int32_t value)
2526 {
2527     if (delegate_) {
2528         delegate_->UpdateDefaultFixedFontSize(value);
2529     }
2530 }
2531 
OnDefaultFontSizeUpdate(int32_t value)2532 void WebPattern::OnDefaultFontSizeUpdate(int32_t value)
2533 {
2534     if (delegate_) {
2535         delegate_->UpdateDefaultFontSize(value);
2536     }
2537 }
2538 
OnMinFontSizeUpdate(int32_t value)2539 void WebPattern::OnMinFontSizeUpdate(int32_t value)
2540 {
2541     if (delegate_) {
2542         delegate_->UpdateMinFontSize(value);
2543     }
2544 }
2545 
OnMinLogicalFontSizeUpdate(int32_t value)2546 void WebPattern::OnMinLogicalFontSizeUpdate(int32_t value)
2547 {
2548     if (delegate_) {
2549         delegate_->UpdateMinLogicalFontSize(value);
2550     }
2551 }
2552 
OnBlockNetworkUpdate(bool value)2553 void WebPattern::OnBlockNetworkUpdate(bool value)
2554 {
2555     if (delegate_) {
2556         delegate_->UpdateBlockNetwork(value);
2557     }
2558 }
2559 
OnHorizontalScrollBarAccessEnabledUpdate(bool value)2560 void WebPattern::OnHorizontalScrollBarAccessEnabledUpdate(bool value)
2561 {
2562     if (delegate_) {
2563         delegate_->UpdateHorizontalScrollBarAccess(value);
2564     }
2565 }
2566 
OnVerticalScrollBarAccessEnabledUpdate(bool value)2567 void WebPattern::OnVerticalScrollBarAccessEnabledUpdate(bool value)
2568 {
2569     if (delegate_) {
2570         delegate_->UpdateVerticalScrollBarAccess(value);
2571     }
2572 }
2573 
OnOverlayScrollbarEnabledUpdate(bool enable)2574 void WebPattern::OnOverlayScrollbarEnabledUpdate(bool enable)
2575 {
2576     if (delegate_) {
2577         delegate_->UpdateOverlayScrollbarEnabled(enable);
2578     }
2579 }
2580 
OnNativeEmbedModeEnabledUpdate(bool value)2581 void WebPattern::OnNativeEmbedModeEnabledUpdate(bool value)
2582 {
2583     if (delegate_) {
2584         delegate_->UpdateNativeEmbedModeEnabled(value);
2585     }
2586 }
2587 
OnNativeEmbedRuleTagUpdate(const std::string & tag)2588 void WebPattern::OnNativeEmbedRuleTagUpdate(const std::string& tag)
2589 {
2590     if (delegate_) {
2591         delegate_->UpdateNativeEmbedRuleTag(tag);
2592     }
2593 }
2594 
OnNativeEmbedRuleTypeUpdate(const std::string & type)2595 void WebPattern::OnNativeEmbedRuleTypeUpdate(const std::string& type)
2596 {
2597     if (delegate_) {
2598         delegate_->UpdateNativeEmbedRuleType(type);
2599     }
2600 }
2601 
OnTextAutosizingUpdate(bool isTextAutosizing)2602 void WebPattern::OnTextAutosizingUpdate(bool isTextAutosizing)
2603 {
2604     if (delegate_) {
2605         delegate_->UpdateTextAutosizing(isTextAutosizing);
2606     }
2607 }
2608 
OnKeyboardAvoidModeUpdate(const WebKeyboardAvoidMode & mode)2609 void WebPattern::OnKeyboardAvoidModeUpdate(const WebKeyboardAvoidMode& mode)
2610 {
2611     keyBoardAvoidMode_ = mode;
2612 }
2613 
OnEnabledHapticFeedbackUpdate(bool enable)2614 void WebPattern::OnEnabledHapticFeedbackUpdate(bool enable)
2615 {
2616     isEnabledHapticFeedback_ = enable;
2617 }
2618 
IsRootNeedExportTexture()2619 bool WebPattern::IsRootNeedExportTexture()
2620 {
2621     auto host = GetHost();
2622     CHECK_NULL_RETURN(host, false);
2623     bool isNeedExportTexture = false;
2624     for (auto parent = host->GetParent(); parent != nullptr; parent = parent->GetParent()) {
2625         RefPtr<FrameNode> frameNode = AceType::DynamicCast<FrameNode>(parent);
2626         if (!frameNode) {
2627             continue;
2628         }
2629         isNeedExportTexture = frameNode->IsNeedExportTexture();
2630         if (isNeedExportTexture) {
2631             return isNeedExportTexture;
2632         }
2633     }
2634     return isNeedExportTexture;
2635 }
2636 
OnAttachContext(PipelineContext * context)2637 void WebPattern::OnAttachContext(PipelineContext *context)
2638 {
2639     nodeAttach_ = true;
2640     auto pipelineContext = Claim(context);
2641     int32_t newId = pipelineContext->GetInstanceId();
2642     instanceId_ = newId;
2643     if (delegate_) {
2644         delegate_->OnAttachContext(pipelineContext);
2645     }
2646 
2647     if (observer_) {
2648         observer_->OnAttachContext(pipelineContext);
2649     }
2650 
2651     if (updateInstanceIdCallback_) {
2652         updateInstanceIdCallback_(newId);
2653     }
2654 
2655     if (renderSurface_) {
2656         renderSurface_->SetInstanceId(newId);
2657     }
2658 
2659     auto host = GetHost();
2660     CHECK_NULL_VOID(host);
2661     int32_t nodeId = host->GetId();
2662     auto dragDropManager = pipelineContext->GetDragDropManager();
2663     if (dragDropManager) {
2664         dragDropManager->AddDragFrameNode(host->GetId(), AceType::WeakClaim(AceType::RawPtr(host)));
2665     }
2666 
2667     pipelineContext->AddWindowStateChangedCallback(nodeId);
2668     pipelineContext->AddWindowSizeChangeCallback(nodeId);
2669     pipelineContext->AddOnAreaChangeNode(nodeId);
2670     RegisterVisibleAreaChangeCallback(pipelineContext);
2671     needUpdateWeb_ = true;
2672     RegistVirtualKeyBoardListener(pipelineContext);
2673     InitConfigChangeCallback(pipelineContext);
2674     InitializeAccessibility();
2675 }
2676 
OnDetachContext(PipelineContext * contextPtr)2677 void WebPattern::OnDetachContext(PipelineContext *contextPtr)
2678 {
2679     nodeAttach_ = false;
2680     auto context = AceType::Claim(contextPtr);
2681     CHECK_NULL_VOID(context);
2682 
2683     auto host = GetHost();
2684     int32_t nodeId = host->GetId();
2685     UninitializeAccessibility();
2686     context->RemoveWindowStateChangedCallback(nodeId);
2687     context->RemoveWindowSizeChangeCallback(nodeId);
2688     context->RemoveOnAreaChangeNode(nodeId);
2689     context->RemoveVisibleAreaChangeNode(nodeId);
2690     context->RemoveVirtualKeyBoardCallback(nodeId);
2691     context->RemoveConfigChangedCallback(nodeId);
2692 
2693     if (delegate_) {
2694         delegate_->OnDetachContext();
2695     }
2696 
2697     if (observer_) {
2698         observer_->OnDetachContext();
2699     }
2700 
2701     auto dragDropManager = context->GetDragDropManager();
2702     if (dragDropManager) {
2703         dragDropManager->RemoveDragFrameNode(nodeId);
2704     }
2705 
2706     scrollableParentInfo_.hasParent = true;
2707     scrollableParentInfo_.parentIds.clear();
2708     if (selectOverlayProxy_) {
2709         StopListenSelectOverlayParentScroll(host);
2710         auto selectOverlayManager = context->GetSelectOverlayManager();
2711         if (selectOverlayManager) {
2712             selectOverlayManager->DestroySelectOverlay(selectOverlayProxy_);
2713         }
2714         selectOverlayProxy_ = nullptr;
2715     }
2716 
2717     if (tooltipId_ != -1) {
2718         auto overlayManager = context->GetOverlayManager();
2719         if (overlayManager) {
2720             overlayManager->RemoveIndexerPopupById(tooltipId_);
2721             TAG_LOGI(AceLogTag::ACE_WEB,
2722                 "OnDetachContext tooltipId_:%{public}d", tooltipId_);
2723         }
2724         tooltipId_ = -1;
2725     }
2726 }
2727 
SetUpdateInstanceIdCallback(std::function<void (int32_t)> && callback)2728 void WebPattern::SetUpdateInstanceIdCallback(std::function<void(int32_t)>&& callback)
2729 {
2730     updateInstanceIdCallback_ = callback;
2731 }
2732 
OnScrollBarColorUpdate(const std::string & value)2733 void WebPattern::OnScrollBarColorUpdate(const std::string& value)
2734 {
2735     if (delegate_) {
2736         delegate_->UpdateScrollBarColor(value);
2737     }
2738 }
2739 
OnDefaultTextEncodingFormatUpdate(const std::string & value)2740 void WebPattern::OnDefaultTextEncodingFormatUpdate(const std::string& value)
2741 {
2742     if (delegate_) {
2743         delegate_->UpdateDefaultTextEncodingFormat(value);
2744     }
2745 }
2746 
OnNativeVideoPlayerConfigUpdate(const std::tuple<bool,bool> & config)2747 void WebPattern::OnNativeVideoPlayerConfigUpdate(const std::tuple<bool, bool>& config)
2748 {
2749     if (delegate_) {
2750         delegate_->UpdateNativeVideoPlayerConfig(
2751             std::get<0>(config), std::get<1>(config));
2752     }
2753 }
2754 
RegistVirtualKeyBoardListener(const RefPtr<PipelineContext> & pipelineContext)2755 void WebPattern::RegistVirtualKeyBoardListener(const RefPtr<PipelineContext> &pipelineContext)
2756 {
2757     if (!needUpdateWeb_) {
2758         return;
2759     }
2760     pipelineContext->SetVirtualKeyBoardCallback(GetHost()->GetId(),
2761         [weak = AceType::WeakClaim(this)](int32_t width, int32_t height, double keyboard) {
2762             auto webPattern = weak.Upgrade();
2763             CHECK_NULL_RETURN(webPattern, false);
2764             return webPattern->ProcessVirtualKeyBoard(width, height, keyboard);
2765         });
2766     needUpdateWeb_ = false;
2767 }
2768 
InitEnhanceSurfaceFlag()2769 void WebPattern::InitEnhanceSurfaceFlag()
2770 {
2771     if (SystemProperties::GetExtSurfaceEnabled()) {
2772         isEnhanceSurface_ = true;
2773     } else {
2774         isEnhanceSurface_ = false;
2775     }
2776 }
2777 
OnColorConfigurationUpdate()2778 void WebPattern::OnColorConfigurationUpdate()
2779 {
2780     auto host = GetHost();
2781     CHECK_NULL_VOID(host);
2782     if (magnifierController_) {
2783         magnifierController_->SetColorModeChange(true);
2784         host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
2785     }
2786 }
2787 
OnModifyDone()2788 void WebPattern::OnModifyDone()
2789 {
2790     Pattern::OnModifyDone();
2791     // called in each update function.
2792     auto host = GetHost();
2793     CHECK_NULL_VOID(host);
2794     auto renderContext = host->GetRenderContext();
2795     CHECK_NULL_VOID(renderContext);
2796     renderContext->SetHandleChildBounds(true);
2797     if (!delegate_) {
2798         // first create case,
2799         delegate_ = AceType::MakeRefPtr<WebDelegate>(PipelineContext::GetCurrentContext(), nullptr, "",
2800             Container::CurrentId());
2801         instanceId_ = Container::CurrentId();
2802         CHECK_NULL_VOID(delegate_);
2803         observer_ = AceType::MakeRefPtr<WebDelegateObserver>(delegate_, PipelineContext::GetCurrentContext());
2804         CHECK_NULL_VOID(observer_);
2805         delegate_->SetObserver(observer_);
2806         delegate_->SetRenderMode(renderMode_);
2807         delegate_->SetFitContentMode(layoutMode_);
2808         InitEnhanceSurfaceFlag();
2809         delegate_->SetNGWebPattern(Claim(this));
2810         delegate_->SetEnhanceSurfaceFlag(isEnhanceSurface_);
2811         delegate_->SetPopup(isPopup_);
2812         delegate_->SetParentNWebId(parentNWebId_);
2813         delegate_->SetBackgroundColor(GetBackgroundColorValue(
2814             static_cast<int32_t>(renderContext->GetBackgroundColor().value_or(Color::WHITE).GetValue())));
2815         if (isEnhanceSurface_) {
2816             auto drawSize = Size(1, 1);
2817             delegate_->SetDrawSize(drawSize);
2818             delegate_->InitOHOSWeb(PipelineContext::GetCurrentContext());
2819         } else {
2820             auto drawSize = Size(1, 1);
2821             delegate_->SetDrawSize(drawSize);
2822             int32_t instanceId = Container::CurrentId();
2823             CHECK_NULL_VOID(renderSurface_);
2824             CHECK_NULL_VOID(renderContextForSurface_);
2825             renderSurface_->SetInstanceId(instanceId);
2826             renderSurface_->SetRenderContext(host->GetRenderContext());
2827             if (renderMode_ == RenderMode::SYNC_RENDER) {
2828                 renderSurface_->SetIsTexture(true);
2829                 renderSurface_->SetPatternType(PATTERN_TYPE_WEB);
2830                 renderSurface_->SetSurfaceQueueSize(SYNC_SURFACE_QUEUE_SIZE);
2831                 renderContextForSurface_->SetOpacity(0.0f);
2832             } else {
2833                 renderSurface_->SetIsTexture(false);
2834                 renderSurface_->SetSurfaceQueueSize(GetBufferSizeByDeviceType());
2835                 renderSurface_->SetRenderContext(renderContextForSurface_);
2836             }
2837             renderContext->AddChild(renderContextForSurface_, 0);
2838             renderSurface_->InitSurface();
2839             renderSurface_->SetTransformHint(rotation_);
2840             TAG_LOGD(AceLogTag::ACE_WEB, "OnModify done, set rotation %{public}u", rotation_);
2841             renderSurface_->UpdateSurfaceConfig();
2842             delegate_->InitOHOSWeb(PipelineContext::GetCurrentContext(), renderSurface_);
2843             if (renderMode_ == RenderMode::ASYNC_RENDER) {
2844                 std::string surfaceId = renderSurface_->GetUniqueId();
2845                 delegate_->SetSurfaceId(surfaceId);
2846                 TAG_LOGD(AceLogTag::ACE_WEB, "[getSurfaceId] set surfaceId is %{public}s", surfaceId.c_str());
2847             }
2848         }
2849         UpdateJavaScriptOnDocumentStart();
2850         UpdateJavaScriptOnDocumentEnd();
2851         delegate_->UpdateBackgroundColor(GetBackgroundColorValue(
2852             static_cast<int32_t>(renderContext->GetBackgroundColor().value_or(Color::WHITE).GetValue())));
2853         delegate_->UpdateJavaScriptEnabled(GetJsEnabledValue(true));
2854         delegate_->UpdateBlockNetworkImage(!GetOnLineImageAccessEnabledValue(true));
2855         delegate_->UpdateLoadsImagesAutomatically(GetImageAccessEnabledValue(true));
2856         delegate_->UpdateMixedContentMode(GetMixedModeValue(MixedModeContent::MIXED_CONTENT_NEVER_ALLOW));
2857         isEmbedModeEnabled_ = GetNativeEmbedModeEnabledValue(false);
2858         if ((layoutMode_ == WebLayoutMode::FIT_CONTENT) || isEmbedModeEnabled_) {
2859             delegate_->UpdateSupportZoom(false);
2860         } else {
2861             delegate_->UpdateSupportZoom(GetZoomAccessEnabledValue(true));
2862         }
2863         delegate_->UpdateDomStorageEnabled(GetDomStorageAccessEnabledValue(false));
2864         delegate_->UpdateGeolocationEnabled(GetGeolocationAccessEnabledValue(true));
2865         delegate_->UpdateCacheMode(GetCacheModeValue(WebCacheMode::DEFAULT));
2866         if (webData_) {
2867             // Created a richtext component
2868             delegate_->SetRichtextIdentifier(webData_);
2869             delegate_->UpdateDarkMode(GetDarkModeValue(WebDarkMode::Auto));
2870             delegate_->UpdateForceDarkAccess(GetForceDarkAccessValue(true));
2871             delegate_->UpdateOverviewModeEnabled(GetOverviewModeAccessEnabledValue(false));
2872         } else {
2873             delegate_->UpdateDarkMode(GetDarkModeValue(WebDarkMode::Off));
2874             delegate_->UpdateForceDarkAccess(GetForceDarkAccessValue(false));
2875             delegate_->UpdateOverviewModeEnabled(GetOverviewModeAccessEnabledValue(true));
2876         }
2877         delegate_->UpdateAudioResumeInterval(GetAudioResumeIntervalValue(-1));
2878         delegate_->UpdateAudioExclusive(GetAudioExclusiveValue(true));
2879         delegate_->UpdateFileFromUrlEnabled(GetFileFromUrlAccessEnabledValue(false));
2880         delegate_->UpdateDatabaseEnabled(GetDatabaseAccessEnabledValue(false));
2881         delegate_->UpdateTextZoomRatio(GetTextZoomRatioValue(DEFAULT_TEXT_ZOOM_RATIO));
2882         delegate_->UpdateWebDebuggingAccess(GetWebDebuggingAccessEnabledValue(false));
2883         delegate_->UpdateMediaPlayGestureAccess(GetMediaPlayGestureAccessValue(true));
2884         delegate_->UpdatePinchSmoothModeEnabled(GetPinchSmoothModeEnabledValue(false));
2885         delegate_->UpdateMultiWindowAccess(GetMultiWindowAccessEnabledValue(false));
2886         delegate_->UpdateWebCursiveFont(GetWebCursiveFontValue(DEFAULT_CURSIVE_FONT_FAMILY));
2887         delegate_->UpdateWebFantasyFont(GetWebFantasyFontValue(DEFAULT_FANTASY_FONT_FAMILY));
2888         delegate_->UpdateWebFixedFont(GetWebFixedFontValue(DEFAULT_FIXED_fONT_FAMILY));
2889         delegate_->UpdateWebSansSerifFont(GetWebSansSerifFontValue(DEFAULT_SANS_SERIF_FONT_FAMILY));
2890         delegate_->UpdateWebSerifFont(GetWebSerifFontValue(DEFAULT_SERIF_FONT_FAMILY));
2891         delegate_->UpdateWebStandardFont(GetWebStandardFontValue(DEFAULT_STANDARD_FONT_FAMILY));
2892         delegate_->UpdateDefaultFixedFontSize(GetDefaultFixedFontSizeValue(DEFAULT_FIXED_FONT_SIZE));
2893         delegate_->UpdateDefaultFontSize(GetDefaultFontSizeValue(DEFAULT_FONT_SIZE));
2894         delegate_->UpdateDefaultTextEncodingFormat(GetDefaultTextEncodingFormatValue(DEFAULT_WEB_TEXT_ENCODING_FORMAT));
2895         delegate_->UpdateMinFontSize(GetMinFontSizeValue(DEFAULT_MINIMUM_FONT_SIZE));
2896         delegate_->UpdateMinLogicalFontSize(GetMinLogicalFontSizeValue(DEFAULT_MINIMUM_LOGICAL_FONT_SIZE));
2897         delegate_->UpdateHorizontalScrollBarAccess(GetHorizontalScrollBarAccessEnabledValue(true));
2898         delegate_->UpdateVerticalScrollBarAccess(GetVerticalScrollBarAccessEnabledValue(true));
2899         delegate_->UpdateScrollBarColor(GetScrollBarColorValue(DEFAULT_SCROLLBAR_COLOR));
2900         delegate_->UpdateOverlayScrollbarEnabled(GetOverlayScrollbarEnabledValue(false));
2901         bool isApiGteTwelve =
2902             AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE);
2903         delegate_->UpdateOverScrollMode(GetOverScrollModeValue(OverScrollMode::NEVER));
2904         delegate_->UpdateCopyOptionMode(GetCopyOptionModeValue(static_cast<int32_t>(CopyOptions::Distributed)));
2905         delegate_->UpdateAllowFileAccess(GetFileAccessEnabledValue(isApiGteTwelve ? false : true));
2906         if (GetMetaViewport()) {
2907             delegate_->UpdateMetaViewport(GetMetaViewport().value());
2908         }
2909         delegate_->UpdateTextAutosizing(GetTextAutosizingValue(true));
2910         if (GetBlockNetwork()) {
2911             delegate_->UpdateBlockNetwork(GetBlockNetwork().value());
2912         }
2913         if (GetUserAgent()) {
2914             delegate_->UpdateUserAgent(GetUserAgent().value());
2915         }
2916         if (GetInitialScale()) {
2917             delegate_->UpdateInitialScale(GetInitialScale().value());
2918         }
2919         isAllowWindowOpenMethod_ = SystemProperties::GetAllowWindowOpenMethodEnabled();
2920         delegate_->UpdateAllowWindowOpenMethod(GetAllowWindowOpenMethodValue(isAllowWindowOpenMethod_));
2921         delegate_->UpdateNativeEmbedModeEnabled(GetNativeEmbedModeEnabledValue(false));
2922         delegate_->UpdateNativeEmbedRuleTag(GetNativeEmbedRuleTagValue(""));
2923         delegate_->UpdateNativeEmbedRuleType(GetNativeEmbedRuleTypeValue(""));
2924 
2925         std::tuple<bool, bool> config = GetNativeVideoPlayerConfigValue({false, false});
2926         delegate_->UpdateNativeVideoPlayerConfig(std::get<0>(config), std::get<1>(config));
2927     }
2928 
2929     if (!GetBackgroundColor()) {
2930         UpdateBackgroundColorRightNow(GetDefaultBackgroundColor().GetValue());
2931     }
2932 
2933     // Initialize events such as keyboard, focus, etc.
2934     InitEvent();
2935     // Initialize web params.
2936     InitFeatureParam();
2937     InitializeAccessibility();
2938     InitMagnifier();
2939     // Initialize scrollupdate listener
2940     if (renderMode_ == RenderMode::SYNC_RENDER) {
2941         auto task = [weak = AceType::WeakClaim(this)]() {
2942             auto webPattern = weak.Upgrade();
2943             CHECK_NULL_VOID(webPattern);
2944             webPattern->InitSlideUpdateListener();
2945         };
2946         PostTaskToUI(std::move(task), "ArkUIWebInitSlideUpdateListener");
2947     }
2948 
2949     auto embedEnabledTask = [weak = AceType::WeakClaim(this)]() {
2950         auto webPattern = weak.Upgrade();
2951         CHECK_NULL_VOID(webPattern);
2952         if (webPattern->IsRootNeedExportTexture() && webPattern->delegate_) {
2953             webPattern->delegate_->UpdateNativeEmbedModeEnabled(false);
2954         }
2955     };
2956     PostTaskToUI(std::move(embedEnabledTask), "ArkUIWebUpdateNativeEmbedModeEnabled");
2957 
2958     auto pipelineContext = PipelineContext::GetCurrentContext();
2959     CHECK_NULL_VOID(pipelineContext);
2960     if (nodeAttach_) {
2961         pipelineContext->AddOnAreaChangeNode(host->GetId());
2962     }
2963     // offline mode
2964     if (host->GetNodeStatus() != NodeStatus::NORMAL_NODE) {
2965         InitInOfflineMode();
2966     }
2967 
2968     auto pipeline = PipelineBase::GetCurrentContextSafely();
2969     if (pipeline) {
2970         densityCallbackId_ = pipeline->RegisterDensityChangedCallback([weak = WeakClaim(this)](double density) {
2971             auto webPattern = weak.Upgrade();
2972             CHECK_NULL_VOID(webPattern);
2973             webPattern->SetSurfaceDensity(density);
2974         });
2975         SetSurfaceDensity(pipeline->GetDensity());
2976     }
2977 }
2978 
SetSurfaceDensity(double density)2979 void WebPattern::SetSurfaceDensity(double density)
2980 {
2981     if (delegate_) {
2982         delegate_->SetSurfaceDensity(density);
2983     }
2984 }
2985 
InitInOfflineMode()2986 void WebPattern::InitInOfflineMode()
2987 {
2988     if (offlineWebInited_) {
2989         return;
2990     }
2991     TAG_LOGI(AceLogTag::ACE_WEB, "Web offline mode type, webId:%{public}d", GetWebId());
2992     delegate_->OnRenderToBackground();
2993     offlineWebInited_ = true;
2994     isActive_ = false;
2995     isVisible_ = false;
2996     auto host = GetHost();
2997     CHECK_NULL_VOID(host);
2998     int width = 0;
2999     int height = 0;
3000     auto layoutProperty = host->GetLayoutProperty();
3001     CHECK_NULL_VOID(layoutProperty);
3002     auto& calcLayout = layoutProperty->GetCalcLayoutConstraint();
3003     if (calcLayout) {
3004         width = calcLayout->selfIdealSize ?
3005             calcLayout->selfIdealSize->Width()->GetDimension().ConvertToPx() : 0;
3006         height = calcLayout->selfIdealSize ?
3007             calcLayout->selfIdealSize->Height()->GetDimension().ConvertToPx() : 0;
3008     }
3009     bool isUnSetSize = (width == 0) && (height == 0);
3010     auto defaultDisplay = OHOS::Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
3011     if (isUnSetSize && defaultDisplay) {
3012         width = defaultDisplay->GetWidth();
3013         height = defaultDisplay->GetHeight();
3014     }
3015     Size drawSize = Size(width, height);
3016     Offset offset = Offset(0, 0);
3017     TAG_LOGD(AceLogTag::ACE_WEB, "InitInOfflineMode drawsize_ : %{public}s", drawSize_.ToString().c_str());
3018     delegate_->SetBoundsOrResize(drawSize, offset);
3019 
3020     if (!isUrlLoaded_) {
3021         isUrlLoaded_ = true;
3022         if (webSrc_) {
3023             delegate_->LoadUrl();
3024         } else if (webData_) {
3025             delegate_->LoadDataWithRichText();
3026         }
3027     }
3028     delegate_->HideWebView();
3029     CloseContextSelectionMenu();
3030 }
3031 
IsNeedResizeVisibleViewport()3032 bool WebPattern::IsNeedResizeVisibleViewport()
3033 {
3034     if (visibleViewportSize_.Width() < 0 || visibleViewportSize_.Height() < 0 ||
3035         isVirtualKeyBoardShow_ != VkState::VK_SHOW || NearZero(lastKeyboardHeight_)) {
3036         return false;
3037     }
3038     auto context = PipelineContext::GetCurrentContext();
3039     CHECK_NULL_RETURN(context, false);
3040     int32_t height = context->GetRootRect().Height();
3041     auto y = GetCoordinatePoint()->GetY();
3042     if (GreatOrEqual(height, lastKeyboardHeight_ + y)) {
3043         double newHeight = height - lastKeyboardHeight_ - y;
3044         if (GreatOrEqual(newHeight, drawSize_.Height()) ||
3045             NearEqual(newHeight, drawSize_.Height())) {
3046             visibleViewportSize_.SetWidth(-1.0);
3047             visibleViewportSize_.SetHeight(-1.0);
3048         } else {
3049             return false;
3050         }
3051     } else {
3052         visibleViewportSize_.SetWidth(-1.0);
3053         visibleViewportSize_.SetHeight(-1.0);
3054     }
3055     delegate_->ResizeVisibleViewport(visibleViewportSize_, false);
3056     return true;
3057 }
3058 
ProcessVirtualKeyBoardHide(int32_t width,int32_t height,bool safeAreaEnabled)3059 bool WebPattern::ProcessVirtualKeyBoardHide(int32_t width, int32_t height, bool safeAreaEnabled)
3060 {
3061     isKeyboardInSafeArea_ = false;
3062     if (layoutMode_ == WebLayoutMode::FIT_CONTENT) {
3063         TAG_LOGI(AceLogTag::ACE_WEB, "ProcessVirtualKeyBoardHide layoutMode is FIT_CONTENT");
3064         isVirtualKeyBoardShow_ = VkState::VK_HIDE;
3065         return true;
3066     }
3067     if (safeAreaEnabled) {
3068         isVirtualKeyBoardShow_ = VkState::VK_HIDE;
3069         return false;
3070     }
3071     if (isVirtualKeyBoardShow_ != VkState::VK_SHOW) {
3072         return false;
3073     }
3074     drawSize_.SetSize(drawSizeCache_);
3075     visibleViewportSize_.SetWidth(-1.0);
3076     visibleViewportSize_.SetHeight(-1.0);
3077     UpdateWebLayoutSize(width, height, false);
3078     isVirtualKeyBoardShow_ = VkState::VK_HIDE;
3079     return true;
3080 }
3081 
ProcessVirtualKeyBoardShow(int32_t width,int32_t height,double keyboard,bool safeAreaEnabled)3082 bool WebPattern::ProcessVirtualKeyBoardShow(int32_t width, int32_t height, double keyboard, bool safeAreaEnabled)
3083 {
3084     if (IsDialogNested()) {
3085         TAG_LOGI(AceLogTag::ACE_WEB, "ProcessVirtualKeyBoardShow, dialog nested, web don't consume keyboard event.");
3086         isKeyboardInSafeArea_ = true;
3087         return false;
3088     }
3089     if (isVirtualKeyBoardShow_ != VkState::VK_SHOW) {
3090         drawSizeCache_.SetSize(drawSize_);
3091     }
3092     if (drawSizeCache_.Height() <= (height - keyboard - GetCoordinatePoint()->GetY())) {
3093         TAG_LOGI(AceLogTag::ACE_WEB, "ProcessVirtualKeyBoardShow not obstruct");
3094         isVirtualKeyBoardShow_ = VkState::VK_SHOW;
3095         return !safeAreaEnabled;
3096     }
3097     if (height - GetCoordinatePoint()->GetY() < keyboard) {
3098         TAG_LOGI(AceLogTag::ACE_WEB, "ProcessVirtualKeyBoardShow Complete occlusion");
3099         isVirtualKeyBoardShow_ = VkState::VK_SHOW;
3100         return true;
3101     }
3102     if (!delegate_->NeedSoftKeyboard()) {
3103         TAG_LOGI(AceLogTag::ACE_WEB, "ProcessVirtualKeyBoardShow not NeedSoftKeyboard");
3104         return false;
3105     }
3106     isVirtualKeyBoardShow_ = VkState::VK_SHOW;
3107     if (layoutMode_ == WebLayoutMode::FIT_CONTENT) {
3108         TAG_LOGI(AceLogTag::ACE_WEB, "ProcessVirtualKeyBoardShow layoutMode is FIT_CONTENT");
3109         lastKeyboardHeight_ = keyboard;
3110         return true;
3111     }
3112     if (safeAreaEnabled) {
3113         isKeyboardInSafeArea_ = true;
3114         lastKeyboardHeight_ = keyboard;
3115         return false;
3116     }
3117     auto frameNode = GetHost();
3118     CHECK_NULL_RETURN(frameNode, false);
3119     frameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
3120     auto context = PipelineContext::GetCurrentContext();
3121     CHECK_NULL_RETURN(context, false);
3122     auto taskExecutor = context->GetTaskExecutor();
3123     CHECK_NULL_RETURN(taskExecutor, false);
3124     UpdateLayoutAfterKeyboardShow(width, height, keyboard, drawSize_.Height());
3125     return true;
3126 }
3127 
ProcessVirtualKeyBoard(int32_t width,int32_t height,double keyboard)3128 bool WebPattern::ProcessVirtualKeyBoard(int32_t width, int32_t height, double keyboard)
3129 {
3130     CHECK_NULL_RETURN(delegate_, false);
3131     delegate_->SetVirtualKeyBoardArg(width, height, keyboard);
3132 
3133     auto host = GetHost();
3134     CHECK_NULL_RETURN(host, false);
3135     auto pipelineContext = host->GetContextRefPtr();
3136     CHECK_NULL_RETURN(pipelineContext, false);
3137     auto safeAreaManager = pipelineContext->GetSafeAreaManager();
3138     CHECK_NULL_RETURN(safeAreaManager, false);
3139     bool keyboardSafeAreaEnabled = safeAreaManager->KeyboardSafeAreaEnabled();
3140     TAG_LOGI(AceLogTag::ACE_WEB,
3141         "ProcessVirtualKeyBoard width:%{public}d, height:%{public}d, keyboard:%{public}f, safeArea:%{public}d",
3142         width, height, keyboard, keyboardSafeAreaEnabled);
3143 
3144     if (!isFocus_ || !isVisible_) {
3145         UpdateOnFocusTextField(false);
3146         ProcessVirtualKeyBoardHide(width, height, keyboardSafeAreaEnabled);
3147         return false;
3148     }
3149     UpdateOnFocusTextField(!NearZero(keyboard));
3150     if (NearZero(keyboard)) {
3151         return ProcessVirtualKeyBoardHide(width, height, keyboardSafeAreaEnabled);
3152     }
3153     return ProcessVirtualKeyBoardShow(width, height, keyboard, keyboardSafeAreaEnabled);
3154 }
3155 
UpdateWebLayoutSize(int32_t width,int32_t height,bool isKeyboard,bool isUpdate)3156 void WebPattern::UpdateWebLayoutSize(int32_t width, int32_t height, bool isKeyboard, bool isUpdate)
3157 {
3158     CHECK_NULL_VOID(delegate_);
3159     if (delegate_->ShouldVirtualKeyboardOverlay()) {
3160         TAG_LOGW(AceLogTag::ACE_WEB, "VirtualKeyboard Overlaycontent is true and does not require resizing");
3161         return;
3162     }
3163     auto frameNode = GetHost();
3164     CHECK_NULL_VOID(frameNode);
3165     auto rect = frameNode->GetRenderContext()->GetPaintRectWithoutTransform();
3166     auto offset = Offset(GetCoordinatePoint()->GetX(), GetCoordinatePoint()->GetY());
3167 
3168     // Scroll focused node into view when keyboard show.
3169     TAG_LOGD(AceLogTag::ACE_WEB, "UpdateWebLayoutSize drawsize_ : %{public}s", drawSize_.ToString().c_str());
3170     delegate_->SetBoundsOrResize(drawSize_, offset, isKeyboard);
3171     delegate_->ResizeVisibleViewport(visibleViewportSize_, isKeyboard);
3172 
3173     if (isUpdate) {
3174         rect.SetSize(SizeF(drawSize_.Width(), drawSize_.Height()));
3175         frameNode->GetRenderContext()->SyncGeometryProperties(rect);
3176         frameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF | PROPERTY_UPDATE_RENDER);
3177     }
3178 }
3179 
HandleTouchDown(const TouchEventInfo & info,bool fromOverlay)3180 void WebPattern::HandleTouchDown(const TouchEventInfo& info, bool fromOverlay)
3181 {
3182     InitTouchEventListener();
3183     isTouchUpEvent_ = false;
3184     CHECK_NULL_VOID(delegate_);
3185     Offset touchOffset = Offset(0, 0);
3186     std::list<TouchInfo> touchInfos;
3187     if (!ParseTouchInfo(info, touchInfos)) {
3188         return;
3189     }
3190     for (auto& touchPoint : touchInfos) {
3191         if (fromOverlay) {
3192             touchPoint.x -= webOffset_.GetX();
3193             touchPoint.y -= webOffset_.GetY();
3194             TAG_LOGI(AceLogTag::ACE_WEB,
3195                 "SelectOverlay touch down add id:%{public}d.", touchPoint.id);
3196             touchOverlayInfo_.push_back(touchPoint);
3197         }
3198         touchPointX = touchPoint.x;
3199         touchPointY = touchPoint.y;
3200         delegate_->HandleTouchDown(touchPoint.id, touchPoint.x, touchPoint.y, fromOverlay);
3201         if (overlayCreating_) {
3202             imageAnalyzerManager_->UpdateOverlayTouchInfo(touchPoint.x, touchPoint.y, TouchType::DOWN);
3203         }
3204     }
3205     if (!touchInfos.empty() && !GetNativeEmbedModeEnabledValue(false)) {
3206         WebRequestFocus();
3207     }
3208 }
3209 
HandleTouchUp(const TouchEventInfo & info,bool fromOverlay)3210 void WebPattern::HandleTouchUp(const TouchEventInfo& info, bool fromOverlay)
3211 {
3212     UninitTouchEventListener();
3213     isTouchUpEvent_ = true;
3214     CHECK_NULL_VOID(delegate_);
3215     if (!isReceivedArkDrag_) {
3216         ResetDragAction();
3217     }
3218     HideMagnifier();
3219     std::list<TouchInfo> touchInfos;
3220     if (!ParseTouchInfo(info, touchInfos)) {
3221         return;
3222     }
3223     for (auto& touchPoint : touchInfos) {
3224         if (fromOverlay) {
3225             touchPoint.x -= webOffset_.GetX();
3226             touchPoint.y -= webOffset_.GetY();
3227             DelTouchOverlayInfoByTouchId(touchPoint.id);
3228         }
3229         if (!overlayCreating_) {
3230             delegate_->HandleTouchUp(touchPoint.id, touchPoint.x, touchPoint.y, fromOverlay);
3231         } else {
3232             if (imageAnalyzerManager_) {
3233                 imageAnalyzerManager_->UpdateOverlayTouchInfo(touchPoint.x, touchPoint.y, TouchType::UP);
3234                 overlayCreating_ = false;
3235                 delegate_->HandleTouchCancel();
3236             }
3237         }
3238     }
3239 }
3240 
HandleTouchClickEventFromOverlay(const GestureEvent & info)3241 void WebPattern::HandleTouchClickEventFromOverlay(const GestureEvent& info)
3242 {
3243     CHECK_NULL_VOID(delegate_);
3244     auto host = GetHost();
3245     CHECK_NULL_VOID(host);
3246     auto focusHub = host->GetOrCreateFocusHub();
3247     CHECK_NULL_VOID(focusHub);
3248     if (!focusHub->IsFocusable() || info.GetSourceDevice() == SourceType::MOUSE) {
3249         return;
3250     }
3251     if (IsSelectOverlayDragging()) {
3252         TAG_LOGI(AceLogTag::ACE_WEB, "HandleTouchClickEvent fail when handle dragging.");
3253         return;
3254     }
3255     if (!IsTouchHandleValid(insertHandle_)) {
3256         return;
3257     }
3258     auto globalLocation = info.GetGlobalLocation();
3259     TouchInfo touchPoint;
3260     touchPoint.id = 0;
3261     touchPoint.x = globalLocation.GetX() - webOffset_.GetX();
3262     touchPoint.y = globalLocation.GetY() - webOffset_.GetY();
3263     auto pipeline = host->GetContext();
3264     CHECK_NULL_VOID(pipeline);
3265     auto theme = pipeline->GetTheme<TextOverlayTheme>();
3266     CHECK_NULL_VOID(theme);
3267     float hotZone = theme->GetHandleHotZoneRadius().ConvertToPx();
3268     RectF edgeRect(insertHandle_->GetX() - hotZone,
3269                    insertHandle_->GetY() - insertHandle_->GetEdgeHeight(),
3270                    hotZone * 2,
3271                    insertHandle_->GetEdgeHeight());
3272     bool isInRegion = edgeRect.IsInRegion({touchPoint.x, touchPoint.y});
3273     TAG_LOGI(AceLogTag::ACE_WEB, "point.x:%{public}f. y:%{public}f, isInRegion:%{public}d",
3274         touchPoint.x, touchPoint.y, isInRegion);
3275     TAG_LOGI(AceLogTag::ACE_WEB, "edgeRect:%{public}s", edgeRect.ToString().c_str());
3276     delegate_->HandleTouchDown(touchPoint.id, touchPoint.x, touchPoint.y, !isInRegion);
3277     delegate_->HandleTouchUp(touchPoint.id, touchPoint.x, touchPoint.y, !isInRegion);
3278 }
3279 
ChangeHandleHeight(const std::shared_ptr<SelectOverlayInfo> & info,const GestureEvent & event,bool isFirst)3280 RectF WebPattern::ChangeHandleHeight(
3281     const std::shared_ptr<SelectOverlayInfo>& info, const GestureEvent& event, bool isFirst)
3282 {
3283     auto touchOffset = event.GetLocalLocation();
3284     auto handle = isFirst ? info->firstHandle : info->secondHandle;
3285     auto handleHeight = SELECT_HANDLE_DEFAULT_HEIGHT.ConvertToPx();
3286     handleHeight = std::min(static_cast<float>(handleHeight), handle.paintRect.Height());
3287     bool isTouchHandleCircle = isFirst ?
3288         LessNotEqual(touchOffset.GetY(), handle.paintRect.Top()) :
3289         GreatNotEqual(touchOffset.GetY(), handle.paintRect.Bottom());
3290     if (isFirst) {
3291         if (!isTouchHandleCircle) {
3292             handle.paintRect.SetTop(static_cast<float>(touchOffset.GetY()) - handleHeight / HALF);
3293         }
3294         handle.paintRect.SetHeight(handleHeight);
3295         info->firstHandle = handle;
3296         info->firstHandle.isCircleShow = false;
3297     } else {
3298         auto handleOffsetY = isTouchHandleCircle
3299                             ? handle.paintRect.Bottom() - handleHeight
3300                             : static_cast<float>(touchOffset.GetY()) - handleHeight / HALF;
3301         handle.paintRect.SetTop(handleOffsetY);
3302         handle.paintRect.SetHeight(handleHeight);
3303         info->secondHandle = handle;
3304         info->secondHandle.isCircleShow = false;
3305     }
3306     return handle.paintRect;
3307 }
3308 
OnSelectHandleStart(const GestureEvent & event,bool isFirst)3309 void WebPattern::OnSelectHandleStart(const GestureEvent& event, bool isFirst)
3310 {
3311     CHECK_NULL_VOID(selectOverlayProxy_);
3312     CHECK_NULL_VOID(delegate_);
3313     SetCurrentStartHandleDragging(isFirst);
3314     SetSelectOverlayDragging(true);
3315 
3316     auto pipeline = PipelineContext::GetCurrentContext();
3317     CHECK_NULL_VOID(pipeline);
3318     auto manager = pipeline->GetSelectOverlayManager();
3319     CHECK_NULL_VOID(manager);
3320     auto node = manager->GetSelectOverlayNode(selectOverlayProxy_->GetSelectOverlayId());
3321     CHECK_NULL_VOID(node);
3322     auto pattern = node->GetPattern<SelectOverlayPattern>();
3323     CHECK_NULL_VOID(pattern);
3324     const std::shared_ptr<SelectOverlayInfo>& info = pattern->GetSelectOverlayInfo();
3325     RectF handleRect = ChangeHandleHeight(info, event, isFirst);
3326 
3327     TouchInfo touchPoint;
3328     touchPoint.id = 0;
3329     touchPoint.x = handleRect.GetX() - webOffset_.GetX();
3330     touchPoint.y = handleRect.GetY() - webOffset_.GetY() + handleRect.Height() / HALF;
3331     TAG_LOGI(AceLogTag::ACE_WEB, "OnSelectHandleStart touch down add id:%{public}d.", touchPoint.id);
3332     touchOverlayInfo_.push_back(touchPoint);
3333     delegate_->HandleTouchDown(touchPoint.id, touchPoint.x, touchPoint.y, true);
3334     if (overlayCreating_) {
3335         imageAnalyzerManager_->UpdateOverlayTouchInfo(touchPoint.x, touchPoint.y, TouchType::DOWN);
3336     }
3337     if (!GetNativeEmbedModeEnabledValue(false)) {
3338         WebRequestFocus();
3339     }
3340 }
3341 
OnSelectHandleDone(const RectF & handleRect,bool isFirst)3342 void WebPattern::OnSelectHandleDone(const RectF& handleRect, bool isFirst)
3343 {
3344     SetSelectOverlayDragging(false);
3345     CHECK_NULL_VOID(delegate_);
3346     TouchInfo touchPoint;
3347     touchPoint.id = 0;
3348     touchPoint.x = handleRect.GetX() - webOffset_.GetX();
3349     touchPoint.y = handleRect.GetY() - webOffset_.GetY() + handleRect.Height() / HALF;
3350     DelTouchOverlayInfoByTouchId(touchPoint.id);
3351     if (!overlayCreating_) {
3352         delegate_->HandleTouchUp(touchPoint.id, touchPoint.x, touchPoint.y, true);
3353     } else if (imageAnalyzerManager_) {
3354         imageAnalyzerManager_->UpdateOverlayTouchInfo(touchPoint.x, touchPoint.y, TouchType::UP);
3355         overlayCreating_ = false;
3356         delegate_->HandleTouchCancel();
3357     }
3358     UpdateTouchHandleForOverlay(true);
3359     if (!IsQuickMenuShow()) {
3360         ChangeVisibilityOfQuickMenu();
3361     }
3362     WebOverlayType overlayType = GetTouchHandleOverlayType(insertHandle_, startSelectionHandle_, endSelectionHandle_);
3363     if (overlayType == SELECTION_OVERLAY && !IsSelectInfoValid()) {
3364         TAG_LOGI(AceLogTag::ACE_WEB, "Close handles and menu.");
3365         CloseSelectOverlay();
3366         SelectCancel();
3367     }
3368 }
3369 
OnMagnifierHandleMove(const RectF & handleRect,bool isFirst)3370 void WebPattern::OnMagnifierHandleMove(const RectF& handleRect, bool isFirst)
3371 {
3372     auto localX = handleRect.GetX() - webOffset_.GetX() + handleRect.Width() / HALF;
3373     auto localY = handleRect.GetY() - webOffset_.GetY() + handleRect.Height() / HALF;
3374     ShowMagnifier(localX, localY);
3375 }
3376 
OnSelectHandleMove(const RectF & handleRect,bool isFirst)3377 void WebPattern::OnSelectHandleMove(const RectF& handleRect, bool isFirst)
3378 {
3379     auto pipeline = PipelineContext::GetCurrentContext();
3380     CHECK_NULL_VOID(pipeline);
3381     auto manager = pipeline->GetDragDropManager();
3382     CHECK_NULL_VOID(manager);
3383     if (isDragging_ || manager->IsDragged()) {
3384         return;
3385     }
3386     CHECK_NULL_VOID(delegate_);
3387     TouchInfo touchPoint;
3388     touchPoint.id = 0;
3389     touchPoint.x = handleRect.GetX() - webOffset_.GetX();
3390     touchPoint.y = handleRect.GetY() - webOffset_.GetY() + handleRect.Height() / HALF;
3391     if (overlayCreating_) {
3392         imageAnalyzerManager_->UpdateOverlayTouchInfo(touchPoint.x, touchPoint.y, TouchType::MOVE);
3393     } else {
3394         std::vector<std::shared_ptr<OHOS::NWeb::NWebTouchPointInfo>> touch_point_infos;
3395         std::shared_ptr<OHOS::NWeb::NWebTouchPointInfo> touch_point_info =
3396             std::make_shared<NWebTouchPointInfoImpl>(touchPoint.id, touchPoint.x, touchPoint.y);
3397         touch_point_infos.emplace_back(touch_point_info);
3398         delegate_->HandleTouchMove(touch_point_infos, true);
3399     }
3400 }
3401 
HandleTouchMove(const TouchEventInfo & info,bool fromOverlay)3402 void WebPattern::HandleTouchMove(const TouchEventInfo& info, bool fromOverlay)
3403 {
3404     if (isDragging_) {
3405         return;
3406     }
3407     auto pipeline = PipelineContext::GetCurrentContext();
3408     CHECK_NULL_VOID(pipeline);
3409     auto manager = pipeline->GetDragDropManager();
3410     CHECK_NULL_VOID(manager);
3411     if (manager->IsDragged()) {
3412         return;
3413     }
3414     CHECK_NULL_VOID(delegate_);
3415     std::list<TouchInfo> touchInfos;
3416 
3417     touchEventInfoList_.emplace_back(info);
3418     for (const auto& touchEventInfo : touchEventInfoList_) {
3419         ParseTouchInfo(touchEventInfo, touchInfos);
3420     }
3421 
3422     if (touchInfos.empty()) {
3423         return;
3424     }
3425     if (!info.GetTouchEventsEnd()) {
3426         return;
3427     }
3428     touchEventInfoList_.clear();
3429 
3430     touchInfos.sort([](const TouchInfo &point1, const TouchInfo &point2) {
3431         return point1.id < point2.id;
3432     });
3433 
3434     std::vector<std::shared_ptr<OHOS::NWeb::NWebTouchPointInfo>> touch_point_infos;
3435     for (auto& touchPoint : touchInfos) {
3436         if (fromOverlay) {
3437             touchPoint.x -= webOffset_.GetX();
3438             touchPoint.y -= webOffset_.GetY();
3439         }
3440         touchPointX = touchPoint.x;
3441         touchPointY = touchPoint.y;
3442         if (magnifierController_ && magnifierController_->GetMagnifierNodeExist()) {
3443             ShowMagnifier(touchPoint.x, touchPoint.y);
3444         }
3445         std::shared_ptr<OHOS::NWeb::NWebTouchPointInfo> touch_point_info =
3446             std::make_shared<NWebTouchPointInfoImpl>(touchPoint.id, touchPoint.x, touchPoint.y);
3447         touch_point_infos.emplace_back(touch_point_info);
3448         if (overlayCreating_) {
3449             imageAnalyzerManager_->UpdateOverlayTouchInfo(touchPoint.x, touchPoint.y, TouchType::MOVE);
3450         }
3451     }
3452 
3453     if (!overlayCreating_) {
3454         delegate_->HandleTouchMove(touch_point_infos, fromOverlay);
3455     }
3456 }
3457 
HandleTouchCancel(const TouchEventInfo & info)3458 void WebPattern::HandleTouchCancel(const TouchEventInfo& info)
3459 {
3460     UninitTouchEventListener();
3461     if (IsRootNeedExportTexture()) {
3462         HandleTouchUp(info, false);
3463     }
3464     CHECK_NULL_VOID(delegate_);
3465     delegate_->HandleTouchCancel();
3466     if (overlayCreating_) {
3467         imageAnalyzerManager_->UpdateOverlayTouchInfo(0, 0, TouchType::CANCEL);
3468         overlayCreating_ = false;
3469     }
3470     HideMagnifier();
3471 }
3472 
ParseTouchInfo(const TouchEventInfo & info,std::list<TouchInfo> & touchInfos)3473 bool WebPattern::ParseTouchInfo(const TouchEventInfo& info, std::list<TouchInfo>& touchInfos)
3474 {
3475     auto context = PipelineContext::GetCurrentContext();
3476     CHECK_NULL_RETURN(context, false);
3477     auto viewScale = context->GetViewScale();
3478 
3479     if (info.GetChangedTouches().empty()) {
3480         return false;
3481     }
3482     for (const auto& point : info.GetChangedTouches()) {
3483         TouchInfo touchInfo;
3484         touchInfo.id = point.GetFingerId();
3485         const Offset& location = point.GetLocalLocation();
3486         touchInfo.x = static_cast<float>(location.GetX() * viewScale);
3487         touchInfo.y = static_cast<float>(location.GetY() * viewScale);
3488         touchInfos.emplace_back(touchInfo);
3489     }
3490     return true;
3491 }
3492 
RequestFullScreen()3493 void WebPattern::RequestFullScreen()
3494 {
3495     isFullScreen_ = true;
3496 }
3497 
ExitFullScreen()3498 void WebPattern::ExitFullScreen()
3499 {
3500     isFullScreen_ = false;
3501 }
3502 
IsTouchHandleValid(std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> handle)3503 bool WebPattern::IsTouchHandleValid(std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> handle)
3504 {
3505     return (handle != nullptr) && (handle->IsEnable());
3506 }
3507 
CheckHandles(SelectHandleInfo & handleInfo,const std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> & handle)3508 void WebPattern::CheckHandles(SelectHandleInfo& handleInfo,
3509     const std::shared_ptr<OHOS::NWeb::NWebTouchHandleState>& handle)
3510 {
3511     CHECK_NULL_VOID(handle);
3512     auto pipeline = PipelineBase::GetCurrentContext();
3513     CHECK_NULL_VOID(pipeline);
3514     int y = static_cast<int32_t>(handle->GetY() / pipeline->GetDipScale());
3515     int edgeHeight = static_cast<int32_t>(handle->GetEdgeHeight() / pipeline->GetDipScale()) - 1;
3516     if (handle->GetAlpha() <= 0 || y < edgeHeight) {
3517         handleInfo.isShow = false;
3518         return;
3519     }
3520 
3521     auto host = GetHost();
3522     CHECK_NULL_VOID(host);
3523     float viewPortY = handle->GetViewPortY();
3524     RectF visibleRect;
3525     RectF visibleInnerRect;
3526     RectF frameRect;
3527     host->GetVisibleRectWithClip(visibleRect, visibleInnerRect, frameRect);
3528     visibleInnerRect.SetRect(visibleInnerRect.GetX(), visibleInnerRect.GetY() + viewPortY - 1,
3529         visibleInnerRect.Width(), visibleInnerRect.Height() - viewPortY + 1);
3530     auto paintRect = handleInfo.paintRect;
3531     PointF bottomPoint = { paintRect.Left(), paintRect.Bottom() };
3532     PointF topPoint = { paintRect.Left(), paintRect.Top() };
3533     handleInfo.isShow = (visibleInnerRect.IsInRegion(bottomPoint) && visibleInnerRect.IsInRegion(topPoint));
3534 }
3535 
GetTouchHandleOverlayType(std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> insertHandle,std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> startSelectionHandle,std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endSelectionHandle)3536 WebOverlayType WebPattern::GetTouchHandleOverlayType(std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> insertHandle,
3537     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> startSelectionHandle,
3538     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endSelectionHandle)
3539 {
3540     if (IsTouchHandleValid(insertHandle) && !IsTouchHandleValid(startSelectionHandle) &&
3541         !IsTouchHandleValid(endSelectionHandle)) {
3542         return INSERT_OVERLAY;
3543     }
3544 
3545     if (!IsTouchHandleValid(insertHandle) && IsTouchHandleValid(startSelectionHandle) &&
3546         IsTouchHandleValid(endSelectionHandle)) {
3547         return SELECTION_OVERLAY;
3548     }
3549 
3550     return INVALID_OVERLAY;
3551 }
3552 
GetCoordinatePoint()3553 std::optional<OffsetF> WebPattern::GetCoordinatePoint()
3554 {
3555     auto frameNode = GetHost();
3556     CHECK_NULL_RETURN(frameNode, std::nullopt);
3557     return frameNode->GetTransformRelativeOffset();
3558 }
3559 
ComputeTouchHandleRect(std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> touchHandle)3560 RectF WebPattern::ComputeTouchHandleRect(std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> touchHandle)
3561 {
3562     CHECK_NULL_RETURN(touchHandle, RectF());
3563     RectF paintRect;
3564     auto offset = GetCoordinatePoint().value_or(OffsetF());
3565     auto size = GetHostFrameSize().value_or(SizeF());
3566     float edgeHeight = touchHandle->GetEdgeHeight();
3567     float x = touchHandle->GetX();
3568     float y = touchHandle->GetY();
3569     if (x > size.Width()) {
3570         x = offset.GetX() + size.Width();
3571     } else {
3572         x = x + offset.GetX();
3573     }
3574 
3575     if (y < 0) {
3576         y = offset.GetY();
3577     } else if (y > size.Height()) {
3578         y = offset.GetY() + size.Height();
3579     } else {
3580         y = y + offset.GetY();
3581         y = y - edgeHeight;
3582     }
3583 
3584     paintRect.SetOffset({ x, y });
3585     paintRect.SetSize({ SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), edgeHeight });
3586     return paintRect;
3587 }
3588 
DelTouchOverlayInfoByTouchId(int32_t touchId)3589 void WebPattern::DelTouchOverlayInfoByTouchId(int32_t touchId)
3590 {
3591     std::list<TouchInfo>::iterator iter;
3592     for (iter = touchOverlayInfo_.begin(); iter != touchOverlayInfo_.end();) {
3593         if (iter->id == touchId) {
3594             TAG_LOGI(AceLogTag::ACE_WEB,
3595                 "SelectOverlay del touch overlay info by id:%{public}d", iter->id);
3596             iter = touchOverlayInfo_.erase(iter);
3597         } else {
3598             ++iter;
3599         }
3600     }
3601 }
3602 
CloseSelectOverlay()3603 void WebPattern::CloseSelectOverlay()
3604 {
3605     auto pipeline = PipelineContext::GetCurrentContext();
3606     CHECK_NULL_VOID(pipeline);
3607     selectTemporarilyHidden_ = false;
3608     selectTemporarilyHiddenByScroll_ = false;
3609     if (selectOverlayProxy_) {
3610         TAG_LOGI(AceLogTag::ACE_WEB, "Close Select Overlay Now");
3611         SetSelectOverlayDragging(false);
3612         StopListenSelectOverlayParentScroll(GetHost());
3613         selectOverlayProxy_->Close();
3614         pipeline->GetSelectOverlayManager()->DestroySelectOverlay(selectOverlayProxy_);
3615         selectOverlayProxy_ = nullptr;
3616 
3617         for (auto& touchOverlayInfo : touchOverlayInfo_) {
3618             TAG_LOGI(AceLogTag::ACE_WEB,
3619                 "SelectOverlay send touch up id:%{public}d", touchOverlayInfo.id);
3620             delegate_->HandleTouchUp(touchOverlayInfo.id, touchOverlayInfo.x, touchOverlayInfo.y, true);
3621             HideMagnifier();
3622         }
3623         touchOverlayInfo_.clear();
3624     }
3625 }
3626 
OnParentScrollStartOrEndCallback(bool isEnd)3627 void WebPattern::OnParentScrollStartOrEndCallback(bool isEnd)
3628 {
3629     CHECK_NULL_VOID(selectOverlayProxy_);
3630     auto pipeline = PipelineContext::GetCurrentContext();
3631     CHECK_NULL_VOID(pipeline);
3632     auto manager = pipeline->GetSelectOverlayManager();
3633     CHECK_NULL_VOID(manager);
3634     auto overlayId = selectOverlayProxy_->GetSelectOverlayId();
3635     if (!manager->HasSelectOverlay(overlayId)) {
3636         return;
3637     }
3638 
3639     if (selectOverlayProxy_->IsSingleHandle()) {
3640         if (!isEnd) {
3641             selectOverlayProxy_->UpdateSelectMenuInfo([](SelectMenuInfo& menuInfo) {
3642                 menuInfo.menuIsShow = false;
3643             });
3644         }
3645         return;
3646     }
3647     selectTemporarilyHiddenByScroll_ = !isEnd;
3648     if (selectTemporarilyHidden_) {
3649         return;
3650     }
3651     HideHandleAndQuickMenuIfNecessary(selectTemporarilyHiddenByScroll_, true);
3652 }
3653 
RegisterSelectOverlayParentScrollCallback(int32_t parentId,int32_t callbackId)3654 void WebPattern::RegisterSelectOverlayParentScrollCallback(int32_t parentId, int32_t callbackId)
3655 {
3656     auto host = GetHost();
3657     CHECK_NULL_VOID(host);
3658     auto context = host->GetContext();
3659     CHECK_NULL_VOID(context);
3660     auto manager = context->GetSelectOverlayManager();
3661     CHECK_NULL_VOID(manager);
3662     auto scrollCallback = [weak = WeakClaim(this)](Axis axis, float offset, int32_t source) {
3663         auto client = weak.Upgrade();
3664         CHECK_NULL_VOID(client);
3665         if (source == SCROLL_FROM_START) {
3666             client->OnParentScrollStartOrEndCallback(false);
3667         } else if (source == -1) {
3668             client->OnParentScrollStartOrEndCallback(true);
3669         }
3670     };
3671     manager->RegisterScrollCallback(parentId, callbackId, scrollCallback);
3672 }
3673 
StartListenSelectOverlayParentScroll(const RefPtr<FrameNode> & host)3674 void WebPattern::StartListenSelectOverlayParentScroll(const RefPtr<FrameNode>& host)
3675 {
3676     if (!scrollableParentInfo_.hasParent) {
3677         TAG_LOGI(AceLogTag::ACE_WEB, "has no scrollable parent");
3678         return;
3679     }
3680     CHECK_NULL_VOID(host);
3681     auto context = host->GetContext();
3682     CHECK_NULL_VOID(context);
3683     auto hostId = host->GetId();
3684     if (!scrollableParentInfo_.parentIds.empty()) {
3685         for (const auto& scrollId : scrollableParentInfo_.parentIds) {
3686             RegisterSelectOverlayParentScrollCallback(scrollId, hostId);
3687         }
3688         return;
3689     }
3690     auto parent = host->GetParent();
3691     while (parent && parent->GetTag() != V2::PAGE_ETS_TAG) {
3692         auto parentNode = AceType::DynamicCast<FrameNode>(parent);
3693         if (parentNode) {
3694             auto pattern = parentNode->GetPattern<ScrollablePattern>();
3695             if (pattern) {
3696                 scrollableParentInfo_.parentIds.emplace_back(parentNode->GetId());
3697                 RegisterSelectOverlayParentScrollCallback(parentNode->GetId(), hostId);
3698             }
3699         }
3700         parent = parent->GetParent();
3701     }
3702     scrollableParentInfo_.hasParent = !scrollableParentInfo_.parentIds.empty();
3703     TAG_LOGI(AceLogTag::ACE_WEB, "find scrollable parent %{public}d", scrollableParentInfo_.hasParent);
3704 }
3705 
StopListenSelectOverlayParentScroll(const RefPtr<FrameNode> & host)3706 void WebPattern::StopListenSelectOverlayParentScroll(const RefPtr<FrameNode>& host)
3707 {
3708     CHECK_NULL_VOID(host);
3709     auto context = host->GetContext();
3710     CHECK_NULL_VOID(context);
3711     auto manager = context->GetSelectOverlayManager();
3712     CHECK_NULL_VOID(manager);
3713     manager->RemoveScrollCallback(host->GetId());
3714 }
3715 
RegisterSelectOverlayCallback(SelectOverlayInfo & selectInfo,std::shared_ptr<OHOS::NWeb::NWebQuickMenuParams> params,std::shared_ptr<OHOS::NWeb::NWebQuickMenuCallback> callback)3716 void WebPattern::RegisterSelectOverlayCallback(SelectOverlayInfo& selectInfo,
3717     std::shared_ptr<OHOS::NWeb::NWebQuickMenuParams> params,
3718     std::shared_ptr<OHOS::NWeb::NWebQuickMenuCallback> callback)
3719 {
3720     CHECK_NULL_VOID(delegate_);
3721     auto copyOption = delegate_->GetCopyOptionMode();
3722     quickMenuCallback_ = callback;
3723     uint32_t flags = static_cast<uint32_t>(params->GetEditStateFlags());
3724     if ((flags & OHOS::NWeb::NWebQuickMenuParams::QM_EF_CAN_CUT)
3725         && (copyOption != OHOS::NWeb::NWebPreference::CopyOptionMode::NONE)) {
3726         selectInfo.menuCallback.onCut = [weak = AceType::WeakClaim(this), callback]() {
3727             CHECK_NULL_VOID(callback);
3728             callback->Continue(
3729                 OHOS::NWeb::NWebQuickMenuParams::QM_EF_CAN_CUT, OHOS::NWeb::MenuEventFlags::EF_LEFT_MOUSE_BUTTON);
3730         };
3731     } else {
3732         selectInfo.menuInfo.showCut = false;
3733     }
3734     if ((flags & OHOS::NWeb::NWebQuickMenuParams::QM_EF_CAN_COPY)
3735         && (copyOption != OHOS::NWeb::NWebPreference::CopyOptionMode::NONE)) {
3736         selectInfo.menuCallback.onCopy = [weak = AceType::WeakClaim(this), callback]() {
3737             CHECK_NULL_VOID(callback);
3738             callback->Continue(
3739                 OHOS::NWeb::NWebQuickMenuParams::QM_EF_CAN_COPY, OHOS::NWeb::MenuEventFlags::EF_LEFT_MOUSE_BUTTON);
3740         };
3741     } else {
3742         selectInfo.menuInfo.showCopy = false;
3743     }
3744     if (flags & OHOS::NWeb::NWebQuickMenuParams::QM_EF_CAN_PASTE) {
3745         selectInfo.menuCallback.onPaste = [weak = AceType::WeakClaim(this), callback]() {
3746             CHECK_NULL_VOID(callback);
3747             callback->Continue(
3748                 OHOS::NWeb::NWebQuickMenuParams::QM_EF_CAN_PASTE, OHOS::NWeb::MenuEventFlags::EF_LEFT_MOUSE_BUTTON);
3749         };
3750     } else {
3751         selectInfo.menuInfo.showPaste = false;
3752     }
3753     if (flags & OHOS::NWeb::NWebQuickMenuParams::QM_EF_CAN_SELECT_ALL) {
3754         selectInfo.menuCallback.onSelectAll = [weak = AceType::WeakClaim(this), callback]() {
3755             CHECK_NULL_VOID(callback);
3756             callback->Continue(OHOS::NWeb::NWebQuickMenuParams::QM_EF_CAN_SELECT_ALL,
3757                 OHOS::NWeb::MenuEventFlags::EF_LEFT_MOUSE_BUTTON);
3758         };
3759     } else {
3760         selectInfo.menuInfo.showCopyAll = false;
3761     }
3762 
3763     StartListenSelectOverlayParentScroll(GetHost());
3764 }
3765 
RegisterSelectOverlayEvent(SelectOverlayInfo & selectInfo)3766 void WebPattern::RegisterSelectOverlayEvent(SelectOverlayInfo& selectInfo)
3767 {
3768     selectInfo.onHandleMoveDone = [weak = AceType::WeakClaim(this)](const RectF& rectF, bool isFirst) {
3769         auto webPattern = weak.Upgrade();
3770         CHECK_NULL_VOID(webPattern);
3771         webPattern->HideMagnifier();
3772         webPattern->OnSelectHandleDone(rectF, isFirst);
3773     };
3774     selectInfo.onTouchDown = [weak = AceType::WeakClaim(this)](const TouchEventInfo& info) {};
3775     selectInfo.onTouchUp = [weak = AceType::WeakClaim(this)](const TouchEventInfo& info) {};
3776     selectInfo.onTouchMove = [weak = AceType::WeakClaim(this)](const TouchEventInfo& info) {};
3777     selectInfo.onClick = [weak = AceType::WeakClaim(this)](const GestureEvent& info, bool isFirst) {
3778         auto webPattern = weak.Upgrade();
3779         CHECK_NULL_VOID(webPattern);
3780         webPattern->HandleTouchClickEventFromOverlay(info);
3781     };
3782     selectInfo.onHandleMove = [weak = AceType::WeakClaim(this)](const RectF& handleRect, bool isFirst) {
3783         auto webPattern = weak.Upgrade();
3784         CHECK_NULL_VOID(webPattern);
3785         webPattern->OnSelectHandleMove(handleRect, isFirst);
3786         webPattern->OnMagnifierHandleMove(handleRect, isFirst);
3787     };
3788     selectInfo.onHandleMoveStart = [weak = AceType::WeakClaim(this)](const GestureEvent& event, bool isFirst) {
3789         auto webPattern = weak.Upgrade();
3790         CHECK_NULL_VOID(webPattern);
3791         webPattern->OnSelectHandleStart(event, isFirst);
3792     };
3793     selectInfo.checkIsTouchInHostArea =
3794     [weak = AceType::WeakClaim(this)](const PointF& touchPoint) -> bool {
3795         return true;
3796     };
3797 }
3798 
ComputeMouseClippedSelectionBounds(int32_t x,int32_t y,int32_t w,int32_t h)3799 RectF WebPattern::ComputeMouseClippedSelectionBounds(int32_t x, int32_t y, int32_t w, int32_t h)
3800 {
3801     auto offset = GetCoordinatePoint().value_or(OffsetF());
3802     float selectX = offset.GetX() + x;
3803     float selectY = offset.GetY();
3804     float selectWidth = w;
3805     float selectHeight = h;
3806     if (LessOrEqual(GetHostFrameSize().value_or(SizeF()).Height(), y)) {
3807         selectY += GetHostFrameSize().value_or(SizeF()).Height();
3808     } else if (y + h <= 0) {
3809         selectY -= h;
3810     } else {
3811         selectY += y;
3812     }
3813     return RectF(selectX, selectY, selectWidth, selectHeight);
3814 }
3815 
UpdateClippedSelectionBounds(int32_t x,int32_t y,int32_t w,int32_t h)3816 void WebPattern::UpdateClippedSelectionBounds(int32_t x, int32_t y, int32_t w, int32_t h)
3817 {
3818     selectArea_ = ComputeMouseClippedSelectionBounds(x, y, w, h);
3819     if (selectOverlayProxy_ && isQuickMenuMouseTrigger_) {
3820         selectOverlayProxy_->UpdateSelectArea(selectArea_);
3821     }
3822 }
3823 
SelectCancel() const3824 void WebPattern::SelectCancel() const
3825 {
3826     CHECK_NULL_VOID(quickMenuCallback_);
3827     quickMenuCallback_->Cancel();
3828 }
3829 
IsSelectInfoValid()3830 bool WebPattern::IsSelectInfoValid()
3831 {
3832     auto info = GetSelectInfo();
3833     return !info.empty() && info != STRING_LF;
3834 }
3835 
GetSelectInfo() const3836 std::string WebPattern::GetSelectInfo() const
3837 {
3838     CHECK_NULL_RETURN(delegate_, std::string());
3839     return delegate_->GetSelectInfo();
3840 }
3841 
OnSelectionMenuOptionsUpdate(const WebMenuOptionsParam & webMenuOption)3842 void  WebPattern::OnSelectionMenuOptionsUpdate(const WebMenuOptionsParam& webMenuOption)
3843 {
3844     menuOptionParam_ = std::move(webMenuOption.menuOption);
3845     for (auto& menuOption : menuOptionParam_) {
3846         std::function<void(const std::string&)> action = std::move(menuOption.action);
3847         menuOption.action = [weak = AceType::WeakClaim(this), action] (
3848                                 const std::string selectInfo) {
3849             auto webPattern = weak.Upgrade();
3850             CHECK_NULL_VOID(webPattern);
3851             webPattern->SelectCancel();
3852             std::string selectStr = webPattern->GetSelectInfo();
3853             if (action) {
3854                 action(selectStr);
3855             }
3856         };
3857     }
3858 }
3859 
UpdateEditMenuOptions(const NG::OnCreateMenuCallback && onCreateMenuCallback,const NG::OnMenuItemClickCallback && onMenuItemClick)3860 void WebPattern::UpdateEditMenuOptions(
3861     const NG::OnCreateMenuCallback&& onCreateMenuCallback,
3862     const NG::OnMenuItemClickCallback&& onMenuItemClick)
3863 {
3864     onCreateMenuCallback_ = std::move(onCreateMenuCallback);
3865     onMenuItemClick_ = [weak = AceType::WeakClaim(this), action = std::move(onMenuItemClick)] (
3866                             const OHOS::Ace::NG::MenuItemParam& menuItem) -> bool {
3867         auto webPattern = weak.Upgrade();
3868         bool result = false;
3869         if (action) {
3870             result = action(menuItem);
3871         }
3872         CHECK_NULL_RETURN(webPattern, result);
3873         if (!result && webPattern->IsQuickMenuShow()) {
3874             webPattern->selectOverlayProxy_->ShowOrHiddenMenu(true, true);
3875         }
3876         return result;
3877     };
3878 }
3879 
UpdateRunQuickMenuSelectInfo(SelectOverlayInfo & selectInfo,std::shared_ptr<OHOS::NWeb::NWebQuickMenuParams> params,std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> insertTouchHandle,std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> beginTouchHandle,std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endTouchHandle)3880 void WebPattern::UpdateRunQuickMenuSelectInfo(SelectOverlayInfo& selectInfo,
3881     std::shared_ptr<OHOS::NWeb::NWebQuickMenuParams> params,
3882     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> insertTouchHandle,
3883     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> beginTouchHandle,
3884     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endTouchHandle)
3885 {
3886     selectInfo.hitTestMode = HitTestMode::HTMDEFAULT;
3887     isQuickMenuMouseTrigger_ = false;
3888     if (selectInfo.isSingleHandle) {
3889         selectInfo.firstHandle.paintRect = ComputeTouchHandleRect(insertTouchHandle);
3890         CheckHandles(selectInfo.firstHandle, insertTouchHandle);
3891         selectInfo.secondHandle.isShow = false;
3892     } else {
3893         selectInfo.firstHandle.paintRect = ComputeTouchHandleRect(beginTouchHandle);
3894         selectInfo.secondHandle.paintRect = ComputeTouchHandleRect(endTouchHandle);
3895         CheckHandles(selectInfo.firstHandle, beginTouchHandle);
3896         CheckHandles(selectInfo.secondHandle, endTouchHandle);
3897         QuickMenuIsNeedNewAvoid(selectInfo, params, beginTouchHandle, endTouchHandle);
3898         if (!(onCreateMenuCallback_ && onMenuItemClick_)) {
3899             selectInfo.menuOptionItems = menuOptionParam_;
3900         }
3901     }
3902     selectInfo.menuInfo.menuIsShow = true;
3903     selectInfo.handleReverse = false;
3904     if (onCreateMenuCallback_ && onMenuItemClick_) {
3905         selectInfo.onCreateCallback.onCreateMenuCallback = onCreateMenuCallback_;
3906         selectInfo.onCreateCallback.onMenuItemClick = onMenuItemClick_;
3907         auto textRange = [](int32_t& start, int32_t& end) {
3908             start = -1;
3909             end = -1;
3910         };
3911         selectInfo.onCreateCallback.textRangeCallback = textRange;
3912     }
3913 }
3914 
HideHandleAndQuickMenuIfNecessary(bool hide,bool isScroll)3915 void WebPattern::HideHandleAndQuickMenuIfNecessary(bool hide, bool isScroll)
3916 {
3917     WebOverlayType overlayType = GetTouchHandleOverlayType(insertHandle_, startSelectionHandle_, endSelectionHandle_);
3918     TAG_LOGI(AceLogTag::ACE_WEB,
3919         "HideHandleAndQuickMenuIfNecessary hide:%{public}d, overlayType:%{public}d, isScroll:%{public}d",
3920         hide, overlayType, isScroll);
3921     if (overlayType != SELECTION_OVERLAY) {
3922         return;
3923     }
3924     SelectHandleInfo firstInfo;
3925     SelectHandleInfo secondInfo;
3926     if (!isScroll) {
3927         selectTemporarilyHidden_ = hide;
3928         if (selectTemporarilyHiddenByScroll_) {
3929             return;
3930         }
3931     }
3932     if (hide) {
3933         if (selectOverlayProxy_) {
3934             selectOverlayProxy_->ShowOrHiddenMenu(true, true);
3935             firstInfo.isShow = false;
3936             firstInfo.paintRect = ComputeTouchHandleRect(startSelectionHandle_);
3937             secondInfo.isShow = false;
3938             secondInfo.paintRect = ComputeTouchHandleRect(endSelectionHandle_);
3939             selectOverlayProxy_->UpdateFirstAndSecondHandleInfo(firstInfo, secondInfo);
3940         }
3941     } else {
3942         if (!selectOverlayProxy_ || selectOverlayProxy_->IsMenuShow()) {
3943             return;
3944         }
3945         firstInfo.paintRect = ComputeTouchHandleRect(startSelectionHandle_);
3946         secondInfo.paintRect = ComputeTouchHandleRect(endSelectionHandle_);
3947         CheckHandles(firstInfo, startSelectionHandle_);
3948         CheckHandles(secondInfo, endSelectionHandle_);
3949         if (firstInfo.isShow || secondInfo.isShow) {
3950             selectOverlayProxy_->SetIsNewAvoid(false);
3951         } else if (dropParams_) {
3952             bool isNewAvoid = false;
3953             auto selectArea = ComputeClippedSelectionBounds(
3954                 dropParams_, startSelectionHandle_, endSelectionHandle_, isNewAvoid);
3955             selectOverlayProxy_->SetIsNewAvoid(isNewAvoid);
3956             selectOverlayProxy_->UpdateSelectArea(selectArea);
3957         }
3958         selectOverlayProxy_->UpdateFirstAndSecondHandleInfo(firstInfo, secondInfo);
3959         selectOverlayProxy_->ShowOrHiddenMenu(false);
3960     }
3961 }
3962 
ChangeVisibilityOfQuickMenu()3963 void WebPattern::ChangeVisibilityOfQuickMenu()
3964 {
3965     CHECK_NULL_VOID(selectOverlayProxy_);
3966     WebOverlayType overlayType = GetTouchHandleOverlayType(insertHandle_, startSelectionHandle_, endSelectionHandle_);
3967     if (overlayType == SELECTION_OVERLAY && !selectTemporarilyHidden_ && !selectTemporarilyHiddenByScroll_) {
3968         bool isMenuShow = selectOverlayProxy_->IsMenuShow();
3969         selectOverlayProxy_->ShowOrHiddenMenu(isMenuShow);
3970         TAG_LOGI(AceLogTag::ACE_WEB, "Current menu display status is %{public}d.", isMenuShow);
3971     }
3972 }
3973 
IsQuickMenuShow()3974 bool WebPattern::IsQuickMenuShow()
3975 {
3976     CHECK_NULL_RETURN(selectOverlayProxy_, false);
3977     return selectOverlayProxy_->IsMenuShow();
3978 }
3979 
RunQuickMenu(std::shared_ptr<OHOS::NWeb::NWebQuickMenuParams> params,std::shared_ptr<OHOS::NWeb::NWebQuickMenuCallback> callback)3980 bool WebPattern::RunQuickMenu(std::shared_ptr<OHOS::NWeb::NWebQuickMenuParams> params,
3981     std::shared_ptr<OHOS::NWeb::NWebQuickMenuCallback> callback)
3982 {
3983     CHECK_NULL_RETURN(params, false);
3984     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> insertTouchHandle =
3985         params->GetTouchHandleState(OHOS::NWeb::NWebTouchHandleState::TouchHandleType::INSERT_HANDLE);
3986     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> beginTouchHandle =
3987         params->GetTouchHandleState(OHOS::NWeb::NWebTouchHandleState::TouchHandleType::SELECTION_BEGIN_HANDLE);
3988     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endTouchHandle =
3989         params->GetTouchHandleState(OHOS::NWeb::NWebTouchHandleState::TouchHandleType::SELECTION_END_HANDLE);
3990     WebOverlayType overlayType = GetTouchHandleOverlayType(insertTouchHandle, beginTouchHandle, endTouchHandle);
3991     if (overlayType == INVALID_OVERLAY) {
3992         return false;
3993     }
3994     if (params->GetIsLongPressActived()) {
3995         ShowMagnifier(static_cast<int>(touchPointX), static_cast<int>(touchPointY));
3996         return false;
3997     }
3998     if (selectOverlayProxy_) {
3999         CloseSelectOverlay();
4000     }
4001     selectTemporarilyHidden_ = false;
4002     selectTemporarilyHiddenByScroll_ = false;
4003     auto pipeline = PipelineContext::GetCurrentContext();
4004     CHECK_NULL_RETURN(pipeline, false);
4005     SelectOverlayInfo selectInfo;
4006     RegisterSelectOverLayOnClose(selectInfo);
4007     selectInfo.isSingleHandle = (overlayType == INSERT_OVERLAY);
4008     UpdateRunQuickMenuSelectInfo(selectInfo, params, insertTouchHandle, beginTouchHandle, endTouchHandle);
4009     if (isQuickMenuMouseTrigger_) {
4010         return false;
4011     }
4012     RegisterSelectOverlayCallback(selectInfo, params, callback);
4013     RegisterSelectOverlayEvent(selectInfo);
4014     selectOverlayProxy_ = pipeline->GetSelectOverlayManager()->CreateAndShowSelectOverlay(selectInfo, WeakClaim(this));
4015     if (selectInfo.isNewAvoid && selectOverlayProxy_) {
4016         selectOverlayProxy_->ShowOrHiddenMenu(false);
4017     }
4018     if (selectOverlayProxy_) {
4019         selectOverlayProxy_->SetHandleReverse(false);
4020     }
4021     dropParams_ = params;
4022     selectMenuInfo_ = selectInfo.menuInfo;
4023     insertHandle_ = insertTouchHandle;
4024     startSelectionHandle_ = beginTouchHandle;
4025     endSelectionHandle_ = endTouchHandle;
4026     if (selectOverlayProxy_) {
4027         DestroyAnalyzerOverlay();
4028         return true;
4029     }
4030     return false;
4031 }
4032 
ShowMagnifier(int centerOffsetX,int centerOffsetY)4033 void WebPattern::ShowMagnifier(int centerOffsetX, int centerOffsetY)
4034 {
4035     if (magnifierController_) {
4036         OffsetF localOffset = OffsetF(centerOffsetX, centerOffsetY);
4037         magnifierController_->SetLocalOffset(localOffset);
4038     }
4039 }
4040 
HideMagnifier()4041 void WebPattern::HideMagnifier()
4042 {
4043     if (magnifierController_) {
4044         magnifierController_->RemoveMagnifierFrameNode();
4045     }
4046 }
4047 
GetTextPaintOffset() const4048 OffsetF WebPattern::GetTextPaintOffset() const
4049 {
4050     auto frameNode = GetHost();
4051     CHECK_NULL_RETURN(frameNode, OffsetF());
4052     return frameNode->GetTransformRelativeOffset();
4053 }
4054 
RegisterSelectOverLayOnClose(SelectOverlayInfo & selectInfo)4055 void WebPattern::RegisterSelectOverLayOnClose(SelectOverlayInfo& selectInfo)
4056 {
4057     selectInfo.onClose = [weak = AceType::WeakClaim(this)] (bool isGlobalTouchEvent) {
4058         if (!isGlobalTouchEvent) {
4059             return;
4060         }
4061         TAG_LOGI(AceLogTag::ACE_WEB, "globalTouchEvent, close web select overLayer.");
4062         auto webPattern = weak.Upgrade();
4063         CHECK_NULL_VOID(webPattern);
4064         webPattern->CloseSelectOverlay();
4065         webPattern->SelectCancel();
4066     };
4067 }
4068 
ComputeClippedSelectionBounds(std::shared_ptr<OHOS::NWeb::NWebQuickMenuParams> params,std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> startHandle,std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endHandle,bool & isNewAvoid)4069 RectF WebPattern::ComputeClippedSelectionBounds(
4070     std::shared_ptr<OHOS::NWeb::NWebQuickMenuParams> params,
4071     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> startHandle,
4072     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endHandle,
4073     bool& isNewAvoid)
4074 {
4075     auto pipeline = PipelineBase::GetCurrentContext();
4076     CHECK_NULL_RETURN(pipeline, RectF());
4077     auto host = GetHost();
4078     CHECK_NULL_RETURN(host, RectF());
4079 
4080     float selectX = params->GetSelectX();
4081     float selectY = params->GetSelectY();
4082     float selectWidth = params->GetSelectWidth();
4083     float selectHeight = params->GetSelectXHeight();
4084     float viewPortX = static_cast<float>((startHandle->GetViewPortX() + endHandle->GetViewPortX())) / 2;
4085     float viewPortY = static_cast<float>((startHandle->GetViewPortY() + endHandle->GetViewPortY())) / 2;
4086     auto offset = GetCoordinatePoint().value_or(OffsetF());
4087 
4088     RectF visibleRect;
4089     RectF visibleInnerRect;
4090     RectF frameRect;
4091     host->GetVisibleRectWithClip(visibleRect, visibleInnerRect, frameRect);
4092     auto visibleTop = visibleInnerRect.Top();
4093     auto visibleBottom = visibleInnerRect.Bottom();
4094 
4095     isNewAvoid = true;
4096     if (LessOrEqual(visibleBottom, selectY + viewPortY + offset.GetY()) ||
4097         LessOrEqual(selectY + selectHeight + offset.GetY(), visibleTop)) {
4098         TAG_LOGI(AceLogTag::ACE_WEB, "Selected area not visible, Do not display menu");
4099         isNewAvoid = false;
4100         return RectF();
4101     } else if (LessOrEqual(selectY + offset.GetY(), visibleTop) &&
4102         LessOrEqual(visibleBottom, selectY + viewPortY + selectHeight + offset.GetY())) {
4103         TAG_LOGI(AceLogTag::ACE_WEB, "Center menu display");
4104         return RectF(offset.GetX(), offset.GetY(), drawSize_.Width(), drawSize_.Height());
4105     }
4106 
4107     auto theme = pipeline->GetTheme<TextOverlayTheme>();
4108     float radius = theme ? theme->GetHandleHotZoneRadius().ConvertToPx() : 0.0;
4109     if (LessOrEqual(visibleBottom, selectY + viewPortY + startHandle->GetEdgeHeight() + offset.GetY())) {
4110         selectX = startHandle->GetX() + offset.GetX();
4111         selectY = startHandle->GetY() + offset.GetY() - radius - startHandle->GetEdgeHeight() - SELECT_MENE_HEIGHT;
4112         selectWidth = SelectHandleInfo::GetDefaultLineWidth().ConvertToPx();
4113     } else if (LessOrEqual(selectY + selectHeight - endHandle->GetEdgeHeight() + offset.GetY(), visibleTop)) {
4114         selectX = endHandle->GetX() + offset.GetX();
4115         selectY = endHandle->GetY() + offset.GetY() + radius;
4116         selectWidth = SelectHandleInfo::GetDefaultLineWidth().ConvertToPx();
4117     } else {
4118         selectX = selectX + viewPortX + offset.GetX();
4119         selectY = selectY + viewPortY + offset.GetY() - SELECT_MENE_HEIGHT - radius;
4120         if (selectY < offset.GetY()) {
4121             selectY = offset.GetY();
4122         }
4123     }
4124     TAG_LOGI(AceLogTag::ACE_WEB, "SelectionBounds pos: (%{public}f, %{public}f)", selectX, selectY);
4125     return RectF(selectX, selectY, selectWidth, SELECT_MENE_HEIGHT);
4126 }
4127 
QuickMenuIsNeedNewAvoid(SelectOverlayInfo & selectInfo,std::shared_ptr<OHOS::NWeb::NWebQuickMenuParams> params,std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> startHandle,std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endHandle)4128 void WebPattern::QuickMenuIsNeedNewAvoid(
4129     SelectOverlayInfo& selectInfo,
4130     std::shared_ptr<OHOS::NWeb::NWebQuickMenuParams> params,
4131     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> startHandle,
4132     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endHandle)
4133 {
4134     isQuickMenuMouseTrigger_ = false;
4135     if (!selectInfo.firstHandle.isShow && !selectInfo.secondHandle.isShow) {
4136         selectInfo.isNewAvoid = true;
4137         if ((startHandle->GetEdgeHeight() == 0 && startHandle->GetTouchHandleId() == -1) &&
4138             (endHandle->GetEdgeHeight() == 0 && endHandle->GetTouchHandleId() == -1)) {
4139             isQuickMenuMouseTrigger_ = true;
4140             selectInfo.selectArea =
4141                 ComputeMouseClippedSelectionBounds(params->GetSelectX(),
4142                                                    params->GetSelectY(),
4143                                                    params->GetSelectWidth(),
4144                                                    params->GetSelectXHeight());
4145             selectArea_ = selectInfo.selectArea;
4146         } else {
4147             selectInfo.selectArea =
4148                 ComputeClippedSelectionBounds(params, startHandle, endHandle, selectInfo.isNewAvoid);
4149         }
4150     }
4151 }
4152 
OnQuickMenuDismissed()4153 void WebPattern::OnQuickMenuDismissed()
4154 {
4155     CloseSelectOverlay();
4156 }
4157 
DumpViewDataPageNode(RefPtr<ViewDataWrap> viewDataWrap,bool needsRecordData)4158 void WebPattern::DumpViewDataPageNode(RefPtr<ViewDataWrap> viewDataWrap, bool needsRecordData)
4159 {
4160     TAG_LOGI(AceLogTag::ACE_WEB, "called");
4161     CHECK_NULL_VOID(viewDataWrap);
4162     for (const auto& nodeInfo : pageNodeInfo_) {
4163         if (nodeInfo) {
4164             viewDataWrap->AddPageNodeInfoWrap(nodeInfo);
4165         }
4166     }
4167     viewDataWrap->SetPageUrl(viewDataCommon_.pageUrl);
4168     viewDataWrap->SetUserSelected(viewDataCommon_.isUserSelected);
4169     viewDataWrap->SetOtherAccount(viewDataCommon_.isOtherAccount);
4170 }
4171 
NotifyFillRequestSuccess(RefPtr<ViewDataWrap> viewDataWrap,RefPtr<PageNodeInfoWrap> nodeWrap,AceAutoFillType autoFillType)4172 void WebPattern::NotifyFillRequestSuccess(RefPtr<ViewDataWrap> viewDataWrap,
4173     RefPtr<PageNodeInfoWrap> nodeWrap, AceAutoFillType autoFillType)
4174 {
4175     TAG_LOGI(AceLogTag::ACE_WEB, "called");
4176     CHECK_NULL_VOID(viewDataWrap);
4177     auto nodeInfoWraps = viewDataWrap->GetPageNodeInfoWraps();
4178     auto jsonNode = JsonUtil::Create(true);
4179     AceAutoFillType focusType = AceAutoFillType::ACE_UNSPECIFIED;
4180     for (const auto& nodeInfoWrap : nodeInfoWraps) {
4181         if (nodeInfoWrap == nullptr) {
4182             continue;
4183         }
4184         auto type = nodeInfoWrap->GetAutoFillType();
4185         // white list check
4186         if (ACE_AUTOFILL_TYPE_TO_NWEB.count(type) != 0) {
4187             std::string key = ACE_AUTOFILL_TYPE_TO_NWEB.at(type);
4188             if (nodeInfoWrap->GetMetadata() != IS_HINT_TYPE) {
4189                 jsonNode->Put(key.c_str(), nodeInfoWrap->GetValue().c_str());
4190             } else {
4191                 auto json = JsonUtil::Create(true);
4192                 json->Put(OHOS::NWeb::NWEB_VIEW_DATA_KEY_PLACEHOLDER.c_str(), nodeInfoWrap->GetId());
4193                 json->Put(OHOS::NWeb::NWEB_VIEW_DATA_KEY_VALUE.c_str(), nodeInfoWrap->GetValue().c_str());
4194                 jsonNode->Put(key.c_str(), std::move(json));
4195             }
4196         }
4197         if (nodeInfoWrap->GetIsFocus()) {
4198             focusType = type;
4199         }
4200     }
4201     auto pageUrl = viewDataWrap->GetPageUrl();
4202     jsonNode->Put(AUTO_FILL_VIEW_DATA_PAGE_URL.c_str(), pageUrl.c_str());
4203     auto otherAccount = viewDataWrap->GetOtherAccount();
4204     jsonNode->Put(AUTO_FILL_VIEW_DATA_OTHER_ACCOUNT.c_str(), otherAccount);
4205     delegate_->NotifyAutoFillViewData(jsonNode->ToString());
4206 
4207     // shift focus after autofill
4208     if (focusType != AceAutoFillType::ACE_UNSPECIFIED && !isPasswordFill_) {
4209         for (const auto& nodeInfo : pageNodeInfo_) {
4210             if (nodeInfo && nodeInfo->GetAutoFillType() == focusType) {
4211                 TouchEventInfo info("autofill");
4212                 TouchLocationInfo location("autofill", 0);
4213                 auto rectF = nodeInfo->GetPageNodeRect();
4214                 location.SetLocalLocation(Offset(rectF.GetX() + (rectF.Width() / POPUP_CALCULATE_RATIO),
4215                     rectF.GetY() + (rectF.Height() / POPUP_CALCULATE_RATIO)));
4216                 info.AddChangedTouchLocationInfo(std::move(location));
4217                 HandleTouchDown(info, false);
4218                 HandleTouchUp(info, false);
4219                 break;
4220             }
4221         }
4222     }
4223 }
4224 
NotifyFillRequestFailed(int32_t errCode,const std::string & fillContent,bool isPopup)4225 void WebPattern::NotifyFillRequestFailed(int32_t errCode, const std::string& fillContent, bool isPopup)
4226 {
4227     TAG_LOGI(AceLogTag::ACE_WEB, "called, errCode:%{public}d", errCode);
4228     if (isPasswordFill_) {
4229         delegate_->AutofillCancel(fillContent);
4230     }
4231 }
4232 
ParseViewDataNumber(const std::string & key,int32_t value,RefPtr<PageNodeInfoWrap> node,RectT<float> & rect,float viewScale)4233 void WebPattern::ParseViewDataNumber(const std::string& key, int32_t value,
4234     RefPtr<PageNodeInfoWrap> node, RectT<float>& rect, float viewScale)
4235 {
4236     CHECK_NULL_VOID(viewScale > FLT_EPSILON);
4237     CHECK_NULL_VOID(node);
4238     if (key == OHOS::NWeb::NWEB_VIEW_DATA_KEY_FOCUS) {
4239         node->SetIsFocus(static_cast<bool>(value));
4240     } else if (key == OHOS::NWeb::NWEB_VIEW_DATA_KEY_RECT_X) {
4241         rect.SetLeft(value / viewScale);
4242     } else if (key == OHOS::NWeb::NWEB_VIEW_DATA_KEY_RECT_Y) {
4243         rect.SetTop(value / viewScale);
4244     } else if (key == OHOS::NWeb::NWEB_VIEW_DATA_KEY_RECT_W) {
4245         rect.SetWidth(value / viewScale);
4246     } else if (key == OHOS::NWeb::NWEB_VIEW_DATA_KEY_RECT_H) {
4247         rect.SetHeight(value / viewScale);
4248     }
4249 }
4250 
ParseViewDataString(const std::string & key,const std::string & value,RefPtr<PageNodeInfoWrap> node)4251 void ParseViewDataString(const std::string& key,
4252     const std::string& value, RefPtr<PageNodeInfoWrap> node)
4253 {
4254     CHECK_NULL_VOID(node);
4255     if (key == OHOS::NWeb::NWEB_VIEW_DATA_KEY_VALUE) {
4256         node->SetValue(value);
4257     } else if (key == OHOS::NWeb::NWEB_VIEW_DATA_KEY_PLACEHOLDER) {
4258         node->SetPlaceholder(value);
4259     }
4260 }
4261 
GetHintTypeAndMetadata(const std::string & attribute,RefPtr<PageNodeInfoWrap> node)4262 HintToTypeWrap WebPattern::GetHintTypeAndMetadata(const std::string& attribute, RefPtr<PageNodeInfoWrap> node)
4263 {
4264     HintToTypeWrap hintToTypeWrap;
4265     auto placeholder = node->GetPlaceholder();
4266     if (NWEB_AUTOFILL_TYPE_TO_ACE.count(attribute) != 0) {
4267         AceAutoFillType type = NWEB_AUTOFILL_TYPE_TO_ACE.at(attribute);
4268         if (node->GetIsFocus()) {
4269             if (type == AceAutoFillType::ACE_USER_NAME || type == AceAutoFillType::ACE_PASSWORD ||
4270                 type == AceAutoFillType::ACE_NEW_PASSWORD) {
4271                 TAG_LOGI(AceLogTag::ACE_WEB, "The form is login fill form");
4272                 isPasswordFill_ = true;
4273             }
4274         }
4275         hintToTypeWrap.autoFillType = type;
4276     } else if (!placeholder.empty()) {
4277         // try hint2Type
4278         auto host = GetHost();
4279         CHECK_NULL_RETURN(host, hintToTypeWrap);
4280         auto container = Container::Current();
4281         if (container == nullptr) {
4282             container = Container::GetActive();
4283         }
4284         CHECK_NULL_RETURN(container, hintToTypeWrap);
4285         hintToTypeWrap = container->PlaceHolderToType(placeholder);
4286     }
4287     return hintToTypeWrap;
4288 }
4289 
ParseNWebViewDataNode(std::unique_ptr<JsonValue> child,std::vector<RefPtr<PageNodeInfoWrap>> & nodeInfos,int32_t nodeId)4290 void WebPattern::ParseNWebViewDataNode(std::unique_ptr<JsonValue> child,
4291     std::vector<RefPtr<PageNodeInfoWrap>>& nodeInfos, int32_t nodeId)
4292 {
4293     auto host = GetHost();
4294     CHECK_NULL_VOID(host);
4295     auto pipelineContext = host->GetContextRefPtr();
4296     CHECK_NULL_VOID(pipelineContext);
4297     float viewScale = pipelineContext->GetViewScale();
4298     CHECK_NULL_VOID(viewScale > FLT_EPSILON);
4299 
4300     RefPtr<PageNodeInfoWrap> node = PageNodeInfoWrap::CreatePageNodeInfoWrap();
4301     std::string attribute = child->GetKey();
4302 
4303     RectT<float> rect;
4304     int32_t len = child->GetArraySize();
4305     for (int32_t index = 0; index < len; index++) {
4306         auto object = child->GetArrayItem(index);
4307         if (object == nullptr || !object->IsObject()) {
4308             continue;
4309         }
4310         for (auto child = object->GetChild(); child && !child->IsNull(); child = child->GetNext()) {
4311             if (child->IsString()) {
4312                 ParseViewDataString(child->GetKey(), child->GetString(), node);
4313             } else if (child->IsNumber()) {
4314                 ParseViewDataNumber(child->GetKey(), child->GetInt(), node, rect, viewScale);
4315             }
4316         }
4317     }
4318 
4319     HintToTypeWrap hintToTypeWrap = GetHintTypeAndMetadata(attribute, node);
4320     auto type = hintToTypeWrap.autoFillType;
4321     if (type != AceAutoFillType::ACE_UNSPECIFIED) {
4322         node->SetAutoFillType(type);
4323         node->SetMetadata(hintToTypeWrap.metadata);
4324     } else {
4325         return;
4326     }
4327 
4328     NG::RectF rectF;
4329     rectF.SetRect(rect.GetX(), rect.GetY(), rect.Width(), rect.Height());
4330     node->SetPageNodeRect(rectF);
4331     node->SetId(nodeId);
4332     node->SetDepth(-1);
4333     nodeInfos.emplace_back(node);
4334 }
4335 
ParseNWebViewDataCommonField(std::unique_ptr<JsonValue> child,ViewDataCommon & viewDataCommon)4336 void WebPattern::ParseNWebViewDataCommonField(std::unique_ptr<JsonValue> child, ViewDataCommon& viewDataCommon)
4337 {
4338     std::string key = child->GetKey();
4339     if (child->IsString() && key == OHOS::NWeb::NWEB_AUTOFILL_EVENT_TYPE) {
4340         std::string eventType = child->GetString();
4341         if (NWEB_AUTOFILL_EVENTS.count(eventType) != 0) {
4342             OHOS::NWeb::NWebAutofillEvent event = NWEB_AUTOFILL_EVENTS.at(eventType);
4343             viewDataCommon.eventType = event;
4344         }
4345     }
4346     if (child->IsString() && key == OHOS::NWeb::NWEB_AUTOFILL_PAGE_URL) {
4347         viewDataCommon.pageUrl = child->GetString();
4348     }
4349     if (child->IsBool() && key == OHOS::NWeb::NWEB_AUTOFILL_IS_USER_SELECTED) {
4350         viewDataCommon.isUserSelected = child->GetBool();
4351     }
4352     if (child->IsBool() && key == OHOS::NWeb::NWEB_AUTOFILL_IS_OTHER_ACCOUNT) {
4353         viewDataCommon.isOtherAccount = child->GetBool();
4354     }
4355     if (child->IsString() && key == OHOS::NWeb::NWEB_AUTOFILL_EVENT_SOURCE) {
4356         viewDataCommon.source = child->GetString();
4357     }
4358 }
4359 
ParseNWebViewDataJson(const std::shared_ptr<OHOS::NWeb::NWebMessage> & viewDataJson,std::vector<RefPtr<PageNodeInfoWrap>> & nodeInfos,ViewDataCommon & viewDataCommon)4360 void WebPattern::ParseNWebViewDataJson(const std::shared_ptr<OHOS::NWeb::NWebMessage>& viewDataJson,
4361     std::vector<RefPtr<PageNodeInfoWrap>>& nodeInfos, ViewDataCommon& viewDataCommon)
4362 {
4363     nodeInfos.clear();
4364     auto sourceJson = JsonUtil::ParseJsonString(viewDataJson->GetString());
4365     if (sourceJson == nullptr || sourceJson->IsNull()) {
4366         return;
4367     }
4368 
4369     int32_t nodeId = 1;
4370     int32_t len = sourceJson->GetArraySize();
4371     for (int32_t index = 0; index < len; index++) {
4372         auto object = sourceJson->GetArrayItem(index);
4373         if (object == nullptr || !object->IsObject()) {
4374             continue;
4375         }
4376         auto child = object->GetChild();
4377         if (child == nullptr || child->IsNull()) {
4378             continue;
4379         }
4380         if (child->IsArray()) {
4381             ParseNWebViewDataNode(std::move(child), nodeInfos, nodeId);
4382             nodeId++;
4383         } else {
4384             ParseNWebViewDataCommonField(std::move(child), viewDataCommon);
4385         }
4386     }
4387 }
4388 
GetFocusedType()4389 AceAutoFillType WebPattern::GetFocusedType()
4390 {
4391     AceAutoFillType type = AceAutoFillType::ACE_UNSPECIFIED;
4392     for (const auto& nodeInfo : pageNodeInfo_) {
4393         if (nodeInfo && nodeInfo->GetIsFocus()) {
4394             type = static_cast<AceAutoFillType>(nodeInfo->GetAutoFillType());
4395             break;
4396         }
4397     }
4398     return type;
4399 }
4400 
HandleAutoFillEvent(const std::shared_ptr<OHOS::NWeb::NWebMessage> & viewDataJson)4401 bool WebPattern::HandleAutoFillEvent(const std::shared_ptr<OHOS::NWeb::NWebMessage>& viewDataJson)
4402 {
4403     TAG_LOGI(AceLogTag::ACE_WEB, "AutoFillEvent");
4404     viewDataCommon_ = {};
4405     isPasswordFill_ = false;
4406     ParseNWebViewDataJson(viewDataJson, pageNodeInfo_, viewDataCommon_);
4407 
4408     if (isPasswordFill_ && viewDataCommon_.source != OHOS::NWeb::NWEB_AUTOFILL_FOR_LOGIN) {
4409         TAG_LOGI(AceLogTag::ACE_WEB,
4410             "Handle autofill event failed! The form contains a login node, but the soruce is incorrect.");
4411         return false;
4412     }
4413 
4414     auto eventType = viewDataCommon_.eventType;
4415 
4416     if (eventType == OHOS::NWeb::NWebAutofillEvent::FILL) {
4417         auto host = GetHost();
4418         CHECK_NULL_RETURN(host, false);
4419         auto context = host->GetContext();
4420         CHECK_NULL_RETURN(context, false);
4421         auto taskExecutor = context->GetTaskExecutor();
4422         CHECK_NULL_RETURN(taskExecutor, false);
4423         bool fillRet = taskExecutor->PostDelayedTask(
4424             [weak = WeakClaim(this)] () {
4425                 auto pattern = weak.Upgrade();
4426                 CHECK_NULL_RETURN(pattern, false);
4427                 return pattern->RequestAutoFill(pattern->GetFocusedType());
4428             },
4429             TaskExecutor::TaskType::UI, AUTOFILL_DELAY_TIME, "ArkUIWebHandleAutoFillEvent");
4430         return fillRet;
4431     }
4432 
4433     if (eventType == OHOS::NWeb::NWebAutofillEvent::SAVE) {
4434         return RequestAutoSave();
4435     } else if (eventType == OHOS::NWeb::NWebAutofillEvent::UPDATE) {
4436         return UpdateAutoFillPopup();
4437     } else if (eventType == OHOS::NWeb::NWebAutofillEvent::CLOSE) {
4438         return CloseAutoFillPopup();
4439     }
4440 
4441     return false;
4442 }
4443 
RequestAutoFill(AceAutoFillType autoFillType)4444 bool WebPattern::RequestAutoFill(AceAutoFillType autoFillType)
4445 {
4446     TAG_LOGI(AceLogTag::ACE_WEB, "RequestAutoFill");
4447     auto host = GetHost();
4448     CHECK_NULL_RETURN(host, false);
4449     auto context = host->GetContext();
4450     CHECK_NULL_RETURN(context, false);
4451     auto instanceId = context->GetInstanceId();
4452     CHECK_NULL_RETURN(instanceId, false);
4453     ContainerScope scope(instanceId);
4454 
4455     auto offset = GetCoordinatePoint().value_or(OffsetF());
4456     for (auto& nodeInfo : pageNodeInfo_) {
4457         auto rect = nodeInfo->GetPageNodeRect();
4458         NG::RectF rectF;
4459         rectF.SetRect(rect.GetX() + offset.GetX(), rect.GetY()+ offset.GetY(), rect.Width(), rect.Height());
4460         nodeInfo->SetPageNodeRect(rectF);
4461     }
4462 
4463     auto container = Container::Current();
4464     if (container == nullptr) {
4465         container = Container::GetActive();
4466     }
4467     CHECK_NULL_RETURN(container, false);
4468     isAutoFillClosing_ = false;
4469     bool isPopup = false;
4470     return container->RequestAutoFill(host, autoFillType, false, isPopup, autoFillSessionId_, false);
4471 }
4472 
RequestAutoSave()4473 bool WebPattern::RequestAutoSave()
4474 {
4475     TAG_LOGI(AceLogTag::ACE_WEB, "RequestAutoSave");
4476     auto host = GetHost();
4477     CHECK_NULL_RETURN(host, false);
4478     auto context = host->GetContext();
4479     CHECK_NULL_RETURN(context, false);
4480     auto instanceId = context->GetInstanceId();
4481     CHECK_NULL_RETURN(instanceId, false);
4482     ContainerScope scope(instanceId);
4483     auto container = Container::Current();
4484     if (container == nullptr) {
4485         container = Container::GetActive();
4486     }
4487     CHECK_NULL_RETURN(container, false);
4488     return container->RequestAutoSave(host, nullptr, nullptr, false);
4489 }
4490 
UpdateAutoFillPopup()4491 bool WebPattern::UpdateAutoFillPopup()
4492 {
4493     TAG_LOGI(AceLogTag::ACE_WEB, "UpdateAutoFillPopup");
4494     if (isAutoFillClosing_) {
4495         return false;
4496     }
4497     auto host = GetHost();
4498     CHECK_NULL_RETURN(host, false);
4499     auto context = host->GetContext();
4500     CHECK_NULL_RETURN(context, false);
4501     auto instanceId = context->GetInstanceId();
4502     CHECK_NULL_RETURN(instanceId, false);
4503     ContainerScope scope(instanceId);
4504     auto container = Container::Current();
4505     if (container == nullptr) {
4506         container = Container::GetActive();
4507     }
4508     CHECK_NULL_RETURN(container, false);
4509     return container->UpdatePopupUIExtension(host, autoFillSessionId_, false);
4510 }
4511 
CloseAutoFillPopup()4512 bool WebPattern::CloseAutoFillPopup()
4513 {
4514     TAG_LOGI(AceLogTag::ACE_WEB, "CloseAutoFillPopup");
4515     auto host = GetHost();
4516     CHECK_NULL_RETURN(host, false);
4517     auto context = host->GetContext();
4518     CHECK_NULL_RETURN(context, false);
4519     auto instanceId = context->GetInstanceId();
4520     CHECK_NULL_RETURN(instanceId, false);
4521     ContainerScope scope(instanceId);
4522     auto container = Container::Current();
4523     if (container == nullptr) {
4524         container = Container::GetActive();
4525     }
4526     CHECK_NULL_RETURN(container, false);
4527     isAutoFillClosing_ = true;
4528     return container->ClosePopupUIExtension(autoFillSessionId_);
4529 }
4530 
UpdateSelectHandleInfo()4531 void WebPattern::UpdateSelectHandleInfo()
4532 {
4533     bool needReverse = IsSelectHandleReverse();
4534     SelectHandleInfo handleInfo;
4535     if (!needReverse) {
4536         if (!isCurrentStartHandleDragging_) {
4537             handleInfo.paintRect = ComputeTouchHandleRect(startSelectionHandle_);
4538             CheckHandles(handleInfo, startSelectionHandle_);
4539             selectOverlayProxy_->UpdateFirstSelectHandleInfo(handleInfo);
4540         } else {
4541             handleInfo.paintRect = ComputeTouchHandleRect(endSelectionHandle_);
4542             CheckHandles(handleInfo, endSelectionHandle_);
4543             selectOverlayProxy_->UpdateSecondSelectHandleInfo(handleInfo);
4544         }
4545     } else {
4546         if (!isCurrentStartHandleDragging_) {
4547             handleInfo.paintRect = ComputeTouchHandleRect(endSelectionHandle_);
4548             CheckHandles(handleInfo, endSelectionHandle_);
4549             selectOverlayProxy_->UpdateFirstSelectHandleInfo(handleInfo);
4550         } else {
4551             handleInfo.paintRect = ComputeTouchHandleRect(startSelectionHandle_);
4552             CheckHandles(handleInfo, startSelectionHandle_);
4553             selectOverlayProxy_->UpdateSecondSelectHandleInfo(handleInfo);
4554         }
4555     }
4556 }
4557 
IsSelectHandleReverse()4558 bool WebPattern::IsSelectHandleReverse()
4559 {
4560     if (startSelectionHandle_->GetTouchHandleType() ==
4561         OHOS::NWeb::NWebTouchHandleState::SELECTION_BEGIN_HANDLE &&
4562         endSelectionHandle_->GetTouchHandleType() ==
4563         OHOS::NWeb::NWebTouchHandleState::SELECTION_BEGIN_HANDLE) {
4564         return true;
4565     } else if (startSelectionHandle_->GetTouchHandleType() ==
4566         OHOS::NWeb::NWebTouchHandleState::SELECTION_END_HANDLE &&
4567         endSelectionHandle_->GetTouchHandleType() ==
4568         OHOS::NWeb::NWebTouchHandleState::SELECTION_END_HANDLE) {
4569         return true;
4570     }
4571     return false;
4572 }
4573 
OnTouchSelectionChanged(std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> insertHandle,std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> startSelectionHandle,std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endSelectionHandle)4574 void WebPattern::OnTouchSelectionChanged(std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> insertHandle,
4575     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> startSelectionHandle,
4576     std::shared_ptr<OHOS::NWeb::NWebTouchHandleState> endSelectionHandle)
4577 {
4578     WebOverlayType overlayType = GetTouchHandleOverlayType(insertHandle, startSelectionHandle, endSelectionHandle);
4579     if (overlayType == INVALID_OVERLAY) {
4580         CloseSelectOverlay();
4581         return;
4582     }
4583     auto pipeline = PipelineContext::GetCurrentContext();
4584     CHECK_NULL_VOID(pipeline);
4585     insertHandle_ = insertHandle;
4586     startSelectionHandle_ = startSelectionHandle;
4587     endSelectionHandle_ = endSelectionHandle;
4588     if (selectTemporarilyHidden_ || selectTemporarilyHiddenByScroll_) {
4589         TAG_LOGD(AceLogTag::ACE_WEB, "select menu temporarily hidden");
4590         return;
4591     }
4592     if (!selectOverlayProxy_) {
4593         if (overlayType == INSERT_OVERLAY) {
4594             SelectOverlayInfo selectInfo;
4595             selectInfo.isSingleHandle = true;
4596             selectInfo.firstHandle.paintRect = ComputeTouchHandleRect(insertHandle_);
4597             CheckHandles(selectInfo.firstHandle, insertHandle_);
4598             selectInfo.secondHandle.isShow = false;
4599             selectInfo.menuInfo.menuDisable = true;
4600             selectInfo.menuInfo.menuIsShow = false;
4601             selectInfo.hitTestMode = HitTestMode::HTMDEFAULT;
4602             selectInfo.isHandleLineShow = false;
4603             RegisterSelectOverlayEvent(selectInfo);
4604             selectOverlayProxy_ =
4605                 pipeline->GetSelectOverlayManager()->CreateAndShowSelectOverlay(selectInfo, WeakClaim(this));
4606         }
4607     } else {
4608         if (overlayType == INSERT_OVERLAY) {
4609             if (!IsSelectOverlayDragging()) {
4610                 UpdateTouchHandleForOverlay();
4611             }
4612         } else {
4613             UpdateSelectHandleInfo();
4614             if (!IsSelectOverlayDragging()) {
4615                 UpdateTouchHandleForOverlay();
4616             }
4617         }
4618     }
4619 }
4620 
OnCursorChange(const OHOS::NWeb::CursorType & type,std::shared_ptr<OHOS::NWeb::NWebCursorInfo> info)4621 bool WebPattern::OnCursorChange(const OHOS::NWeb::CursorType& type, std::shared_ptr<OHOS::NWeb::NWebCursorInfo> info)
4622 {
4623     TAG_LOGD(AceLogTag::ACE_WEB, "OnCursorChange type: %{public}d", type);
4624     if (mouseEventDeviceId_ == RESERVED_DEVICEID) {
4625         TAG_LOGD(AceLogTag::ACE_WEB, "OnCursorChange this device id is reserved.");
4626         return false;
4627     }
4628     if (isHoverExit_ && type == OHOS::NWeb::CursorType::CT_NONE) {
4629         TAG_LOGD(AceLogTag::ACE_WEB, "OnCursorChange reciving unexpected hide command");
4630         return false;
4631     }
4632     auto pipeline = PipelineContext::GetCurrentContext();
4633     CHECK_NULL_RETURN(pipeline, false);
4634     auto windowId = pipeline->GetWindowId();
4635     auto mouseStyle = MouseStyle::CreateMouseStyle();
4636     int32_t curPointerStyle = 0;
4637     if (mouseStyle->GetPointerStyle(windowId, curPointerStyle) == -1) {
4638         return false;
4639     }
4640 
4641     if ((type == OHOS::NWeb::CursorType::CT_CONTEXTMENU) || (type == OHOS::NWeb::CursorType::CT_ALIAS)) {
4642         UpdateLocalCursorStyle(windowId, type);
4643     } else if (type == OHOS::NWeb::CursorType::CT_CUSTOM) {
4644         UpdateCustomCursor(windowId, info);
4645     } else {
4646         MouseFormat pointStyle = MouseFormat::DEFAULT;
4647         int64_t idx = BinarySearchFindIndex(g_cursorTypeMap, ArraySize(g_cursorTypeMap), type);
4648         if (idx >= 0) {
4649             pointStyle = g_cursorTypeMap[idx].value;
4650         }
4651         mouseStyle->SetPointerVisible(pointStyle);
4652         if (static_cast<int32_t>(pointStyle) != curPointerStyle) {
4653             mouseStyle->SetPointerStyle(windowId, pointStyle);
4654         }
4655     }
4656     return true;
4657 }
4658 
UpdateLocalCursorStyle(int32_t windowId,const OHOS::NWeb::CursorType & type)4659 void WebPattern::UpdateLocalCursorStyle(int32_t windowId, const OHOS::NWeb::CursorType& type)
4660 {
4661     std::shared_ptr<Media::PixelMap> pixelMap;
4662     auto mouseStyle = MouseStyle::CreateMouseStyle();
4663     if (type == NWeb::CursorType::CT_CONTEXTMENU) {
4664         MouseFormat pointStyle = MouseFormat::CONTEXT_MENU;
4665         pixelMap = CreatePixelMapFromString(IMAGE_POINTER_CONTEXT_MENU_PATH);
4666         mouseStyle->SetMouseIcon(windowId, pointStyle, pixelMap);
4667     } else if (type == NWeb::CursorType::CT_ALIAS) {
4668         MouseFormat pointStyle = MouseFormat::ALIAS;
4669         pixelMap = CreatePixelMapFromString(IMAGE_POINTER_ALIAS_PATH);
4670         mouseStyle->SetMouseIcon(windowId, pointStyle, pixelMap);
4671     }
4672 }
4673 
UpdateCustomCursor(int32_t windowId,std::shared_ptr<OHOS::NWeb::NWebCursorInfo> info)4674 void WebPattern::UpdateCustomCursor(int32_t windowId, std::shared_ptr<OHOS::NWeb::NWebCursorInfo> info)
4675 {
4676     int32_t x = 0;
4677     int32_t y = 0;
4678     int32_t width = 0;
4679     int32_t height = 0;
4680     uint8_t *buff = nullptr;
4681     if (info) {
4682         x = info->GetX();
4683         y = info->GetY();
4684         buff = info->GetBuff();
4685         width = info->GetWidth();
4686         height = info->GetHeight();
4687     }
4688     Media::InitializationOptions opt;
4689     opt.size.width = width;
4690     opt.size.height = height;
4691     opt.editable = true;
4692     auto pixelMap = Media::PixelMap::Create(opt);
4693     CHECK_NULL_VOID(pixelMap);
4694     uint64_t bufferSize = static_cast<uint64_t>(width * height * IMAGE_POINTER_CUSTOM_CHANNEL);
4695     uint32_t status = pixelMap->WritePixels(static_cast<const uint8_t*>(buff), bufferSize);
4696     if (status != 0) {
4697         TAG_LOGE(AceLogTag::ACE_WEB, "write pixel map failed %{public}u", status);
4698         return;
4699     }
4700     std::shared_ptr<Media::PixelMap> cursorPixelMap(pixelMap.release());
4701     CHECK_NULL_VOID(cursorPixelMap);
4702     auto mouseStyle = MouseStyle::CreateMouseStyle();
4703     CHECK_NULL_VOID(mouseStyle);
4704     mouseStyle->SetCustomCursor(windowId, x, y, cursorPixelMap);
4705 }
4706 
CreatePixelMapFromString(const std::string & filePath)4707 std::shared_ptr<OHOS::Media::PixelMap> WebPattern::CreatePixelMapFromString(const std::string& filePath)
4708 {
4709     OHOS::Media::SourceOptions opts;
4710     opts.formatHint = "image/svg+xml";
4711     uint32_t errCode = 0;
4712     auto imageSource = OHOS::Media::ImageSource::CreateImageSource(filePath, opts, errCode);
4713     CHECK_NULL_RETURN(imageSource, nullptr);
4714     std::set<std::string> formats;
4715     errCode = imageSource->GetSupportedFormats(formats);
4716     Media::DecodeOptions decodeOpts;
4717     std::shared_ptr<OHOS::Media::PixelMap> pixelMap = imageSource->CreatePixelMap(decodeOpts, errCode);
4718     CHECK_NULL_RETURN(pixelMap, nullptr);
4719 
4720     return pixelMap;
4721 }
4722 
OnTooltip(const std::string & tooltip)4723 void WebPattern::OnTooltip(const std::string& tooltip)
4724 {
4725     auto pipeline = PipelineContext::GetCurrentContext();
4726     CHECK_NULL_VOID(pipeline);
4727     auto overlayManager = pipeline->GetOverlayManager();
4728     CHECK_NULL_VOID(overlayManager);
4729     tooltipTimestamp_ = GetSysTimestamp();
4730     auto tooltipTimestamp = tooltipTimestamp_;
4731 
4732     if (tooltipId_ != -1) {
4733         TAG_LOGI(AceLogTag::ACE_WEB,
4734             "OnTooltip Remove text:%{public}s, tooltipId_:%{public}d", tooltip.c_str(), tooltipId_);
4735         overlayManager->RemoveIndexerPopupById(tooltipId_);
4736         tooltipId_ = -1;
4737     }
4738 
4739     if (tooltip == "" || mouseHoveredX_ < 0 || mouseHoveredY_ < 0) {
4740         return;
4741     }
4742     ShowTooltip(tooltip, tooltipTimestamp);
4743 }
4744 
AttachCustomKeyboard()4745 void WebPattern::AttachCustomKeyboard()
4746 {
4747     TAG_LOGI(AceLogTag::ACE_WEB, "WebCustomKeyboard AttachCustomKeyboard enter");
4748     CHECK_NULL_VOID(customKeyboardBuilder_);
4749     auto frameNode = GetHost();
4750     CHECK_NULL_VOID(frameNode);
4751     auto pipeline = PipelineContext::GetCurrentContextSafely();
4752     CHECK_NULL_VOID(pipeline);
4753     auto overlayManager = pipeline->GetOverlayManager();
4754     CHECK_NULL_VOID(overlayManager);
4755     overlayManager->SetCustomKeyboardOption(true);
4756     overlayManager->BindKeyboard(customKeyboardBuilder_, frameNode->GetId());
4757     keyboardOverlay_ = overlayManager;
4758     keyboardOverlay_->AvoidCustomKeyboard(frameNode->GetId(), 0);
4759     TAG_LOGI(AceLogTag::ACE_WEB, "WebCustomKeyboard AttachCustomKeyboard end");
4760 }
4761 
CloseCustomKeyboard()4762 void WebPattern::CloseCustomKeyboard()
4763 {
4764     TAG_LOGI(AceLogTag::ACE_WEB, "WebCustomKeyboard CloseCustomKeyboard enter");
4765     auto frameNode = GetHost();
4766     CHECK_NULL_VOID(frameNode);
4767     CHECK_NULL_VOID(keyboardOverlay_);
4768     keyboardOverlay_->CloseKeyboard(frameNode->GetId());
4769     TAG_LOGI(AceLogTag::ACE_WEB, "WebCustomKeyboard CloseCustomKeyboard end");
4770 }
4771 
HandleShowTooltip(const std::string & tooltip,int64_t tooltipTimestamp)4772 void WebPattern::HandleShowTooltip(const std::string& tooltip, int64_t tooltipTimestamp)
4773 {
4774     if ((tooltipTimestamp_ != tooltipTimestamp) || (tooltip == "")) {
4775         return;
4776     }
4777     auto pipeline = PipelineContext::GetCurrentContext();
4778     CHECK_NULL_VOID(pipeline);
4779     auto overlayManager = pipeline->GetOverlayManager();
4780     CHECK_NULL_VOID(overlayManager);
4781     if (tooltipId_ == -1) {
4782         tooltipId_ = ElementRegister::GetInstance()->MakeUniqueId();
4783     }
4784     SetTooltipTextLayoutPropertyInner(pipeline, tooltip, overlayManager);
4785     TAG_LOGI(AceLogTag::ACE_WEB, "HandleShowTooltip text:%{public}s, tooltipId_:%{public}d",
4786         tooltip.c_str(), tooltipId_);
4787 }
4788 
SetTooltipTextLayoutPropertyInner(const RefPtr<PipelineContext> & pipeline,const std::string & tooltip,RefPtr<OverlayManager> & overlayManager)4789 void WebPattern::SetTooltipTextLayoutPropertyInner(const RefPtr<PipelineContext>& pipeline,
4790     const std::string& tooltip, RefPtr<OverlayManager>& overlayManager)
4791 {
4792     auto tooltipNode = FrameNode::GetOrCreateFrameNode(V2::TEXT_ETS_TAG, tooltipId_,
4793         []() { return AceType::MakeRefPtr<TextPattern>(); });
4794     CHECK_NULL_VOID(tooltipNode);
4795 
4796     auto textRenderContext = tooltipNode->GetRenderContext();
4797     CHECK_NULL_VOID(textRenderContext);
4798     auto textLayoutProperty = tooltipNode->GetLayoutProperty<TextLayoutProperty>();
4799     CHECK_NULL_VOID(textLayoutProperty);
4800     textLayoutProperty->UpdateContent(tooltip);
4801 
4802     BorderWidthProperty borderWidth;
4803     borderWidth.SetBorderWidth(TOOLTIP_BORDER_WIDTH);
4804     textLayoutProperty->UpdateBorderWidth(borderWidth);
4805     textLayoutProperty->UpdateFontSize(TOOLTIP_FONT_SIZE);
4806     textLayoutProperty->UpdatePadding({ CalcLength(TOOLTIP_PADDING),
4807         CalcLength(TOOLTIP_PADDING), CalcLength(TOOLTIP_PADDING), CalcLength(TOOLTIP_PADDING) });
4808     textLayoutProperty->UpdateCalcMaxSize(CalcSize(CalcLength(Dimension(
4809         pipeline->GetCurrentRootWidth() * TOOLTIP_MAX_PORTION)), std::nullopt));
4810     textRenderContext->UpdateBackgroundColor(Color::WHITE);
4811 
4812     OffsetF tooltipOffset;
4813     CalculateTooltipOffset(tooltipNode, tooltipOffset);
4814     textRenderContext->UpdatePosition(OffsetT<Dimension>(Dimension(tooltipOffset.GetX()),
4815         Dimension(tooltipOffset.GetY())));
4816 
4817     BorderColorProperty borderColor;
4818     borderColor.SetColor(Color::BLACK);
4819     textRenderContext->UpdateBorderColor(borderColor);
4820     overlayManager->ShowIndexerPopup(tooltipId_, tooltipNode);
4821 }
4822 
ShowTooltip(const std::string & tooltip,int64_t tooltipTimestamp)4823 void WebPattern::ShowTooltip(const std::string& tooltip, int64_t tooltipTimestamp)
4824 {
4825     auto tooltipTask = [weak = WeakClaim(this), tooltip, tooltipTimestamp]() {
4826         auto pattern = weak.Upgrade();
4827         CHECK_NULL_VOID(pattern);
4828         pattern->HandleShowTooltip(tooltip, tooltipTimestamp);
4829     };
4830 
4831     auto host = GetHost();
4832     CHECK_NULL_VOID(host);
4833     auto context = host->GetContext();
4834     CHECK_NULL_VOID(context);
4835 
4836     auto taskExecutor = context->GetTaskExecutor();
4837     CHECK_NULL_VOID(taskExecutor);
4838 
4839     taskExecutor->PostDelayedTask(tooltipTask, TaskExecutor::TaskType::UI, TOOLTIP_DELAY_MS, "ArkUIWebShowTooltip");
4840 }
4841 
CalculateTooltipOffset(RefPtr<FrameNode> & tooltipNode,OffsetF & tooltipOffset)4842 void WebPattern::CalculateTooltipOffset(RefPtr<FrameNode>& tooltipNode, OffsetF& tooltipOffset)
4843 {
4844     auto textLayoutWrapper = tooltipNode->CreateLayoutWrapper(true);
4845     CHECK_NULL_VOID(textLayoutWrapper);
4846     textLayoutWrapper->Measure(std::nullopt);
4847     auto textGeometryNode = textLayoutWrapper->GetGeometryNode();
4848     CHECK_NULL_VOID(textGeometryNode);
4849     auto textWidth = textGeometryNode->GetMarginFrameSize().Width();
4850     auto textHeight = textGeometryNode->GetMarginFrameSize().Height();
4851 
4852     auto offset = GetCoordinatePoint().value_or(OffsetF());
4853     auto offsetX = offset.GetX() + mouseHoveredX_ + TOOLTIP_MARGIN;
4854     auto offsetY = offset.GetY() + mouseHoveredY_ + TOOLTIP_MARGIN;
4855     auto pipeline = PipelineContext::GetCurrentContext();
4856     CHECK_NULL_VOID(pipeline);
4857     ScopedLayout scope(pipeline.GetRawPtr());
4858     if (GreatNotEqual(offsetX + textWidth, pipeline->GetCurrentRootWidth())) {
4859         offsetX = pipeline->GetCurrentRootWidth() - textWidth;
4860     }
4861     if (GreatNotEqual(offsetY + textHeight, pipeline->GetCurrentRootHeight())) {
4862         offsetY = pipeline->GetCurrentRootHeight() - textHeight;
4863     }
4864     tooltipOffset.SetX(offsetX);
4865     tooltipOffset.SetY(offsetY);
4866     TAG_LOGI(AceLogTag::ACE_WEB,
4867         "CalculateTooltipOffset [Tooltip] width: %{public}f height: %{public}f offset:(%{public}f, %{public}f)"
4868         " [Web] width: %{public}f height: %{public}f offset:(%{public}f, %{public}f)",
4869         textWidth, textHeight, offsetX, offsetY, drawSize_.Width(), drawSize_.Height(), offset.GetX(), offset.GetY());
4870 }
4871 
OnSelectPopupMenu(std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuParam> params,std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuCallback> callback)4872 void WebPattern::OnSelectPopupMenu(std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuParam> params,
4873     std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuCallback> callback)
4874 {
4875     CHECK_NULL_VOID(params);
4876     CHECK_NULL_VOID(callback);
4877     auto host = GetHost();
4878     CHECK_NULL_VOID(host);
4879     auto eventHub = host->GetEventHub<WebEventHub>();
4880     CHECK_NULL_VOID(eventHub);
4881     auto context = PipelineContext::GetCurrentContext();
4882     CHECK_NULL_VOID(context);
4883     auto overlayManager = context->GetOverlayManager();
4884     CHECK_NULL_VOID(overlayManager);
4885 
4886     auto id = host->GetId();
4887     std::vector<SelectParam> selectParam;
4888     for (auto& item : params->GetMenuItems()) {
4889         selectParam.push_back({
4890             item->GetLabel(), ""
4891         });
4892     }
4893     auto menu = MenuView::Create(selectParam, id, host->GetTag());
4894     CHECK_NULL_VOID(menu);
4895     auto menuWrapperPattern = menu->GetPattern<MenuWrapperPattern>();
4896     CHECK_NULL_VOID(menuWrapperPattern);
4897     auto destructor = [weak = WeakClaim(this), id]() {
4898         auto pattern = weak.Upgrade();
4899         CHECK_NULL_VOID(pattern);
4900         auto pipeline = NG::PipelineContext::GetCurrentContext();
4901         CHECK_NULL_VOID(pipeline);
4902         auto manager = pipeline->GetOverlayManager();
4903         CHECK_NULL_VOID(manager);
4904         pattern->SetSelectPopupMenuShowing(false);
4905         manager->DeleteMenu(id);
4906     };
4907     eventHub->SetOnDisappear(destructor);
4908 
4909     WebPattern::InitSelectPopupMenuView(menu, callback, params, context->GetDipScale());
4910     menuWrapperPattern->RegisterMenuDisappearCallback([weak = WeakClaim(this), callback]() {
4911         auto pattern = weak.Upgrade();
4912         CHECK_NULL_VOID(pattern);
4913         callback->Cancel();
4914         pattern->SetSelectPopupMenuShowing(false);
4915     });
4916     auto offset = GetSelectPopupPostion(params->GetSelectMenuBound());
4917     TAG_LOGI(AceLogTag::ACE_WEB, "OnSelectPopupMenu offset:(%{public}f, %{public}f)", offset.GetX(), offset.GetY());
4918     selectPopupMenuShowing_ = true;
4919     overlayManager->ShowMenu(id, offset, menu);
4920 }
4921 
NotifyForNextTouchEvent()4922 void WebPattern::NotifyForNextTouchEvent()
4923 {
4924     TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::NotifyForNextTouchEvent");
4925     CHECK_NULL_VOID(delegate_);
4926     delegate_->NotifyForNextTouchEvent();
4927 }
4928 
InitTouchEventListener()4929 void WebPattern::InitTouchEventListener()
4930 {
4931     TAG_LOGD(AceLogTag::ACE_WEB, "WebPattern::InitTouchEventListener");
4932     if (touchEventListener_) {
4933         return;
4934     }
4935     touchEventListener_ = std::make_shared<TouchEventListener>();
4936     touchEventListener_->SetPatternToListener(AceType::WeakClaim(this));
4937 
4938     auto context = PipelineContext::GetCurrentContext();
4939     CHECK_NULL_VOID(context);
4940 
4941     context->RegisterTouchEventListener(touchEventListener_);
4942 }
4943 
UninitTouchEventListener()4944 void WebPattern::UninitTouchEventListener()
4945 {
4946     TAG_LOGD(AceLogTag::ACE_WEB, "WebPattern::UninitTouchEventListener");
4947     touchEventListener_ = nullptr;
4948 
4949     auto context = PipelineContext::GetCurrentContext();
4950     CHECK_NULL_VOID(context);
4951     context->UnregisterTouchEventListener(AceType::WeakClaim(this));
4952 }
4953 
OnDateTimeChooserPopup(std::shared_ptr<OHOS::NWeb::NWebDateTimeChooser> chooser,const std::vector<std::shared_ptr<OHOS::NWeb::NWebDateTimeSuggestion>> & suggestions,std::shared_ptr<NWeb::NWebDateTimeChooserCallback> callback)4954 void WebPattern::OnDateTimeChooserPopup(std::shared_ptr<OHOS::NWeb::NWebDateTimeChooser> chooser,
4955     const std::vector<std::shared_ptr<OHOS::NWeb::NWebDateTimeSuggestion>>& suggestions,
4956     std::shared_ptr<NWeb::NWebDateTimeChooserCallback> callback)
4957 {
4958     if (!chooser) {
4959         return;
4960     }
4961 
4962     bool result = false;
4963     if (suggestions.size() != 0) {
4964         result = ShowDateTimeSuggestionDialog(chooser, suggestions, callback);
4965     } else if (chooser->GetType() == NWeb::DTC_TIME) {
4966         result = ShowTimeDialog(chooser, suggestions, callback);
4967     } else {
4968         result = ShowDateTimeDialog(chooser, suggestions, callback);
4969     }
4970     if (!result) {
4971         callback->Continue(false, OHOS::NWeb::DateTime());
4972     }
4973 }
4974 
GetDialogProperties(const RefPtr<DialogTheme> & theme)4975 DialogProperties WebPattern::GetDialogProperties(const RefPtr<DialogTheme>& theme)
4976 {
4977     DialogProperties properties;
4978     if (GetWebInfoType() == WebInfoType::TYPE_MOBILE) {
4979         properties.alignment = DialogAlignment::BOTTOM;
4980     } else {
4981         properties.alignment = DialogAlignment::CENTER;
4982     }
4983     properties.customStyle = false;
4984     properties.offset = DimensionOffset(Offset(0, -theme->GetMarginBottom().ConvertToPx()));
4985     return properties;
4986 }
4987 
ShowDateTimeDialog(std::shared_ptr<OHOS::NWeb::NWebDateTimeChooser> chooser,const std::vector<std::shared_ptr<OHOS::NWeb::NWebDateTimeSuggestion>> & suggestions,std::shared_ptr<NWeb::NWebDateTimeChooserCallback> callback)4988 bool WebPattern::ShowDateTimeDialog(std::shared_ptr<OHOS::NWeb::NWebDateTimeChooser> chooser,
4989     const std::vector<std::shared_ptr<OHOS::NWeb::NWebDateTimeSuggestion>>& suggestions,
4990     std::shared_ptr<NWeb::NWebDateTimeChooserCallback> callback)
4991 {
4992     auto container = Container::Current();
4993     CHECK_NULL_RETURN(container, false);
4994     auto pipelineContext = AccessibilityManager::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
4995     CHECK_NULL_RETURN(pipelineContext, false);
4996     auto executor = pipelineContext->GetTaskExecutor();
4997     CHECK_NULL_RETURN(executor, false);
4998     auto context = AccessibilityManager::DynamicCast<NG::PipelineContext>(pipelineContext);
4999     auto overlayManager = context ? context->GetOverlayManager() : nullptr;
5000     CHECK_NULL_RETURN(overlayManager, false);
5001     auto theme = pipelineContext->GetTheme<DialogTheme>();
5002     CHECK_NULL_RETURN(theme, false);
5003     NG::DatePickerSettingData settingData;
5004     settingData.isLunar = false;
5005     settingData.showTime = chooser->GetType() == NWeb::DTC_DATETIME_LOCAL;
5006     settingData.useMilitary = true;
5007     DialogProperties properties = GetDialogProperties(theme);
5008     std::map<std::string, PickerDate> datePickerProperty;
5009     std::map<std::string, PickerTime> timePickerProperty;
5010     OHOS::NWeb::DateTime minimum = chooser->GetMinimum();
5011     OHOS::NWeb::DateTime maximum = chooser->GetMaximum();
5012     OHOS::NWeb::DateTime dialogValue = chooser->GetDialogValue();
5013     settingData.datePickerProperty["start"] = PickerDate(
5014         minimum.year, minimum.month + 1, minimum.day);
5015     settingData.datePickerProperty["end"] = PickerDate(
5016         maximum.year, maximum.month + 1, maximum.day);
5017     if (chooser->GetHasSelected()) {
5018         int32_t day = (dialogValue.day == 0) ? 1 : dialogValue.day;
5019         settingData.datePickerProperty["selected"] =
5020             PickerDate(dialogValue.year, dialogValue.month + 1, day);
5021     }
5022     std::map<std::string, NG::DialogEvent> dialogEvent;
5023     std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent;
5024     dialogEvent["acceptId"] = [callback](const std::string& info) {
5025         OHOS::NWeb::DateTime result;
5026         bool success = ParseDateTimeJson(info, result);
5027         callback->Continue(success, result);
5028     };
5029     dialogCancelEvent["cancelId"] =
5030         [callback](const GestureEvent&) { callback->Continue(false, OHOS::NWeb::DateTime()); };
5031     overlayManager->RegisterOnHideDialog([callback] { callback->Continue(false, OHOS::NWeb::DateTime()); });
5032     executor->PostTask(
5033         [properties, settingData, dialogEvent, dialogCancelEvent, weak = WeakPtr<NG::OverlayManager>(overlayManager)] {
5034             auto overlayManager = weak.Upgrade();
5035             CHECK_NULL_VOID(overlayManager);
5036             overlayManager->ShowDateDialog(properties, settingData, dialogEvent, dialogCancelEvent);
5037         },
5038         TaskExecutor::TaskType::UI, "ArkUIWebShowDateDialog");
5039     return true;
5040 }
5041 
ShowTimeDialog(std::shared_ptr<OHOS::NWeb::NWebDateTimeChooser> chooser,const std::vector<std::shared_ptr<OHOS::NWeb::NWebDateTimeSuggestion>> & suggestions,std::shared_ptr<NWeb::NWebDateTimeChooserCallback> callback)5042 bool WebPattern::ShowTimeDialog(std::shared_ptr<OHOS::NWeb::NWebDateTimeChooser> chooser,
5043     const std::vector<std::shared_ptr<OHOS::NWeb::NWebDateTimeSuggestion>>& suggestions,
5044     std::shared_ptr<NWeb::NWebDateTimeChooserCallback> callback)
5045 {
5046     auto container = Container::Current();
5047     CHECK_NULL_RETURN(container, false);
5048     auto pipelineContext = AccessibilityManager::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
5049     CHECK_NULL_RETURN(pipelineContext, false);
5050     auto executor = pipelineContext->GetTaskExecutor();
5051     CHECK_NULL_RETURN(executor, false);
5052     auto theme = pipelineContext->GetTheme<DialogTheme>();
5053     CHECK_NULL_RETURN(theme, false);
5054     auto context = AccessibilityManager::DynamicCast<NG::PipelineContext>(pipelineContext);
5055     auto overlayManager = context ? context->GetOverlayManager() : nullptr;
5056     CHECK_NULL_RETURN(overlayManager, false);
5057     NG::TimePickerSettingData settingData;
5058     settingData.isUseMilitaryTime = true;
5059     DialogProperties properties = GetDialogProperties(theme);
5060     std::map<std::string, PickerTime> timePickerProperty;
5061     OHOS::NWeb::DateTime minimum = chooser->GetMinimum();
5062     OHOS::NWeb::DateTime maximum = chooser->GetMaximum();
5063     OHOS::NWeb::DateTime dialogValue = chooser->GetDialogValue();
5064     timePickerProperty["start"] = PickerTime(minimum.hour, minimum.minute, minimum.second);
5065     timePickerProperty["selected"] = PickerTime(maximum.hour, maximum.minute, maximum.second);
5066     if (chooser->GetHasSelected()) {
5067         timePickerProperty["selected"] =
5068             PickerTime(dialogValue.hour, dialogValue.minute, dialogValue.second);
5069     }
5070     std::map<std::string, NG::DialogEvent> dialogEvent;
5071     std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent;
5072     dialogEvent["acceptId"] = [callback](const std::string& info) {
5073         OHOS::NWeb::DateTime result;
5074         bool success = ParseDateTimeJson(info, result);
5075         callback->Continue(success, result);
5076     };
5077     dialogCancelEvent["cancelId"] =
5078         [callback](const GestureEvent&) { callback->Continue(false, OHOS::NWeb::DateTime()); };
5079     overlayManager->RegisterOnHideDialog([callback] { callback->Continue(false, OHOS::NWeb::DateTime()); });
5080     executor->PostTask(
5081         [properties, settingData, timePickerProperty, dialogEvent, dialogCancelEvent,
5082             weak = WeakPtr<NG::OverlayManager>(overlayManager)] {
5083             auto overlayManager = weak.Upgrade();
5084             CHECK_NULL_VOID(overlayManager);
5085             overlayManager->ShowTimeDialog(properties, settingData, timePickerProperty, dialogEvent, dialogCancelEvent);
5086         },
5087         TaskExecutor::TaskType::UI, "ArkUIWebShowTimeDialog");
5088     return true;
5089 }
5090 
ShowDateTimeSuggestionDialog(std::shared_ptr<OHOS::NWeb::NWebDateTimeChooser> chooser,const std::vector<std::shared_ptr<OHOS::NWeb::NWebDateTimeSuggestion>> & suggestions,std::shared_ptr<NWeb::NWebDateTimeChooserCallback> callback)5091 bool WebPattern::ShowDateTimeSuggestionDialog(std::shared_ptr<OHOS::NWeb::NWebDateTimeChooser> chooser,
5092     const std::vector<std::shared_ptr<OHOS::NWeb::NWebDateTimeSuggestion>>& suggestions,
5093     std::shared_ptr<NWeb::NWebDateTimeChooserCallback> callback)
5094 {
5095     auto container = Container::Current();
5096     CHECK_NULL_RETURN(container, false);
5097     auto pipelineContext = AccessibilityManager::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
5098     CHECK_NULL_RETURN(pipelineContext, false);
5099     auto executor = pipelineContext->GetTaskExecutor();
5100     CHECK_NULL_RETURN(executor, false);
5101     auto theme = pipelineContext->GetTheme<DialogTheme>();
5102     CHECK_NULL_RETURN(theme, false);
5103     auto context = AccessibilityManager::DynamicCast<NG::PipelineContext>(pipelineContext);
5104     auto overlayManager = context ? context->GetOverlayManager() : nullptr;
5105     CHECK_NULL_RETURN(overlayManager, false);
5106     NG::TextPickerSettingData settingData;
5107     if (memset_s(&settingData, sizeof(NG::TextPickerSettingData), 0, sizeof(NG::TextPickerSettingData)) != EOK) {
5108         return false;
5109     }
5110     std::map<std::string, OHOS::NWeb::DateTime> suggestionMap;
5111     for (size_t i = 0; i < suggestions.size(); i++) {
5112         settingData.rangeVector.push_back({ "", suggestions[i]->GetLocalizedValue() });
5113         settingData.values.push_back(suggestions[i]->GetLocalizedValue());
5114         suggestionMap.emplace(std::make_pair(suggestions[i]->GetLocalizedValue(), suggestions[i]->GetValue()));
5115     }
5116     settingData.columnKind = NG::TEXT;
5117     settingData.selected = chooser->GetSuggestionIndex();
5118     DialogProperties properties = GetDialogProperties(theme);
5119     std::map<std::string, NG::DialogTextEvent> dialogEvent;
5120     std::map<std::string, NG::DialogGestureEvent> dialogCancelEvent;
5121     dialogEvent["acceptId"] = [suggestionMap, callback](const std::string& info) {
5122         std::string value = ParseTextJsonValue(info);
5123         if (suggestionMap.find(value) != suggestionMap.end()) {
5124             callback->Continue(true, suggestionMap.at(value));
5125         } else {
5126             callback->Continue(false, OHOS::NWeb::DateTime());
5127         }
5128     };
5129     dialogCancelEvent["cancelId"] =
5130         [callback](const GestureEvent&) { callback->Continue(false, OHOS::NWeb::DateTime()); };
5131     overlayManager->RegisterOnHideDialog([callback] { callback->Continue(false, OHOS::NWeb::DateTime()); });
5132     executor->PostTask(
5133         [properties, settingData, dialogEvent, dialogCancelEvent,
5134             weak = WeakPtr<NG::OverlayManager>(overlayManager)] {
5135             auto overlayManager = weak.Upgrade();
5136             CHECK_NULL_VOID(overlayManager);
5137             overlayManager->ShowTextDialog(properties, settingData, dialogEvent, dialogCancelEvent);
5138         },
5139         TaskExecutor::TaskType::UI, "ArkUIWebShowTextDialog");
5140     return true;
5141 }
5142 
OnDateTimeChooserClose()5143 void WebPattern::OnDateTimeChooserClose() {}
5144 
InitSelectPopupMenuViewOption(const std::vector<RefPtr<FrameNode>> & options,const std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuCallback> & callback,const std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuParam> & params,const double & dipScale)5145 void WebPattern::InitSelectPopupMenuViewOption(const std::vector<RefPtr<FrameNode>>& options,
5146     const std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuCallback>& callback,
5147     const std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuParam>& params,
5148     const double& dipScale)
5149 {
5150     int32_t optionIndex = -1;
5151     int32_t width = params->GetSelectMenuBound() ? params->GetSelectMenuBound()->GetWidth() : 0;
5152     auto items = params->GetMenuItems();
5153     int32_t selectedIndex = params->GetSelectedItem();
5154     TAG_LOGD(AceLogTag::ACE_WEB, "InitSelectPopupMenuViewOption selectedIndex:%{public}d", selectedIndex);
5155 
5156     for (auto &&option : options) {
5157         optionIndex++;
5158         CHECK_NULL_VOID(option);
5159         auto optionPattern = option->GetPattern<OptionPattern>();
5160         CHECK_NULL_VOID(optionPattern);
5161         auto optionPaintProperty = option->GetPaintProperty<OptionPaintProperty>();
5162         CHECK_NULL_VOID(optionPaintProperty);
5163         optionPaintProperty->SetIdealWidthForWeb(width - OPTION_MARGIN.ConvertToPx());
5164         optionPattern->SetFontSize(Dimension(params->GetItemFontSize() * dipScale));
5165         if (selectedIndex == optionIndex) {
5166             optionPattern->SetFontColor(SELECTED_OPTION_FONT_COLOR);
5167             optionPattern->SetBgColor(SELECTED_OPTION_BACKGROUND_COLOR);
5168             optionPattern->UpdateNextNodeDivider(false);
5169             optionPaintProperty->UpdateNeedDivider(false);
5170         }
5171         auto hub = option->GetEventHub<OptionEventHub>();
5172         CHECK_NULL_VOID(hub);
5173         if (optionIndex >= 0 && static_cast<uint32_t>(optionIndex) < items.size()) {
5174             hub->SetEnabled(items[optionIndex]->GetIsEnabled());
5175             auto focusHub = option->GetFocusHub();
5176             if (focusHub) {
5177                 focusHub->SetEnabled(items[optionIndex]->GetIsEnabled());
5178             }
5179         }
5180         auto selectCallback = [callback](int32_t index) {
5181             std::vector<int32_t> indices { static_cast<int32_t>(index) };
5182             callback->Continue(indices);
5183         };
5184         hub->SetOnSelect(std::move(selectCallback));
5185         option->MarkModifyDone();
5186     }
5187 }
5188 
InitSelectPopupMenuView(RefPtr<FrameNode> & menuWrapper,std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuCallback> callback,std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuParam> params,const double & dipScale)5189 void WebPattern::InitSelectPopupMenuView(RefPtr<FrameNode>& menuWrapper,
5190     std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuCallback> callback,
5191     std::shared_ptr<OHOS::NWeb::NWebSelectPopupMenuParam> params,
5192     const double& dipScale)
5193 {
5194     auto menu = AceType::DynamicCast<FrameNode>(menuWrapper->GetChildAtIndex(0));
5195     CHECK_NULL_VOID(menu);
5196     auto menuPattern = menu->GetPattern<MenuPattern>();
5197     CHECK_NULL_VOID(menuPattern);
5198 
5199     InitSelectPopupMenuViewOption(menuPattern->GetOptions(), callback, params, dipScale);
5200 }
5201 
GetSelectPopupPostion(std::shared_ptr<OHOS::NWeb::NWebSelectMenuBound> bound)5202 OffsetF WebPattern::GetSelectPopupPostion(std::shared_ptr<OHOS::NWeb::NWebSelectMenuBound> bound)
5203 {
5204     auto offset = GetCoordinatePoint().value_or(OffsetF());
5205     if (bound) {
5206         offset.AddX(bound->GetX());
5207         offset.AddY(bound->GetY() + bound->GetHeight());
5208     }
5209     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
5210         offset.AddX(-CALIBERATE_X.ConvertToPx());
5211     }
5212     return offset;
5213 }
5214 
UpdateTouchHandleForOverlay(bool fromOverlay)5215 void WebPattern::UpdateTouchHandleForOverlay(bool fromOverlay)
5216 {
5217     WebOverlayType overlayType = GetTouchHandleOverlayType(insertHandle_, startSelectionHandle_, endSelectionHandle_);
5218     CHECK_NULL_VOID(selectOverlayProxy_);
5219     if (overlayType == INVALID_OVERLAY) {
5220         CloseSelectOverlay();
5221         return;
5222     }
5223     SelectHandleInfo firstHandleInfo;
5224     SelectHandleInfo secondHandleInfo;
5225     if (overlayType == INSERT_OVERLAY) {
5226         if (!fromOverlay) {
5227             selectOverlayProxy_->ShowOrHiddenMenu(true, true);
5228         }
5229         firstHandleInfo.paintRect = ComputeTouchHandleRect(insertHandle_);
5230         CheckHandles(firstHandleInfo, insertHandle_);
5231         firstHandleInfo.needLayout = true;
5232         selectOverlayProxy_->UpdateFirstSelectHandleInfo(firstHandleInfo);
5233     } else {
5234         if (selectTemporarilyHidden_ || selectTemporarilyHiddenByScroll_) {
5235             return;
5236         }
5237         firstHandleInfo.paintRect = ComputeTouchHandleRect(startSelectionHandle_);
5238         secondHandleInfo.paintRect = ComputeTouchHandleRect(endSelectionHandle_);
5239         CheckHandles(firstHandleInfo, startSelectionHandle_);
5240         CheckHandles(secondHandleInfo, endSelectionHandle_);
5241         if (firstHandleInfo.isShow || secondHandleInfo.isShow) {
5242             selectOverlayProxy_->SetIsNewAvoid(false);
5243         }
5244         selectOverlayProxy_->UpdateFirstSelectHandleInfo(firstHandleInfo);
5245         selectOverlayProxy_->UpdateSecondSelectHandleInfo(secondHandleInfo);
5246         selectMenuInfo_.menuIsShow = selectOverlayProxy_->IsMenuShow();
5247         selectOverlayProxy_->UpdateSelectMenuInfo(selectMenuInfo_);
5248         selectOverlayProxy_->SetHandleReverse(false);
5249     }
5250 }
5251 
UpdateLocale()5252 void WebPattern::UpdateLocale()
5253 {
5254     CHECK_NULL_VOID(delegate_);
5255     delegate_->UpdateLocale();
5256 }
5257 
OnWindowShow()5258 void WebPattern::OnWindowShow()
5259 {
5260     TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnWindowShow");
5261     CHECK_NULL_VOID(delegate_);
5262     delegate_->OnRenderToForeground();
5263     delegate_->OnOnlineRenderToForeground();
5264 
5265     if (isWindowShow_ || !isVisible_) {
5266         return;
5267     }
5268 
5269     delegate_->ShowWebView();
5270     isWindowShow_ = true;
5271 }
5272 
OnWindowHide()5273 void WebPattern::OnWindowHide()
5274 {
5275     TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnWindowHide");
5276     CHECK_NULL_VOID(delegate_);
5277     delegate_->OnRenderToBackground();
5278     if (!isWindowShow_ || !isVisible_) {
5279         return;
5280     }
5281 
5282     delegate_->HideWebView();
5283     CloseContextSelectionMenu();
5284     needOnFocus_ = false;
5285     isWindowShow_ = false;
5286 }
5287 
OnWindowSizeChanged(int32_t width,int32_t height,WindowSizeChangeReason type)5288 void WebPattern::OnWindowSizeChanged(int32_t width, int32_t height, WindowSizeChangeReason type) {}
5289 
OnCompleteSwapWithNewSize()5290 void WebPattern::OnCompleteSwapWithNewSize()
5291 {
5292     if (!isInWindowDrag_ || !isWaiting_)
5293         return;
5294 
5295     ACE_SCOPED_TRACE("WebPattern::OnCompleteSwapWithNewSize");
5296     isWaiting_ = false;
5297 }
5298 
OnResizeNotWork()5299 void WebPattern::OnResizeNotWork()
5300 {
5301     if (!isInWindowDrag_ || !isWaiting_)
5302         return;
5303 
5304     ACE_SCOPED_TRACE("WebPattern::OnResizeNotWork");
5305     isWaiting_ = false;
5306 }
5307 
UpdateOnFocusTextField(bool isFocus)5308 void WebPattern::UpdateOnFocusTextField(bool isFocus)
5309 {
5310     auto host = GetHost();
5311     CHECK_NULL_VOID(host);
5312     auto context = PipelineContext::GetCurrentContext();
5313     CHECK_NULL_VOID(context);
5314     auto textFieldManager = DynamicCast<TextFieldManagerNG>(context->GetTextFieldManager());
5315     CHECK_NULL_VOID(textFieldManager);
5316     isFocus ? textFieldManager->SetOnFocusTextField(WeakClaim(this))
5317             : textFieldManager->ClearOnFocusTextField(host->GetId());
5318 }
5319 
OnBackPressed()5320 bool WebPattern::OnBackPressed()
5321 {
5322     auto host = GetHost();
5323     CHECK_NULL_RETURN(host, false);
5324     TAG_LOGI(AceLogTag::ACE_WEB, "Web %{public}d receives back press event", host->GetId());
5325     if (IsVirtualKeyBoardShow()) {
5326         CloseSelectOverlay();
5327         SelectCancel();
5328         TAG_LOGI(AceLogTag::ACE_WEB, "Request close soft keyboard.");
5329         auto inputMethod = MiscServices::InputMethodController::GetInstance();
5330         CHECK_NULL_RETURN(inputMethod, false);
5331         inputMethod->HideTextInput();
5332         inputMethod->Close();
5333         CHECK_NULL_RETURN(delegate_, true);
5334         delegate_->CloseCustomKeyboard();
5335         return true;
5336     }
5337     return false;
5338 }
5339 
OnBackPressedForFullScreen() const5340 bool WebPattern::OnBackPressedForFullScreen() const
5341 {
5342     if (!isFullScreen_) {
5343         return false;
5344     }
5345 
5346     TAG_LOGI(AceLogTag::ACE_WEB, "FullScreenBackPressEvent Received");
5347     CHECK_NULL_RETURN(fullScreenExitHandler_, false);
5348     auto webFullScreenExitHandler = fullScreenExitHandler_->GetHandler();
5349     CHECK_NULL_RETURN(webFullScreenExitHandler, false);
5350     webFullScreenExitHandler->ExitFullScreen();
5351     return true;
5352 }
5353 
SetFullScreenExitHandler(const std::shared_ptr<FullScreenEnterEvent> & fullScreenExitHandler)5354 void WebPattern::SetFullScreenExitHandler(const std::shared_ptr<FullScreenEnterEvent>& fullScreenExitHandler)
5355 {
5356     fullScreenExitHandler_ = fullScreenExitHandler;
5357 }
5358 
OnInActive()5359 void WebPattern::OnInActive()
5360 {
5361     TAG_LOGI(AceLogTag::ACE_WEB,
5362         "WebPattern::OnInActive webId:%{public}d, isActive:%{public}d", GetWebId(), isActive_);
5363     if (!isActive_) {
5364         return;
5365     }
5366 
5367     CHECK_NULL_VOID(delegate_);
5368     delegate_->OnInactive();
5369     isActive_ = false;
5370 }
5371 
OnActive()5372 void WebPattern::OnActive()
5373 {
5374     TAG_LOGI(AceLogTag::ACE_WEB,
5375         "WebPattern::OnActive webId:%{public}d, isActive:%{public}d", GetWebId(), isActive_);
5376     if (isActive_) {
5377         return;
5378     }
5379 
5380     CHECK_NULL_VOID(delegate_);
5381     delegate_->OnActive();
5382     isActive_ = true;
5383 }
5384 
OnVisibleAreaChange(bool isVisible)5385 void WebPattern::OnVisibleAreaChange(bool isVisible)
5386 {
5387     bool isDialogNested = IsDialogNested();
5388     ACE_SCOPED_TRACE("WebPattern::OnVisibleAreaChange, webId: %d, isVisible: %d", GetWebId(), isVisible);
5389     TAG_LOGI(AceLogTag::ACE_WEB,
5390         "WebPattern::OnVisibleAreaChange webId:%{public}d, isVisible:%{public}d, old_isVisible:%{public}d, "
5391         "isVisibleActiveEnable:%{public}d, isDialogNested:%{public}d, isFocus:%{public}d",
5392         GetWebId(), isVisible, isVisible_, isVisibleActiveEnable_, isDialogNested, isFocus_);
5393     if (isVisible_ == isVisible) {
5394         return;
5395     }
5396 
5397     isVisible_ = isVisible;
5398     if (!isVisible_) {
5399         CloseSelectOverlay();
5400         SelectCancel();
5401         DestroyAnalyzerOverlay();
5402         isDragEndMenuShow_ = false;
5403         if (isVisibleActiveEnable_ && (!isDialogNested || !isFocus_)) {
5404             OnInActive();
5405         }
5406     } else {
5407         if (isVisibleActiveEnable_) {
5408             OnActive();
5409         }
5410     }
5411 }
5412 
GetDefaultBackgroundColor()5413 Color WebPattern::GetDefaultBackgroundColor()
5414 {
5415     auto darkMode = GetDarkModeValue(webData_ ? (WebDarkMode::Auto) : (WebDarkMode::Off));
5416     if (GetForceDarkAccessValue(false) &&
5417         (darkMode == WebDarkMode::On || ((darkMode == WebDarkMode::Auto) && (GetSystemColor() == Color::BLACK)))) {
5418         return Color::BLACK;
5419     } else {
5420         return Color::WHITE;
5421     }
5422 }
5423 
UpdateBackgroundColorRightNow(int32_t color)5424 void WebPattern::UpdateBackgroundColorRightNow(int32_t color)
5425 {
5426     auto host = GetHost();
5427     CHECK_NULL_VOID(host);
5428     auto renderContext = host->GetRenderContext();
5429     CHECK_NULL_VOID(renderContext);
5430     renderContext->UpdateBackgroundColor(Color(static_cast<uint32_t>(color)));
5431     CHECK_NULL_VOID(renderContextForSurface_);
5432     renderContextForSurface_->UpdateBackgroundColor(Color(static_cast<uint32_t>(color)));
5433 }
5434 
GetSystemColor() const5435 Color WebPattern::GetSystemColor() const
5436 {
5437     Color color = Color::WHITE;
5438     auto appMgrClient = std::make_shared<AppExecFwk::AppMgrClient>();
5439     CHECK_NULL_RETURN(appMgrClient, color);
5440     if (appMgrClient->ConnectAppMgrService()) {
5441         return color;
5442     }
5443     auto systemConfig = OHOS::AppExecFwk::Configuration();
5444     appMgrClient->GetConfiguration(systemConfig);
5445     auto colorMode = systemConfig.GetItem(OHOS::AAFwk::GlobalConfigurationKey::SYSTEM_COLORMODE);
5446     if (colorMode == OHOS::AppExecFwk::ConfigurationInner::COLOR_MODE_DARK) {
5447         return Color::BLACK;
5448     }
5449     if (colorMode == OHOS::AppExecFwk::ConfigurationInner::COLOR_MODE_LIGHT) {
5450         return Color::WHITE;
5451     }
5452     TAG_LOGW(AceLogTag::ACE_WEB, "no system color mode is found.");
5453     return color;
5454 }
5455 
OnNotifyMemoryLevel(int32_t level)5456 void WebPattern::OnNotifyMemoryLevel(int32_t level)
5457 {
5458     if (!isMemoryLevelEnable_) {
5459         return;
5460     }
5461     CHECK_NULL_VOID(delegate_);
5462     delegate_->NotifyMemoryLevel(level);
5463 }
5464 
GetWebId()5465 int WebPattern::GetWebId()
5466 {
5467     if (delegate_) {
5468         return delegate_->GetWebId();
5469     }
5470     return -1;
5471 }
5472 
HandleScroll(float offset,int32_t source,NestedState state,float velocity)5473 ScrollResult WebPattern::HandleScroll(float offset, int32_t source, NestedState state, float velocity)
5474 {
5475     // If no parent object is specified, the nearest nested scrollable parent is used by default.
5476     return HandleScroll(GetNestedScrollParent(), offset, source, state);
5477 }
5478 
HandleScroll(RefPtr<NestableScrollContainer> parent,float offset,int32_t source,NestedState state)5479 ScrollResult WebPattern::HandleScroll(RefPtr<NestableScrollContainer> parent, float offset,
5480     int32_t source, NestedState state)
5481 {
5482     if (parent) {
5483         source = isMouseEvent_ ? SCROLL_FROM_AXIS : source;
5484         return parent->HandleScroll(offset, source, state);
5485     }
5486     return { 0.0f, false };
5487 }
5488 
HandleScrollVelocity(float velocity,const RefPtr<NestableScrollContainer> & child)5489 bool WebPattern::HandleScrollVelocity(float velocity, const RefPtr<NestableScrollContainer>& child)
5490 {
5491     // If no parent object is specified, the nearest nested scrollable parent is used by default.
5492     return HandleScrollVelocity(GetNestedScrollParent(), velocity);
5493 }
5494 
HandleScrollVelocity(RefPtr<NestableScrollContainer> parent,float velocity)5495 bool WebPattern::HandleScrollVelocity(RefPtr<NestableScrollContainer> parent, float velocity)
5496 {
5497     CHECK_NULL_RETURN(parent, false);
5498     if (!NestedScrollOutOfBoundary()) {
5499         OnParentScrollDragEndRecursive(parent);
5500     }
5501     if (InstanceOf<SwiperPattern>(parent)) {
5502         // When scrolling to the previous SwiperItem, that item needs to be visible. Update the offset slightly to make
5503         // it visible before calling HandleScrollVelocity.
5504         float tweak = (velocity > 0.0f) ? 1.0f : -1.0f;
5505         parent->HandleScroll(tweak, SCROLL_FROM_UPDATE, NestedState::CHILD_SCROLL);
5506         OnParentScrollDragEndRecursive(parent);
5507     }
5508     TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::HandleScrollVelocity, to parent scroll velocity=%{public}f", velocity);
5509     if (parent->HandleScrollVelocity(velocity)) {
5510         OnParentScrollDragEndRecursive(parent);
5511         return true;
5512     }
5513     OnParentScrollDragEndRecursive(parent);
5514     return false;
5515 }
5516 
OnScrollStartRecursive(WeakPtr<NestableScrollContainer> child,float position,float velocity)5517 void WebPattern::OnScrollStartRecursive(WeakPtr<NestableScrollContainer> child, float position, float velocity)
5518 {
5519     // If only one position value is passed, it will be notified to the nearest nested scrollable parent.
5520     OnScrollStartRecursive(std::vector({ position }));
5521 }
5522 
OnScrollStartRecursive(std::vector<float> positions)5523 void WebPattern::OnScrollStartRecursive(std::vector<float> positions)
5524 {
5525     TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnScrollStartRecursive");
5526     SetIsNestedInterrupt(false);
5527     auto it = positions.begin();
5528     for (auto parentMap : parentsMap_) {
5529         auto parent = parentMap.second.Upgrade();
5530         if (parent && it < positions.end()) {
5531             parent->OnScrollStartRecursive(WeakClaim(this), *it);
5532         }
5533         it++;
5534     }
5535     isFirstFlingScrollVelocity_ = true;
5536     isNeedUpdateScrollAxis_ = true;
5537     isScrollStarted_ = true;
5538 }
5539 
OnAttachToBuilderNode(NodeStatus nodeStatus)5540 void WebPattern::OnAttachToBuilderNode(NodeStatus nodeStatus)
5541 {
5542     TAG_LOGD(AceLogTag::ACE_WEB, "WebPattern::OnAttachToBuilderNode");
5543     if (nodeStatus != NodeStatus::NORMAL_NODE) {
5544         InitInOfflineMode();
5545     }
5546 }
5547 
OnScrollEndRecursive(const std::optional<float> & velocity)5548 void WebPattern::OnScrollEndRecursive(const std::optional<float>& velocity)
5549 {
5550     TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnScrollEndRecursive");
5551     CHECK_EQUAL_VOID(isScrollStarted_, false);
5552     for (auto parentMap : parentsMap_) {
5553         auto parent = parentMap.second.Upgrade();
5554         if (parent) {
5555             OnParentScrollDragEndRecursive(parent);
5556             parent->OnScrollEndRecursive(std::nullopt);
5557         }
5558     }
5559     isScrollStarted_ = false;
5560     SetIsNestedInterrupt(false);
5561 }
5562 
OnOverScrollFlingVelocity(float xVelocity,float yVelocity,bool isFling)5563 void WebPattern::OnOverScrollFlingVelocity(float xVelocity, float yVelocity, bool isFling)
5564 {
5565     if (isNeedUpdateScrollAxis_) {
5566         TAG_LOGD(AceLogTag::ACE_WEB, "WebPattern::OnOverScrollFlingVelocity scrollAxis has not been updated");
5567         return;
5568     }
5569     float velocity = (expectedScrollAxis_ == Axis::HORIZONTAL) ? xVelocity : yVelocity;
5570     OnOverScrollFlingVelocityHandler(velocity, isFling);
5571 }
5572 
OnOverScrollFlingVelocityHandler(float velocity,bool isFling)5573 void WebPattern::OnOverScrollFlingVelocityHandler(float velocity, bool isFling)
5574 {
5575     auto it = parentsMap_.find(expectedScrollAxis_);
5576     CHECK_EQUAL_VOID(it, parentsMap_.end());
5577     auto parent = it->second;
5578     auto nestedScroll = GetNestedScroll();
5579     ScrollResult result = { 0.f, true };
5580     auto remain = 0.f;
5581     if (!isFling) {
5582         if (scrollState_) {
5583             if (((velocity < 0 && nestedScroll.backward == NestedScrollMode::SELF_FIRST) ||
5584                     (velocity > 0 && nestedScroll.forward == NestedScrollMode::SELF_FIRST))) {
5585                 result = HandleScroll(parent.Upgrade(), -velocity, SCROLL_FROM_UPDATE, NestedState::CHILD_SCROLL);
5586                 remain = result.remain;
5587             } else if ((velocity < 0 && nestedScroll.backward == NestedScrollMode::PARENT_FIRST) ||
5588                            (velocity > 0 && nestedScroll.forward == NestedScrollMode::PARENT_FIRST)) {
5589                 remain = -velocity;
5590             }
5591             if (!NearZero(remain)) {
5592                 HandleScroll(parent.Upgrade(), remain, SCROLL_FROM_UPDATE, NestedState::CHILD_OVER_SCROLL);
5593             }
5594         }
5595     } else {
5596         if (((velocity > 0 && nestedScroll.backward == NestedScrollMode::SELF_FIRST) ||
5597                 (velocity < 0 && nestedScroll.forward == NestedScrollMode::SELF_FIRST))) {
5598             if (isFirstFlingScrollVelocity_) {
5599                 HandleScrollVelocity(parent.Upgrade(), velocity);
5600                 isFirstFlingScrollVelocity_ = false;
5601             }
5602         }
5603     }
5604 }
5605 
OnScrollState(bool scrollState)5606 void WebPattern::OnScrollState(bool scrollState)
5607 {
5608     scrollState_ = scrollState;
5609     if (!scrollState) {
5610         OnScrollEndRecursive(std::nullopt);
5611     } else {
5612         GetParentAxis();
5613         OnScrollStartRecursive(std::vector<float>({ 0.0, 0.0 }));
5614         if (imageAnalyzerManager_) {
5615             imageAnalyzerManager_->UpdateOverlayStatus(
5616                 false,
5617                 0,
5618                 0,
5619                 0,
5620                 0);
5621         }
5622     }
5623 }
5624 
SetLayoutMode(WebLayoutMode mode)5625 void WebPattern::SetLayoutMode(WebLayoutMode mode)
5626 {
5627     if (layoutMode_ == mode) {
5628         return;
5629     }
5630     layoutMode_ = mode;
5631     TAG_LOGI(AceLogTag::ACE_WEB, "layoutMode is: %{public}d.", layoutMode_);
5632     OnZoomAccessEnabledUpdate(GetZoomAccessEnabledValue(true));
5633     if (delegate_) {
5634         delegate_->UpdateLayoutMode(mode);
5635     }
5636     isLayoutModeChanged_ = true;
5637     auto frameNode = GetHost();
5638     CHECK_NULL_VOID(frameNode);
5639     frameNode->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_MEASURE | PROPERTY_UPDATE_RENDER);
5640 }
5641 
SetRenderMode(RenderMode renderMode)5642 void WebPattern::SetRenderMode(RenderMode renderMode)
5643 {
5644     if (isRenderModeInit_) {
5645         TAG_LOGI(AceLogTag::ACE_WEB, "renderMode not allow to change.");
5646         return;
5647     }
5648     renderMode_ = renderMode;
5649     TAG_LOGI(AceLogTag::ACE_WEB, "web renderMode is: %{public}d.", renderMode_);
5650     isRenderModeInit_ = true;
5651 }
5652 
GetParentAxis()5653 void WebPattern::GetParentAxis()
5654 {
5655     auto parent = GetNestedScrollParent();
5656     if (parent) {
5657         axis_ = parent->GetAxis();
5658         parentsMap_ = { { axis_, parent } };
5659         auto oppositeParent = SearchParent(axis_ == Axis::HORIZONTAL ? Axis::VERTICAL : Axis::HORIZONTAL);
5660         if (oppositeParent) {
5661             parentsMap_.emplace(oppositeParent->GetAxis(), oppositeParent);
5662         }
5663     } else {
5664         auto verticalParent = SearchParent(Axis::VERTICAL);
5665         auto horizontalParent = SearchParent(Axis::HORIZONTAL);
5666         if (verticalParent) {
5667             parentsMap_.emplace(verticalParent->GetAxis(), verticalParent);
5668         }
5669         if (horizontalParent) {
5670             parentsMap_.emplace(horizontalParent->GetAxis(), horizontalParent);
5671         }
5672     }
5673 }
5674 
SearchParent()5675 RefPtr<NestableScrollContainer> WebPattern::SearchParent()
5676 {
5677     return SearchParent(Axis::NONE);
5678 }
5679 
SearchParent(Axis scrollAxis)5680 RefPtr<NestableScrollContainer> WebPattern::SearchParent(Axis scrollAxis)
5681 {
5682     auto host = GetHost();
5683     CHECK_NULL_RETURN(host, nullptr);
5684     for (auto parent = host->GetParent(); parent != nullptr; parent = parent->GetParent()) {
5685         RefPtr<FrameNode> frameNode = AceType::DynamicCast<FrameNode>(parent);
5686         if (!frameNode) {
5687             continue;
5688         }
5689         auto pattern = frameNode->GetPattern<NestableScrollContainer>();
5690         if (!pattern ||
5691             (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE) &&
5692                 InstanceOf<RefreshPattern>(pattern))) {
5693             continue;
5694         }
5695         if (scrollAxis == Axis::NONE || scrollAxis == pattern->GetAxis()) {
5696             return pattern;
5697         }
5698     }
5699     return nullptr;
5700 }
5701 
IsDialogNested()5702 bool WebPattern::IsDialogNested()
5703 {
5704     auto host = GetHost();
5705     CHECK_NULL_RETURN(host, false);
5706     for (auto parent = host->GetParent(); parent != nullptr; parent = parent->GetParent()) {
5707         RefPtr<FrameNode> frameNode = AceType::DynamicCast<FrameNode>(parent);
5708         if (!frameNode) {
5709             continue;
5710         }
5711         if (frameNode->GetPattern<DialogPattern>()) {
5712             return true;
5713         }
5714     }
5715     return false;
5716 }
5717 
OnProgressChanged(int param)5718 void WebPattern::OnProgressChanged(int param)
5719 {
5720     progressParam_ = param;
5721 }
5722 
OnRootLayerChanged(int width,int height)5723 void WebPattern::OnRootLayerChanged(int width, int height)
5724 {
5725     if ((rootLayerWidth_ == width) && (rootLayerHeight_ == height)) {
5726         return;
5727     }
5728     TAG_LOGI(AceLogTag::ACE_WEB, "OnRootLayerChanged width : %{public}d, height : %{public}d", width, height);
5729     rootLayerWidth_ = width;
5730     rootLayerHeight_ = height;
5731     if (layoutMode_ != WebLayoutMode::FIT_CONTENT) {
5732         return;
5733     }
5734     rootLayerChangeSize_ = Size(width, height);
5735     if (GetPendingSizeStatus()) {
5736         return;
5737     }
5738     ReleaseResizeHold();
5739 }
5740 
ReleaseResizeHold()5741 void WebPattern::ReleaseResizeHold()
5742 {
5743     if (layoutMode_ != WebLayoutMode::FIT_CONTENT) {
5744         return;
5745     }
5746     drawSize_.SetSize(rootLayerChangeSize_);
5747     auto frameNode = GetHost();
5748     CHECK_NULL_VOID(frameNode);
5749     frameNode->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT | PROPERTY_UPDATE_MEASURE | PROPERTY_UPDATE_RENDER);
5750 }
5751 
FilterScrollEvent(const float x,const float y,const float xVelocity,const float yVelocity)5752 bool WebPattern::FilterScrollEvent(const float x, const float y, const float xVelocity, const float yVelocity)
5753 {
5754     if (isNeedUpdateScrollAxis_) {
5755         expectedScrollAxis_ = (x != 0 || y != 0)
5756             ? (abs(x) > abs(y) ? Axis::HORIZONTAL : Axis::VERTICAL)
5757             : (abs(xVelocity) > abs(yVelocity) ? Axis::HORIZONTAL : Axis::VERTICAL);
5758         // if there is a parent component in the sliding direction, there is no need to update the direction.
5759         if (parentsMap_.find(expectedScrollAxis_) != parentsMap_.end()) {
5760             isNeedUpdateScrollAxis_ = false;
5761             TAG_LOGI(AceLogTag::ACE_WEB,
5762                 "WebPattern::FilterScrollEvent updateScrollAxis, x=%{public}f, y=%{public}f, "
5763                 "vx=%{public}f, vy=%{public}f, scrolAxis=%{public}d",
5764                 x,
5765                 y,
5766                 xVelocity,
5767                 yVelocity,
5768                 static_cast<int32_t>(expectedScrollAxis_));
5769         }
5770     }
5771     float offset = expectedScrollAxis_ == Axis::HORIZONTAL ? x : y;
5772     float velocity = expectedScrollAxis_ == Axis::HORIZONTAL ? xVelocity : yVelocity;
5773     bool isConsumed = offset != 0 ? FilterScrollEventHandleOffset(offset) : FilterScrollEventHandlevVlocity(velocity);
5774     return isConsumed;
5775 }
5776 
FilterScrollEventHandleOffset(const float offset)5777 bool WebPattern::FilterScrollEventHandleOffset(const float offset)
5778 {
5779     auto it = parentsMap_.find(expectedScrollAxis_);
5780     CHECK_EQUAL_RETURN(it, parentsMap_.end(), false);
5781     auto parent = it->second;
5782     auto nestedScroll = GetNestedScroll();
5783     if (((offset > 0) && nestedScroll.backward == NestedScrollMode::PARENT_FIRST) ||
5784         ((offset < 0) && nestedScroll.forward == NestedScrollMode::PARENT_FIRST)) {
5785         auto result = HandleScroll(parent.Upgrade(), offset, SCROLL_FROM_UPDATE, NestedState::CHILD_SCROLL);
5786         CHECK_EQUAL_RETURN(isParentReachEdge_ && result.reachEdge, true, false);
5787         isParentReachEdge_ = result.reachEdge;
5788         CHECK_NULL_RETURN(delegate_, false);
5789         expectedScrollAxis_ == Axis::HORIZONTAL ? delegate_->ScrollByRefScreen(-result.remain, 0)
5790                                                 : delegate_->ScrollByRefScreen(0, -result.remain);
5791         return true;
5792     } else if (((offset > 0) && nestedScroll.backward == NestedScrollMode::PARALLEL) ||
5793                ((offset < 0) && nestedScroll.forward == NestedScrollMode::PARALLEL)) {
5794         HandleScroll(parent.Upgrade(), offset, SCROLL_FROM_UPDATE, NestedState::CHILD_SCROLL);
5795     } else if ((Positive(offset) && nestedScroll.backward == NestedScrollMode::SELF_FIRST) ||
5796                (Negative(offset) && nestedScroll.forward == NestedScrollMode::SELF_FIRST)) {
5797         if (parent.Upgrade() && parent.Upgrade()->NestedScrollOutOfBoundary()) {
5798             HandleScroll(parent.Upgrade(), offset, SCROLL_FROM_UPDATE, NestedState::CHILD_OVER_SCROLL);
5799             return true;
5800         }
5801     }
5802     return false;
5803 }
5804 
FilterScrollEventHandlevVlocity(const float velocity)5805 bool WebPattern::FilterScrollEventHandlevVlocity(const float velocity)
5806 {
5807     auto it = parentsMap_.find(expectedScrollAxis_);
5808     CHECK_EQUAL_RETURN(it, parentsMap_.end(), false);
5809     auto parent = it->second;
5810     auto nestedScroll = GetNestedScroll();
5811     if (((velocity > 0) && nestedScroll.backward == NestedScrollMode::PARENT_FIRST) ||
5812         ((velocity < 0) && nestedScroll.forward == NestedScrollMode::PARENT_FIRST)) {
5813         if (isParentReachEdge_) {
5814             return false;
5815         }
5816         return HandleScrollVelocity(parent.Upgrade(), velocity);
5817     } else if ((velocity > 0 && nestedScroll.backward == NestedScrollMode::PARALLEL) ||
5818                (velocity < 0 && nestedScroll.forward == NestedScrollMode::PARALLEL)) {
5819         HandleScrollVelocity(parent.Upgrade(), velocity);
5820     }
5821     return false;
5822 }
5823 
IsDefaultFocusNodeExist()5824 bool WebPattern::IsDefaultFocusNodeExist()
5825 {
5826     auto pipeline = PipelineContext::GetCurrentContext();
5827     CHECK_NULL_RETURN(pipeline, false);
5828     auto focusManager = pipeline->GetFocusManager();
5829     CHECK_NULL_RETURN(focusManager, false);
5830     auto focusView =  focusManager->GetLastFocusView().Upgrade();
5831     CHECK_NULL_RETURN(focusView, false);
5832     auto focusHub = focusView->GetFocusHub();
5833     CHECK_NULL_RETURN(focusHub, false);
5834     bool result = focusHub->GetChildFocusNodeByType();
5835     return result;
5836 }
5837 
JavaScriptOnDocumentStart(const ScriptItems & scriptItems)5838 void WebPattern::JavaScriptOnDocumentStart(const ScriptItems& scriptItems)
5839 {
5840     onDocumentStartScriptItems_ = std::make_optional<ScriptItems>(scriptItems);
5841     if (delegate_) {
5842         UpdateJavaScriptOnDocumentStart();
5843         delegate_->JavaScriptOnDocumentStart();
5844     }
5845 }
5846 
UpdateJavaScriptOnDocumentStart()5847 void WebPattern::UpdateJavaScriptOnDocumentStart()
5848 {
5849     if (delegate_ && onDocumentStartScriptItems_.has_value()) {
5850         delegate_->SetJavaScriptItems(onDocumentStartScriptItems_.value(), ScriptItemType::DOCUMENT_START);
5851         onDocumentStartScriptItems_ = std::nullopt;
5852     }
5853 }
5854 
InitSlideUpdateListener()5855 void WebPattern::InitSlideUpdateListener()
5856 {
5857     auto host = GetHost();
5858     CHECK_NULL_VOID(host);
5859     for (auto parent = host->GetParent(); parent != nullptr; parent = parent->GetParent()) {
5860         bool hasTargetParent =
5861             std::find(SYNC_RENDER_SLIDE.begin(), SYNC_RENDER_SLIDE.end(), parent->GetTag()) == SYNC_RENDER_SLIDE.end();
5862         if (hasTargetParent) {
5863             continue;
5864         }
5865         RefPtr<FrameNode> frameNode = AceType::DynamicCast<FrameNode>(parent);
5866         CHECK_NULL_VOID(frameNode);
5867         if (parent->GetTag() == V2::LIST_ETS_TAG) {
5868             auto pattern = frameNode->GetPattern<ListPattern>();
5869             CHECK_NULL_VOID(pattern);
5870             syncAxis_ = pattern->GetAxis();
5871         } else {
5872             auto pattern = frameNode->GetPattern<ScrollPattern>();
5873             CHECK_NULL_VOID(pattern);
5874             syncAxis_ = pattern->GetAxis();
5875         }
5876         CHECK_NULL_VOID(renderSurface_);
5877         renderSurface_->SetWebSlideAxis(syncAxis_);
5878     }
5879 }
5880 
UpdateSlideOffset()5881 void WebPattern::UpdateSlideOffset()
5882 {
5883     switch (syncAxis_) {
5884         case Axis::HORIZONTAL:
5885             CalculateHorizontalDrawRect();
5886             break;
5887         case Axis::VERTICAL:
5888             CalculateVerticalDrawRect();
5889             break;
5890         default :
5891             break;
5892     }
5893 }
5894 
CalculateHorizontalDrawRect()5895 void WebPattern::CalculateHorizontalDrawRect()
5896 {
5897     fitContentOffset_ = OffsetF(GetCoordinatePoint()->GetX(), GetCoordinatePoint()->GetY());
5898     CHECK_NULL_VOID(renderSurface_);
5899     renderSurface_->SetWebOffset(fitContentOffset_.GetX());
5900     if (fitContentOffset_.GetX() >= 0) {
5901         if (isNeedReDrawRect_) {
5902             SetDrawRect(0, 0, ADJUST_WEB_DRAW_LENGTH + ADJUST_WEB_DRAW_LENGTH, drawRectHeight_);
5903         }
5904         isNeedReDrawRect_ = false;
5905         return;
5906     }
5907 
5908     int32_t stepGear = (-fitContentOffset_.GetX()) / ADJUST_WEB_DRAW_LENGTH;
5909     int32_t width = ADJUST_WEB_DRAW_LENGTH * 2 + stepGear;
5910     int32_t height = std::min(static_cast<int32_t>(drawSize_.Height()), FIT_CONTENT_LIMIT_LENGTH);
5911     int32_t x = ADJUST_WEB_DRAW_LENGTH * stepGear;
5912     int32_t y = 0;
5913     renderSurface_->SetWebMessage({ x, 0 });
5914     TAG_LOGD(AceLogTag::ACE_WEB, "SetDrawRect x : %{public}d, y : %{public}d, width : %{public}d, height : %{public}d",
5915         x, y, width, height);
5916     SetDrawRect(x, y, width, height);
5917     isNeedReDrawRect_ = true;
5918 }
5919 
CalculateVerticalDrawRect()5920 void WebPattern::CalculateVerticalDrawRect()
5921 {
5922     fitContentOffset_ = OffsetF(GetCoordinatePoint()->GetX(), GetCoordinatePoint()->GetY());
5923     CHECK_NULL_VOID(renderSurface_);
5924     renderSurface_->SetWebOffset(fitContentOffset_.GetY());
5925     if (fitContentOffset_.GetY() >= 0) {
5926         if (isNeedReDrawRect_) {
5927             SetDrawRect(0, 0, drawRectWidth_, ADJUST_WEB_DRAW_LENGTH + ADJUST_WEB_DRAW_LENGTH);
5928         }
5929         isNeedReDrawRect_ = false;
5930         return;
5931     }
5932 
5933     int32_t stepGear = (-fitContentOffset_.GetY()) / ADJUST_WEB_DRAW_LENGTH;
5934     int32_t width = std::min(static_cast<int32_t>(drawSize_.Width()), FIT_CONTENT_LIMIT_LENGTH);
5935     int32_t height = ADJUST_WEB_DRAW_LENGTH * 2 + stepGear;
5936     int32_t x = 0;
5937     int32_t y = ADJUST_WEB_DRAW_LENGTH * stepGear;
5938     renderSurface_->SetWebMessage({ 0, y });
5939     TAG_LOGD(AceLogTag::ACE_WEB, "SetDrawRect x : %{public}d, y : %{public}d, width : %{public}d, height : %{public}d",
5940         x, y, width, height);
5941     SetDrawRect(x, y, width, height);
5942     isNeedReDrawRect_ = true;
5943 }
5944 
PostTaskToUI(const std::function<void ()> && task,const std::string & name) const5945 void WebPattern::PostTaskToUI(const std::function<void()>&& task, const std::string& name) const
5946 {
5947     CHECK_NULL_VOID(task);
5948     auto container = Container::Current();
5949     CHECK_NULL_VOID(container);
5950     auto pipelineContext = AccessibilityManager::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
5951     CHECK_NULL_VOID(pipelineContext);
5952     auto taskExecutor = pipelineContext->GetTaskExecutor();
5953     CHECK_NULL_VOID(taskExecutor);
5954     taskExecutor->PostTask(task, TaskExecutor::TaskType::UI, name);
5955 }
5956 
SetDrawRect(int32_t x,int32_t y,int32_t width,int32_t height)5957 void WebPattern::SetDrawRect(int32_t x, int32_t y, int32_t width, int32_t height)
5958 {
5959     if ((drawRectWidth_ == width) && (drawRectHeight_ == height)) {
5960         return;
5961     }
5962     drawRectWidth_ = width;
5963     drawRectHeight_ = height;
5964     CHECK_NULL_VOID(delegate_);
5965     delegate_->SetDrawRect(x, y, width, height);
5966 }
5967 
GetPendingSizeStatus()5968 bool WebPattern::GetPendingSizeStatus()
5969 {
5970     if (delegate_) {
5971         return delegate_->GetPendingSizeStatus();
5972     }
5973     return false;
5974 }
5975 
CreateNodePaintMethod()5976 RefPtr<NodePaintMethod> WebPattern::CreateNodePaintMethod()
5977 {
5978     auto paint = MakeRefPtr<WebPaintMethod>(renderSurface_);
5979     return paint;
5980 }
5981 
JavaScriptOnDocumentEnd(const ScriptItems & scriptItems)5982 void WebPattern::JavaScriptOnDocumentEnd(const ScriptItems& scriptItems)
5983 {
5984     onDocumentEndScriptItems_ = std::make_optional<ScriptItems>(scriptItems);
5985     if (delegate_) {
5986         UpdateJavaScriptOnDocumentEnd();
5987         delegate_->JavaScriptOnDocumentEnd();
5988     }
5989 }
5990 
UpdateJavaScriptOnDocumentEnd()5991 void WebPattern::UpdateJavaScriptOnDocumentEnd()
5992 {
5993     if (delegate_ && onDocumentEndScriptItems_.has_value()) {
5994         delegate_->SetJavaScriptItems(onDocumentEndScriptItems_.value(), ScriptItemType::DOCUMENT_END);
5995         onDocumentEndScriptItems_ = std::nullopt;
5996     }
5997 }
5998 
GetAccessibilityNodeById(int64_t accessibilityId)5999 std::shared_ptr<NWeb::NWebAccessibilityNodeInfo> WebPattern::GetAccessibilityNodeById(int64_t accessibilityId)
6000 {
6001     if (!accessibilityState_) {
6002         return nullptr;
6003     }
6004     CHECK_NULL_RETURN(delegate_, nullptr);
6005     return delegate_->GetAccessibilityNodeInfoById(accessibilityId);
6006 }
6007 
GetFocusedAccessibilityNode(int64_t accessibilityId,bool isAccessibilityFocus)6008 std::shared_ptr<NWeb::NWebAccessibilityNodeInfo> WebPattern::GetFocusedAccessibilityNode(
6009     int64_t accessibilityId, bool isAccessibilityFocus)
6010 {
6011     if (!accessibilityState_) {
6012         return nullptr;
6013     }
6014     CHECK_NULL_RETURN(delegate_, nullptr);
6015     return delegate_->GetFocusedAccessibilityNodeInfo(accessibilityId, isAccessibilityFocus);
6016 }
6017 
6018 
GetAccessibilityNodeByFocusMove(int64_t accessibilityId,int32_t direction)6019 std::shared_ptr<NWeb::NWebAccessibilityNodeInfo> WebPattern::GetAccessibilityNodeByFocusMove(int64_t accessibilityId,
6020     int32_t direction)
6021 {
6022     if (!accessibilityState_) {
6023         return nullptr;
6024     }
6025     CHECK_NULL_RETURN(delegate_, nullptr);
6026     return delegate_->GetAccessibilityNodeInfoByFocusMove(accessibilityId, direction);
6027 }
6028 
ExecuteAction(int64_t accessibilityId,AceAction action,const std::map<std::string,std::string> & actionArguments) const6029 bool WebPattern::ExecuteAction(int64_t accessibilityId, AceAction action,
6030     const std::map<std::string, std::string>& actionArguments) const
6031 {
6032     CHECK_NULL_RETURN(delegate_, false);
6033     if (!accessibilityState_) {
6034         return false;
6035     }
6036     return delegate_->ExecuteAction(accessibilityId, action, actionArguments);
6037 }
6038 
SetAccessibilityState(bool state)6039 void WebPattern::SetAccessibilityState(bool state)
6040 {
6041     CHECK_NULL_VOID(delegate_);
6042     focusedAccessibilityId_ = -1;
6043     if (!state) {
6044         if (AceApplicationInfo::GetInstance().IsAccessibilityEnabled()
6045             || inspectorAccessibilityEnable_ || textBlurAccessibilityEnable_) {
6046                 return;
6047         }
6048         accessibilityState_ = state;
6049         delegate_->SetAccessibilityState(state);
6050         return;
6051     }
6052 
6053     if (accessibilityState_ != state) {
6054         accessibilityState_ = state;
6055         delegate_->SetAccessibilityState(state);
6056     }
6057 }
6058 
JsonNodePutDefaultValue(std::unique_ptr<OHOS::Ace::JsonValue> & jsonNode,WebAccessibilityType key,bool value)6059 void WebPattern::JsonNodePutDefaultValue(std::unique_ptr<OHOS::Ace::JsonValue>& jsonNode,
6060     WebAccessibilityType key, bool value)
6061 {
6062     if (!value) {
6063         return;
6064     }
6065     jsonNode->Put(EnumTypeToString(key).c_str(), 1);
6066 }
6067 
JsonNodePutDefaultValue(std::unique_ptr<OHOS::Ace::JsonValue> & jsonNode,WebAccessibilityType key,std::string value)6068 void WebPattern::JsonNodePutDefaultValue(std::unique_ptr<OHOS::Ace::JsonValue>& jsonNode,
6069     WebAccessibilityType key, std::string value)
6070 {
6071     if (value.empty()) {
6072         return;
6073     }
6074     jsonNode->Put(EnumTypeToString(key).c_str(), value.c_str());
6075 }
6076 
JsonNodePutDefaultValue(std::unique_ptr<OHOS::Ace::JsonValue> & jsonNode,WebAccessibilityType key,int32_t value,int32_t defaultValue)6077 void WebPattern::JsonNodePutDefaultValue(std::unique_ptr<OHOS::Ace::JsonValue>& jsonNode,
6078     WebAccessibilityType key, int32_t value, int32_t defaultValue)
6079 {
6080     if (value == defaultValue) {
6081         return;
6082     }
6083     jsonNode->Put(EnumTypeToString(key).c_str(), value);
6084 }
6085 
EnumTypeToString(WebAccessibilityType type)6086 std::string WebPattern::EnumTypeToString(WebAccessibilityType type)
6087 {
6088     return std::to_string(static_cast<int>(type));
6089 }
6090 
VectorIntToString(std::vector<int64_t> && vec)6091 std::string WebPattern::VectorIntToString(std::vector<int64_t>&& vec)
6092 {
6093     std::string vecStr;
6094     uint32_t vecLen = vec.size();
6095     if (vecLen < 1) {
6096         return vecStr;
6097     }
6098     for (uint32_t i = 0; i < vecLen - 1; ++i) {
6099         vecStr += std::to_string(vec[i]) + " ";
6100     }
6101     return vecStr + std::to_string(vec[vecLen - 1]);
6102 }
6103 
WebNodeInfoToJsonValue(std::shared_ptr<OHOS::Ace::JsonValue> & jsonNodeArray,std::shared_ptr<OHOS::NWeb::NWebAccessibilityNodeInfo> webNodeInfo,std::string & nodeTag)6104 void WebPattern::WebNodeInfoToJsonValue(std::shared_ptr<OHOS::Ace::JsonValue>& jsonNodeArray,
6105     std::shared_ptr<OHOS::NWeb::NWebAccessibilityNodeInfo> webNodeInfo, std::string& nodeTag)
6106 {
6107     auto jsonNode = JsonUtil::Create(true);
6108     jsonNode->Put(WEB_NODE_URL, delegate_ ? delegate_->GetUrl().c_str() : "");
6109     jsonNode->Put(EnumTypeToString(WebAccessibilityType::ID).c_str(), webNodeInfo->GetAccessibilityId());
6110     if (webNodeInfo->GetSelectionEnd() != 0) {
6111         jsonNode->Put(EnumTypeToString(WebAccessibilityType::SEL_START).c_str(), webNodeInfo->GetSelectionStart());
6112         jsonNode->Put(EnumTypeToString(WebAccessibilityType::SEL_END).c_str(), webNodeInfo->GetSelectionEnd());
6113     }
6114     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::INPUT_TYPE, webNodeInfo->GetInputType(), -1);
6115     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::LIVE_REGION, webNodeInfo->GetLiveRegion(), -1);
6116     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::HINT, webNodeInfo->GetHint());
6117     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::CONTENT, webNodeInfo->GetContent());
6118     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::ERROR, webNodeInfo->GetError());
6119     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::CHILD_IDS, VectorIntToString(webNodeInfo->GetChildIds()));
6120     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::PARENT_ID, webNodeInfo->GetParentId(), -1);
6121     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::GRID_ROWS, webNodeInfo->GetGridRows(), -1);
6122     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::GRID_COLS, webNodeInfo->GetGridColumns(), -1);
6123     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::GRID_SEL_MODE, webNodeInfo->GetGridSelectedMode(), -1);
6124     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::GRID_ITEM_ROW, webNodeInfo->GetGridItemRow(), -1);
6125     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::GRID_ITEM_ROW_SPAN, webNodeInfo->GetGridItemRowSpan(), -1);
6126     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::GRID_ITEM_COL, webNodeInfo->GetGridItemColumn(), -1);
6127     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::GRID_ITEM_COL_SPAN,
6128         webNodeInfo->GetGridItemColumnSpan(), -1);
6129     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::PAGE_ID, webNodeInfo->GetPageId(), -1);
6130 
6131     if (webNodeInfo->GetRectWidth() != 0 || webNodeInfo->GetRectHeight() != 0) {
6132         jsonNode->Put(EnumTypeToString(WebAccessibilityType::RECTX).c_str(), webNodeInfo->GetRectX());
6133         jsonNode->Put(EnumTypeToString(WebAccessibilityType::RECTY).c_str(), webNodeInfo->GetRectY());
6134         jsonNode->Put(EnumTypeToString(WebAccessibilityType::RECT_WIDTH).c_str(), webNodeInfo->GetRectWidth());
6135         jsonNode->Put(EnumTypeToString(WebAccessibilityType::RECT_HEIGHT).c_str(), webNodeInfo->GetRectHeight());
6136     }
6137 
6138     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::HEADING, webNodeInfo->GetIsHeading());
6139     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::CHECKED, webNodeInfo->GetIsChecked());
6140     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::EDITABLE, webNodeInfo->GetIsEditable());
6141     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::ENABLED, webNodeInfo->GetIsEnabled());
6142     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::FOCUSED, webNodeInfo->GetIsFocused());
6143     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::SELECTED, webNodeInfo->GetIsSelected());
6144     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::CHECKABLE, webNodeInfo->GetIsCheckable());
6145     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::CLICKABLE, webNodeInfo->GetIsClickable());
6146     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::FOCUSABLE, webNodeInfo->GetIsFocusable());
6147     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::SCROLLABLE, webNodeInfo->GetIsScrollable());
6148     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::PASSWORD, webNodeInfo->GetIsPassword());
6149     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::VISIBLE, webNodeInfo->GetIsVisible());
6150     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::PLURAL_LINE, webNodeInfo->GetIsPluralLineSupported());
6151     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::POPUP, webNodeInfo->GetIsPopupSupported());
6152     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::DELETABLE, webNodeInfo->GetIsDeletable());
6153     JsonNodePutDefaultValue(jsonNode, WebAccessibilityType::FOCUS, webNodeInfo->GetIsAccessibilityFocus());
6154     jsonNodeArray->PutRef(nodeTag.c_str(), std::move(jsonNode));
6155 }
6156 
GetWebAllInfosImpl(WebNodeInfoCallback cb,int32_t webId)6157 void WebPattern::GetWebAllInfosImpl(WebNodeInfoCallback cb, int32_t webId)
6158 {
6159     std::shared_ptr<OHOS::NWeb::NWebAccessibilityNodeInfo> rootWebNode;
6160     if (delegate_) {
6161         rootWebNode = delegate_->GetAccessibilityNodeInfoById(-1);
6162     }
6163     CHECK_NULL_VOID(rootWebNode);
6164 
6165     auto jsonNodeArray = static_cast<std::shared_ptr<JsonValue> >(JsonUtil::Create(true));
6166     std::queue<uint64_t> que;
6167     for (auto id: rootWebNode->GetChildIds()) {
6168         que.push(id);
6169     }
6170     int nodeCount = 0;
6171     while (!que.empty()) {
6172         uint64_t tmp = que.front();
6173         que.pop();
6174         auto webNodeInfo = delegate_->GetAccessibilityNodeInfoById(tmp);
6175         CHECK_NULL_VOID(webNodeInfo);
6176         auto componentType = webNodeInfo->GetComponentType();
6177         if (componentType.compare(ACCESSIBILITY_GENERIC_CONTAINER) != 0
6178             && componentType.compare(ACCESSIBILITY_PARAGRAPH) != 0
6179             && componentType.compare(ACCESSIBILITY_IMAGE) != 0) {
6180             WebNodeInfoToJsonValue(jsonNodeArray, webNodeInfo, componentType);
6181         }
6182         for (auto id: webNodeInfo->GetChildIds()) {
6183             que.push(id);
6184         }
6185         nodeCount++;
6186     }
6187     TAG_LOGD(AceLogTag::ACE_WEB, "Current web info node count: %{public}d", nodeCount);
6188     cb(jsonNodeArray, webId);
6189     inspectorAccessibilityEnable_ = false;
6190     SetAccessibilityState(false);
6191 }
6192 
GetAllWebAccessibilityNodeInfos(WebNodeInfoCallback cb,int32_t webId)6193 void WebPattern::GetAllWebAccessibilityNodeInfos(WebNodeInfoCallback cb, int32_t webId)
6194 {
6195     CHECK_NULL_VOID(cb);
6196     inspectorAccessibilityEnable_ = true;
6197     SetAccessibilityState(true);
6198     auto container = Container::Current();
6199     CHECK_NULL_VOID(container);
6200     auto host = GetHost();
6201     CHECK_NULL_VOID(host);
6202     auto pipelineContext = host->GetContext();
6203     CHECK_NULL_VOID(pipelineContext);
6204     auto taskExecutor = pipelineContext->GetTaskExecutor();
6205     taskExecutor->PostDelayedTask([weak = WeakClaim(this), cb, webId] () {
6206         auto pattern = weak.Upgrade();
6207         auto startTime = std::chrono::high_resolution_clock::now();
6208         pattern->GetWebAllInfosImpl(cb, webId);
6209         auto nowTime = std::chrono::high_resolution_clock::now();
6210         std::chrono::duration<double, std::milli> diff =
6211             std::chrono::duration_cast<std::chrono::milliseconds>(nowTime - startTime);
6212         TAG_LOGD(AceLogTag::ACE_WEB, "GetAllAccessibilityInfo time cost: %{public}f", diff.count());
6213         },
6214         TaskExecutor::TaskType::UI, WEB_ACCESSIBILITY_DELAY_TIME, "GetAllWebAccessibilityNodeInfos");
6215 }
6216 
RegisterWebComponentClickCallback(WebComponentClickCallback && callback)6217 void WebPattern::RegisterWebComponentClickCallback(WebComponentClickCallback&& callback)
6218 {
6219     CHECK_NULL_VOID(callback);
6220     webComponentClickCallback_ = std::move(callback);
6221     textBlurAccessibilityEnable_ = true;
6222     SetAccessibilityState(true);
6223 }
6224 
UnregisterWebComponentClickCallback()6225 void WebPattern::UnregisterWebComponentClickCallback()
6226 {
6227     webComponentClickCallback_ = nullptr;
6228     textBlurAccessibilityEnable_ = false;
6229     SetAccessibilityState(false);
6230 }
6231 
UpdateFocusedAccessibilityId(int64_t accessibilityId)6232 void WebPattern::UpdateFocusedAccessibilityId(int64_t accessibilityId)
6233 {
6234     if (!accessibilityState_) {
6235         return;
6236     }
6237     auto host = GetHost();
6238     CHECK_NULL_VOID(host);
6239     auto renderContext = host->GetRenderContext();
6240     CHECK_NULL_VOID(renderContext);
6241 
6242     if (accessibilityId > 0) {
6243         focusedAccessibilityId_ = accessibilityId;
6244     }
6245     RectT<int32_t> rect;
6246     if (focusedAccessibilityId_ <= 0 || !GetAccessibilityFocusRect(rect, focusedAccessibilityId_)) {
6247         renderContext->ResetAccessibilityFocusRect();
6248         renderContext->UpdateAccessibilityFocus(false);
6249         return;
6250     }
6251 
6252     renderContext->UpdateAccessibilityFocusRect(rect);
6253     renderContext->UpdateAccessibilityFocus(true);
6254 }
6255 
ClearFocusedAccessibilityId()6256 void WebPattern::ClearFocusedAccessibilityId()
6257 {
6258     if (!accessibilityState_) {
6259         return;
6260     }
6261 
6262     focusedAccessibilityId_ = -1;
6263     auto host = GetHost();
6264     CHECK_NULL_VOID(host);
6265     auto renderContext = host->GetRenderContext();
6266     CHECK_NULL_VOID(renderContext);
6267     renderContext->ResetAccessibilityFocusRect();
6268     renderContext->UpdateAccessibilityFocus(false);
6269 }
6270 
GetSurfaceRSNode() const6271 std::shared_ptr<Rosen::RSNode> WebPattern::GetSurfaceRSNode() const
6272 {
6273     CHECK_NULL_RETURN(renderContextForSurface_, nullptr);
6274     auto rosenRenderContext = AceType::DynamicCast<NG::RosenRenderContext>(renderContextForSurface_);
6275     CHECK_NULL_RETURN(rosenRenderContext, nullptr);
6276     return rosenRenderContext->GetRSNode();
6277 }
6278 
GetAccessibilityFocusRect(RectT<int32_t> & paintRect,int64_t accessibilityId) const6279 bool WebPattern::GetAccessibilityFocusRect(RectT<int32_t>& paintRect, int64_t accessibilityId) const
6280 {
6281     if (!accessibilityState_) {
6282         return false;
6283     }
6284     CHECK_NULL_RETURN(delegate_, false);
6285     std::shared_ptr<OHOS::NWeb::NWebAccessibilityNodeInfo> info =
6286         delegate_->GetAccessibilityNodeInfoById(accessibilityId);
6287     if (!info) {
6288         return false;
6289     }
6290 
6291     paintRect.SetRect(info->GetRectX(), info->GetRectY(), info->GetRectWidth(), info->GetRectHeight());
6292     return true;
6293 }
6294 
SetTouchEventInfo(const TouchEvent & touchEvent,TouchEventInfo & touchEventInfo,const std::string & embedId)6295 void WebPattern::SetTouchEventInfo(const TouchEvent& touchEvent,
6296     TouchEventInfo& touchEventInfo, const std::string& embedId)
6297 {
6298     CHECK_NULL_VOID(delegate_);
6299     auto host = GetHost();
6300     CHECK_NULL_VOID(host);
6301     auto offset = host->GetTransformRelativeOffset();
6302 
6303     TouchEventInfo tempTouchInfo = touchEventInfo_;
6304     if (touchEvent.type == TouchType::DOWN || touchEvent.type == TouchType::UP) {
6305         while (!touchEventQueue_.empty()) {
6306             if (touchEventQueue_.front().GetChangedTouches().front().GetFingerId() == touchEvent.id) {
6307                 tempTouchInfo = touchEventQueue_.front();
6308                 touchEventQueue_.pop();
6309                 break;
6310             } else {
6311                 touchEventQueue_.pop();
6312             }
6313         }
6314     }
6315     auto pos = delegate_->GetPosition(embedId);
6316     touchEventInfo.SetSourceDevice(tempTouchInfo.GetSourceDevice());
6317     touchEventInfo.SetTarget(tempTouchInfo.GetTarget());
6318     touchEventInfo.SetForce(tempTouchInfo.GetForce());
6319     touchEventInfo.SetSourceTool(tempTouchInfo.GetSourceTool());
6320     touchEventInfo.SetTargetDisplayId(tempTouchInfo.GetTargetDisplayId());
6321     touchEventInfo.SetDeviceId(tempTouchInfo.GetDeviceId());
6322 
6323     TouchLocationInfo changedInfo("onTouch", touchEvent.id);
6324     changedInfo.SetLocalLocation(Offset(touchEvent.x, touchEvent.y));
6325     changedInfo.SetGlobalLocation(Offset(touchEvent.x + offset.GetX() + pos.GetX(),
6326         touchEvent.y + offset.GetY() + pos.GetY()));
6327     changedInfo.SetScreenLocation(Offset(touchEvent.x + offset.GetX() + pos.GetX(),
6328         touchEvent.y + offset.GetY() + pos.GetY()));
6329     changedInfo.SetTouchType(touchEvent.type);
6330 
6331     SetTouchLocationInfo(touchEvent, changedInfo, tempTouchInfo, touchEventInfo);
6332 
6333     touchEventInfo.AddChangedTouchLocationInfo(std::move(changedInfo));
6334 }
6335 
SetTouchLocationInfo(const TouchEvent & touchEvent,const TouchLocationInfo & changedInfo,const TouchEventInfo & tempTouchInfo,TouchEventInfo & touchEventInfo)6336 void WebPattern::SetTouchLocationInfo(const TouchEvent& touchEvent, const TouchLocationInfo& changedInfo,
6337     const TouchEventInfo& tempTouchInfo, TouchEventInfo& touchEventInfo)
6338 {
6339     float scaleX = 0.0f;
6340     float scaleY = 0.0f;
6341     const std::list<TouchLocationInfo>& touchList = tempTouchInfo.GetTouches();
6342     for (const TouchLocationInfo& location : touchList) {
6343         if (touchEvent.id == location.GetFingerId()) {
6344             const OHOS::Ace::Offset& localLocation = location.GetLocalLocation();
6345             scaleX = localLocation.GetX() - touchEvent.x;
6346             scaleY = localLocation.GetY() - touchEvent.y;
6347         }
6348     }
6349     for (const TouchLocationInfo& location : touchList) {
6350         TouchLocationInfo info("onTouch", location.GetFingerId());
6351         if (touchEvent.id == location.GetFingerId()) {
6352             info.SetGlobalLocation(changedInfo.GetGlobalLocation());
6353             info.SetLocalLocation(changedInfo.GetLocalLocation());
6354             info.SetScreenLocation(changedInfo.GetScreenLocation());
6355             info.SetTouchType(changedInfo.GetTouchType());
6356         } else {
6357             const OHOS::Ace::Offset& localLocation = location.GetLocalLocation();
6358             const OHOS::Ace::Offset& globalLocation = location.GetGlobalLocation();
6359             const OHOS::Ace::Offset& screenLocation = location.GetScreenLocation();
6360             info.SetGlobalLocation(Offset(globalLocation.GetX() - scaleX, globalLocation.GetY() - scaleY));
6361             info.SetLocalLocation(Offset(localLocation.GetX() - scaleX, localLocation.GetY() - scaleY));
6362             info.SetScreenLocation(Offset(screenLocation.GetX() - scaleX, screenLocation.GetY() - scaleY));
6363             info.SetTouchType(location.GetTouchType());
6364         }
6365         touchEventInfo.AddTouchLocationInfo(std::move(info));
6366     }
6367 }
6368 
RegisterVisibleAreaChangeCallback(const RefPtr<PipelineContext> & pipeline)6369 void WebPattern::RegisterVisibleAreaChangeCallback(const RefPtr<PipelineContext> &pipeline)
6370 {
6371     auto host = GetHost();
6372     CHECK_NULL_VOID(host);
6373     auto callback = [weak = WeakClaim(this)](bool visible, double ratio) {
6374         auto webPattern = weak.Upgrade();
6375         CHECK_NULL_VOID(webPattern);
6376         if (!visible && !NearZero(ratio)) {
6377             TAG_LOGI(AceLogTag::ACE_WEB, "Fiterate not visible when ratio=%{public}f", ratio);
6378             return;
6379         }
6380         webPattern->OnVisibleAreaChange(visible);
6381     };
6382     std::vector<double> ratioList = {0.0, 1.0};
6383     pipeline->AddVisibleAreaChangeNode(host, ratioList, callback, false, true);
6384 }
6385 
GetWordSelection(const std::string & text,int8_t offset)6386 std::vector<int8_t> WebPattern::GetWordSelection(const std::string& text, int8_t offset)
6387 {
6388     // start sync task
6389     std::future<std::vector<int8_t>> future = std::async(std::launch::async, [text, offset]() {
6390         return DataDetectorMgr::GetInstance().GetWordSelection(text, offset);
6391     });
6392     // set timeout
6393     auto status = future.wait_for(std::chrono::milliseconds(AI_TIMEOUT_LIMIT));
6394     if (status == std::future_status::ready) {
6395         return future.get();
6396     } else {
6397         TAG_LOGE(AceLogTag::ACE_WEB, "WebPattern::GetWordSelection timeout! return default");
6398         return std::vector<int8_t> { -1, -1 };
6399     }
6400 }
6401 
CheckSafeAreaIsExpand()6402 bool WebPattern::CheckSafeAreaIsExpand()
6403 {
6404     auto host = GetHost();
6405     CHECK_NULL_RETURN(host, false);
6406     auto layoutProperty = host->GetLayoutProperty();
6407     CHECK_NULL_RETURN(layoutProperty, false);
6408     auto &&opts = layoutProperty->GetSafeAreaExpandOpts();
6409     CHECK_NULL_RETURN(opts, false);
6410     if ((opts->type & SAFE_AREA_TYPE_SYSTEM) || (opts->type & SAFE_AREA_TYPE_KEYBOARD)) {
6411         return true;
6412     }
6413     return false;
6414 }
6415 
CheckSafeAreaKeyBoard()6416 bool WebPattern::CheckSafeAreaKeyBoard()
6417 {
6418     auto host = GetHost();
6419     CHECK_NULL_RETURN(host, false);
6420     auto layoutProperty = host->GetLayoutProperty();
6421     CHECK_NULL_RETURN(layoutProperty, false);
6422     auto &&opts = layoutProperty->GetSafeAreaExpandOpts();
6423     CHECK_NULL_RETURN(opts, false);
6424     if ((opts->type & SAFE_AREA_TYPE_KEYBOARD) && (opts->edges & SAFE_AREA_EDGE_BOTTOM)) {
6425         TAG_LOGI(AceLogTag::ACE_WEB, "SafeArea type is KEYBOARD.");
6426         return true;
6427     }
6428     return false;
6429 }
6430 
Backward()6431 bool WebPattern::Backward()
6432 {
6433     if (!delegate_) {
6434         TAG_LOGE(AceLogTag::ACE_WEB, "delegate is null");
6435         return false;
6436     }
6437     if (delegate_->AccessBackward()) {
6438         delegate_->Backward();
6439         return true;
6440     }
6441     return false;
6442 }
6443 
SuggestionSelected(int32_t index)6444 void WebPattern::SuggestionSelected(int32_t index)
6445 {
6446     TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::SuggestionSelected index:%{public}d", index);
6447     CHECK_NULL_VOID(delegate_);
6448     delegate_->SuggestionSelected(index);
6449 }
6450 
OnShowAutofillPopup(const float offsetX,const float offsetY,const std::vector<std::string> & menu_items)6451 void WebPattern::OnShowAutofillPopup(
6452     const float offsetX, const float offsetY, const std::vector<std::string>& menu_items)
6453 {
6454     TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnShowAutofillPopup");
6455     isShowAutofillPopup_ = true;
6456     auto host = GetHost();
6457     CHECK_NULL_VOID(host);
6458     auto id = host->GetId();
6459     std::vector<SelectParam> selectParam;
6460     for (auto& item : menu_items) {
6461         selectParam.push_back({ item, "" });
6462     }
6463     auto menu = MenuView::Create(selectParam, id, host->GetTag());
6464     auto context = PipelineContext::GetCurrentContext();
6465     CHECK_NULL_VOID(context);
6466     auto menuContainer = AceType::DynamicCast<FrameNode>(menu->GetChildAtIndex(0));
6467     CHECK_NULL_VOID(menuContainer);
6468     auto menuPattern = menuContainer->GetPattern<MenuPattern>();
6469     CHECK_NULL_VOID(menuPattern);
6470     auto options = menuPattern->GetOptions();
6471     for (auto &&option : options) {
6472         auto selectCallback = [weak = WeakClaim(this)](int32_t index) {
6473             auto webPattern = weak.Upgrade();
6474             CHECK_NULL_VOID(webPattern);
6475             webPattern->SuggestionSelected(index);
6476         };
6477         auto optionNode = AceType::DynamicCast<FrameNode>(option);
6478         if (optionNode) {
6479             auto hub = optionNode->GetEventHub<OptionEventHub>();
6480             auto optionPattern = optionNode->GetPattern<OptionPattern>();
6481             if (!hub || !optionPattern) {
6482                 continue;
6483             }
6484             hub->SetOnSelect(std::move(selectCallback));
6485             optionNode->MarkModifyDone();
6486         }
6487     }
6488     auto overlayManager = context->GetOverlayManager();
6489     CHECK_NULL_VOID(overlayManager);
6490     auto offset = GetCoordinatePoint().value_or(OffsetF());
6491     offset.AddX(offsetX);
6492     offset.AddY(offsetY);
6493     menu->GetOrCreateFocusHub()->SetFocusable(false);
6494     overlayManager->DeleteMenu(id);
6495     overlayManager->ShowMenu(id, offset, menu);
6496 }
6497 
OnHideAutofillPopup()6498 void WebPattern::OnHideAutofillPopup()
6499 {
6500     TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnHideAutofillPopup");
6501     if (!isShowAutofillPopup_) {
6502         return;
6503     }
6504     auto host = GetHost();
6505     CHECK_NULL_VOID(host);
6506     auto id = host->GetId();
6507     auto context = PipelineContext::GetCurrentContext();
6508     CHECK_NULL_VOID(context);
6509     auto eventHub = host->GetEventHub<WebEventHub>();
6510     auto destructor = [weak = WeakClaim(this), id]() {
6511         auto pattern = weak.Upgrade();
6512         CHECK_NULL_VOID(pattern);
6513         auto pipeline = NG::PipelineContext::GetCurrentContext();
6514         CHECK_NULL_VOID(pipeline);
6515         auto overlayManager = pipeline->GetOverlayManager();
6516         CHECK_NULL_VOID(overlayManager);
6517         overlayManager->DeleteMenu(id);
6518     };
6519     CHECK_NULL_VOID(eventHub);
6520     eventHub->SetOnDisappear(destructor);
6521     isShowAutofillPopup_ = false;
6522 }
6523 
CloseKeyboard()6524 void WebPattern::CloseKeyboard()
6525 {
6526     InputMethodManager::GetInstance()->CloseKeyboard();
6527 }
6528 
RequestFocus()6529 void WebPattern::RequestFocus()
6530 {
6531     WebRequestFocus();
6532 }
6533 
OnRebuildFrame()6534 void WebPattern::OnRebuildFrame()
6535 {
6536     auto host = GetHost();
6537     CHECK_NULL_VOID(host);
6538     auto renderContext = host->GetRenderContext();
6539     CHECK_NULL_VOID(renderContext);
6540     CHECK_NULL_VOID(renderContextForSurface_);
6541     renderContext->AddChild(renderContextForSurface_, 0);
6542 }
6543 
CreateOverlay(const RefPtr<OHOS::Ace::PixelMap> & pixelMap,int offsetX,int offsetY,int rectWidth,int rectHeight,int pointX,int pointY)6544 void WebPattern::CreateOverlay(const RefPtr<OHOS::Ace::PixelMap>& pixelMap, int offsetX, int offsetY, int rectWidth,
6545     int rectHeight, int pointX, int pointY)
6546 {
6547     if (!imageAnalyzerManager_) {
6548         imageAnalyzerManager_ = std::make_shared<ImageAnalyzerManager>(GetHost(), ImageAnalyzerHolder::WEB);
6549     }
6550     TAG_LOGI(AceLogTag::ACE_WEB,
6551         "CreateOverlay, offsetX=%{public}d, offsetY=%{public}d, width=%{public}d, height=%{public}d",
6552         offsetX,
6553         offsetY,
6554         rectWidth,
6555         rectHeight);
6556     auto task = [weak = AceType::WeakClaim(this)]() {
6557         auto webPattern = weak.Upgrade();
6558         CHECK_NULL_VOID(webPattern);
6559         webPattern->OnTextSelected();
6560     };
6561     imageAnalyzerManager_->DestroyAnalyzerOverlay();
6562     auto selectedTask = [weak = AceType::WeakClaim(this)](bool isSelected) {
6563         auto webPattern = weak.Upgrade();
6564         CHECK_NULL_VOID(webPattern);
6565         TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::CreateOverlay selectedTask=%{public}d", isSelected);
6566         webPattern->SetImageOverlaySelectedStatus(isSelected);
6567         if (isSelected) {
6568             webPattern->CloseSelectOverlay();
6569             webPattern->SelectCancel();
6570         }
6571     };
6572     imageAnalyzerManager_->SetNotifySelectedCallback(std::move(selectedTask));
6573     imageAnalyzerManager_->UpdatePressOverlay(
6574         pixelMap, offsetX, offsetY, rectWidth, rectHeight, pointX, pointY, std::move(task));
6575     imageAnalyzerManager_->CreateAnalyzerOverlay(nullptr);
6576 }
6577 
OnOverlayStateChanged(int offsetX,int offsetY,int rectWidth,int rectHeight)6578 void WebPattern::OnOverlayStateChanged(int offsetX, int offsetY, int rectWidth, int rectHeight)
6579 {
6580     if (imageAnalyzerManager_) {
6581         TAG_LOGI(AceLogTag::ACE_WEB,
6582             "OnOverlayStateChanged, offsetX=%{public}d, offsetY=%{public}d, width=%{public}d, height=%{public}d",
6583             offsetX,
6584             offsetY,
6585             rectWidth,
6586             rectHeight);
6587         imageAnalyzerManager_->UpdateOverlayStatus(true, offsetX, offsetY, rectWidth, rectHeight);
6588     }
6589 }
6590 
OnTextSelected()6591 void WebPattern::OnTextSelected()
6592 {
6593     CHECK_NULL_VOID(delegate_);
6594     delegate_->OnTextSelected();
6595     overlayCreating_ = true;
6596 }
6597 
DestroyAnalyzerOverlay()6598 void WebPattern::DestroyAnalyzerOverlay()
6599 {
6600     if (imageAnalyzerManager_ && imageAnalyzerManager_->IsOverlayCreated()) {
6601         imageAnalyzerManager_->DestroyAnalyzerOverlay();
6602         delegate_->OnDestroyImageAnalyzerOverlay();
6603     }
6604     overlayCreating_ = false;
6605     imageOverlayIsSelected_ = false;
6606 }
6607 
GetWebInfoType()6608 WebInfoType WebPattern::GetWebInfoType()
6609 {
6610     std::string factoryLevel;
6611     if (delegate_) {
6612         factoryLevel = delegate_->GetWebInfoType();
6613     }
6614     if (factoryLevel == WEB_INFO_PHONE || factoryLevel == WEB_INFO_DEFAULT) {
6615         return WebInfoType::TYPE_MOBILE;
6616     } else if (factoryLevel == WEB_INFO_TABLET) {
6617         return WebInfoType::TYPE_TABLET;
6618     } else if (factoryLevel == WEB_INFO_PC) {
6619         return WebInfoType::TYPE_2IN1;
6620     }
6621     return WebInfoType::TYPE_UNKNOWN;
6622 }
6623 
OnAccessibilityHoverEvent(const PointF & point)6624 bool WebPattern::OnAccessibilityHoverEvent(const PointF& point)
6625 {
6626     CHECK_NULL_RETURN(delegate_, false);
6627     auto host = GetHost();
6628     CHECK_NULL_RETURN(host, false);
6629     auto pipelineContext = host->GetContextRefPtr();
6630     CHECK_NULL_RETURN(pipelineContext, false);
6631     auto viewScale = pipelineContext->GetViewScale();
6632     int32_t globalX = static_cast<int32_t>(point.GetX()) * viewScale;
6633     int32_t globalY = static_cast<int32_t>(point.GetY()) * viewScale;
6634     auto offset = GetCoordinatePoint().value_or(OffsetF());
6635     globalX = static_cast<int32_t>(globalX - offset.GetX());
6636     globalY = static_cast<int32_t>(globalY - offset.GetY());
6637     delegate_->HandleAccessibilityHoverEvent(globalX, globalY);
6638     return true;
6639 }
6640 
RegisterTextBlurCallback(TextBlurCallback && callback)6641 void WebPattern::RegisterTextBlurCallback(TextBlurCallback&& callback)
6642 {
6643     CHECK_NULL_VOID(callback);
6644     textBlurCallback_ = std::move(callback);
6645     textBlurAccessibilityEnable_ = true;
6646     SetAccessibilityState(true);
6647 }
6648 
UnRegisterTextBlurCallback()6649 void WebPattern::UnRegisterTextBlurCallback()
6650 {
6651     textBlurCallback_ = nullptr;
6652     textBlurAccessibilityEnable_ = false;
6653     SetAccessibilityState(false);
6654 }
6655 
InitMagnifier()6656 void WebPattern::InitMagnifier()
6657 {
6658     magnifierController_ = MakeRefPtr<MagnifierController>(WeakClaim(this));
6659 }
6660 
InitializeAccessibility()6661 void WebPattern::InitializeAccessibility()
6662 {
6663     ContainerScope scope(instanceId_);
6664     if (accessibilityChildTreeCallback_.find(instanceId_) != accessibilityChildTreeCallback_.end()) {
6665         return;
6666     }
6667     auto frameNode = frameNode_.Upgrade();
6668     CHECK_NULL_VOID(frameNode);
6669     int64_t accessibilityId = frameNode->GetAccessibilityId();
6670     auto pipeline = PipelineContext::GetCurrentContext();
6671     CHECK_NULL_VOID(pipeline);
6672     auto accessibilityManager = pipeline->GetAccessibilityManager();
6673     CHECK_NULL_VOID(accessibilityManager);
6674     accessibilityChildTreeCallback_[instanceId_] = std::make_shared<WebAccessibilityChildTreeCallback>(
6675         WeakClaim(this), frameNode->GetAccessibilityId());
6676     accessibilityManager->RegisterAccessibilityChildTreeCallback(accessibilityId,
6677         accessibilityChildTreeCallback_[instanceId_]);
6678     if (accessibilityManager->IsRegister()) {
6679         accessibilityChildTreeCallback_[instanceId_]->OnRegister(pipeline->GetWindowId(),
6680             accessibilityManager->GetTreeId());
6681     }
6682 }
6683 
UninitializeAccessibility()6684 void WebPattern::UninitializeAccessibility()
6685 {
6686     ContainerScope scope(instanceId_);
6687     auto frameNode = frameNode_.Upgrade();
6688     CHECK_NULL_VOID(frameNode);
6689     int64_t accessibilityId = frameNode->GetAccessibilityId();
6690     auto pipeline = PipelineContext::GetCurrentContext();
6691     CHECK_NULL_VOID(pipeline);
6692     auto accessibilityManager = pipeline->GetAccessibilityManager();
6693     CHECK_NULL_VOID(accessibilityManager);
6694     if (accessibilityManager->IsRegister()) {
6695         if (accessibilityChildTreeCallback_.find(instanceId_) == accessibilityChildTreeCallback_.end() ||
6696             accessibilityChildTreeCallback_[instanceId_] == nullptr) {
6697             return;
6698         }
6699         accessibilityChildTreeCallback_[instanceId_]->OnDeregister();
6700     }
6701     accessibilityManager->DeregisterAccessibilityChildTreeCallback(accessibilityId);
6702     accessibilityChildTreeCallback_.erase(instanceId_);
6703 }
6704 
OnSetAccessibilityChildTree(int32_t childWindowId,int32_t childTreeId)6705 void WebPattern::OnSetAccessibilityChildTree(int32_t childWindowId, int32_t childTreeId)
6706 {
6707     treeId_ = childTreeId;
6708     auto frameNode = frameNode_.Upgrade();
6709     CHECK_NULL_VOID(frameNode);
6710     auto accessibilityProperty = frameNode->GetAccessibilityProperty<AccessibilityProperty>();
6711     if (accessibilityProperty != nullptr) {
6712         accessibilityProperty->SetChildWindowId(childWindowId);
6713         accessibilityProperty->SetChildTreeId(childTreeId);
6714     }
6715 }
6716 
OnAccessibilityChildTreeRegister()6717 bool WebPattern::OnAccessibilityChildTreeRegister()
6718 {
6719     ContainerScope scope(instanceId_);
6720     auto pipeline = PipelineContext::GetCurrentContext();
6721     CHECK_NULL_RETURN(pipeline, false);
6722     auto accessibilityManager = pipeline->GetAccessibilityManager();
6723     CHECK_NULL_RETURN(accessibilityManager, false);
6724     auto frameNode = frameNode_.Upgrade();
6725     CHECK_NULL_RETURN(frameNode, false);
6726     int64_t accessibilityId = frameNode->GetAccessibilityId();
6727     return accessibilityManager->RegisterWebInteractionOperationAsChildTree(accessibilityId, WeakClaim(this));
6728 }
6729 
OnAccessibilityChildTreeDeregister()6730 bool WebPattern::OnAccessibilityChildTreeDeregister()
6731 {
6732     ContainerScope scope(instanceId_);
6733     auto pipeline = PipelineContext::GetCurrentContext();
6734     CHECK_NULL_RETURN(pipeline, false);
6735     auto accessibilityManager = pipeline->GetAccessibilityManager();
6736     CHECK_NULL_RETURN(accessibilityManager, false);
6737     return accessibilityManager->DeregisterWebInteractionOperationAsChildTree(treeId_);
6738 }
6739 
GetActiveStatus() const6740 bool WebPattern::GetActiveStatus() const
6741 {
6742     return isActive_;
6743 }
6744 
GetBufferSizeByDeviceType()6745 int32_t WebPattern::GetBufferSizeByDeviceType()
6746 {
6747     return (SystemProperties::GetDeviceType() == DeviceType::PHONE) ? ASYNC_SURFACE_QUEUE_SIZE_FOR_PHONE :
6748         ASYNC_SURFACE_QUEUE_SIZE_FOR_OTHERS;
6749 }
6750 
StartVibraFeedback(const std::string & vibratorType)6751 void WebPattern::StartVibraFeedback(const std::string& vibratorType)
6752 {
6753     if (isEnabledHapticFeedback_) {
6754         NG::VibratorUtils::StartVibraFeedback(vibratorType);
6755     }
6756 }
6757 
CloseImageOverlaySelection()6758 bool WebPattern::CloseImageOverlaySelection()
6759 {
6760     if (imageOverlayIsSelected_) {
6761         TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::CloseImageOverlaySelection");
6762         DestroyAnalyzerOverlay();
6763         return true;
6764     }
6765     return false;
6766 }
6767 
OnParentScrollDragEndRecursive(RefPtr<NestableScrollContainer> parent)6768 void WebPattern::OnParentScrollDragEndRecursive(RefPtr<NestableScrollContainer> parent)
6769 {
6770     if (isDragEnd_) {
6771         return;
6772     }
6773     if (parent) {
6774         TAG_LOGI(AceLogTag::ACE_WEB, "WebPattern::OnParentScrollDragEndRecursive");
6775         parent->OnScrollDragEndRecursive();
6776     }
6777     isDragEnd_ = true;
6778 }
6779 
GetAccessibilityVisible(int64_t accessibilityId)6780 bool WebPattern::GetAccessibilityVisible(int64_t accessibilityId)
6781 {
6782     if (delegate_) {
6783         return delegate_->GetAccessibilityVisible(accessibilityId);
6784     }
6785     return true;
6786 }
6787 } // namespace OHOS::Ace::NG
6788