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