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