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