1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "frameworks/bridge/common/dom/dom_document.h"
17
18 #include "base/log/event_report.h"
19 #include "frameworks/bridge/common/dom/dom_button.h"
20 #include "frameworks/bridge/common/dom/dom_calendar.h"
21 #include "frameworks/bridge/common/dom/dom_dialog.h"
22 #include "frameworks/bridge/common/dom/dom_divider.h"
23 #include "frameworks/bridge/common/dom/dom_form.h"
24 #include "frameworks/bridge/common/dom/dom_grid_column.h"
25 #include "frameworks/bridge/common/dom/dom_grid_container.h"
26 #include "frameworks/bridge/common/dom/dom_grid_row.h"
27 #include "frameworks/bridge/common/dom/dom_image.h"
28 #include "frameworks/bridge/common/dom/dom_label.h"
29 #include "frameworks/bridge/common/dom/dom_list.h"
30 #include "frameworks/bridge/common/dom/dom_list_item_group.h"
31 #include "frameworks/bridge/common/dom/dom_marquee.h"
32 #include "frameworks/bridge/common/dom/dom_navigation_bar.h"
33 #include "frameworks/bridge/common/dom/dom_panel.h"
34 #include "frameworks/bridge/common/dom/dom_picker_view.h"
35 #include "frameworks/bridge/common/dom/dom_progress.h"
36 #include "frameworks/bridge/common/dom/dom_qrcode.h"
37 #include "frameworks/bridge/common/dom/dom_refresh.h"
38 #ifdef WEB_SUPPORTED
39 #include "frameworks/bridge/common/dom/dom_rich_text.h"
40 #endif
41 #include "frameworks/bridge/common/dom/dom_search.h"
42 #include "frameworks/bridge/common/dom/dom_slider.h"
43 #include "frameworks/bridge/common/dom/dom_stack.h"
44 #include "frameworks/bridge/common/dom/dom_svg.h"
45 #include "frameworks/bridge/common/dom/dom_svg_animate_motion.h"
46 #include "frameworks/bridge/common/dom/dom_svg_animate_transform.h"
47 #include "frameworks/bridge/common/dom/dom_svg_circle.h"
48 #include "frameworks/bridge/common/dom/dom_svg_defs.h"
49 #include "frameworks/bridge/common/dom/dom_svg_ellipse.h"
50 #include "frameworks/bridge/common/dom/dom_svg_fe_colormatrix.h"
51 #include "frameworks/bridge/common/dom/dom_svg_fe_composite.h"
52 #include "frameworks/bridge/common/dom/dom_svg_fe_gaussianblur.h"
53 #include "frameworks/bridge/common/dom/dom_svg_fe_offset.h"
54 #include "frameworks/bridge/common/dom/dom_svg_filter.h"
55 #include "frameworks/bridge/common/dom/dom_svg_g.h"
56 #include "frameworks/bridge/common/dom/dom_svg_line.h"
57 #include "frameworks/bridge/common/dom/dom_svg_mask.h"
58 #include "frameworks/bridge/common/dom/dom_svg_path.h"
59 #include "frameworks/bridge/common/dom/dom_svg_polygon.h"
60 #include "frameworks/bridge/common/dom/dom_svg_polyline.h"
61 #include "frameworks/bridge/common/dom/dom_svg_rect.h"
62 #include "frameworks/bridge/common/dom/dom_svg_text_path.h"
63 #include "frameworks/bridge/common/dom/dom_svg_tspan.h"
64 #include "frameworks/bridge/common/dom/dom_svg_use.h"
65 #include "frameworks/bridge/common/dom/dom_swiper.h"
66 #include "frameworks/bridge/common/dom/dom_switch.h"
67 #include "frameworks/bridge/common/dom/dom_textarea.h"
68 #include "frameworks/bridge/common/dom/dom_toggle.h"
69 #if defined(XCOMPONENT_SUPPORTED)
70 #include "frameworks/bridge/common/dom/dom_xcomponent.h"
71 #endif
72 #ifndef WEARABLE_PRODUCT
73 #include "frameworks/bridge/common/dom/dom_badge.h"
74 #if defined(CAMERA_FRAMEWORK_EXISTS) && defined(PLAYER_FRAMEWORK_EXISTS)
75 #include "frameworks/bridge/common/dom/dom_camera.h"
76 #endif
77 #include "frameworks/bridge/common/dom/dom_menu.h"
78 #include "frameworks/bridge/common/dom/dom_navigation_menu.h"
79 #include "frameworks/bridge/common/dom/dom_option.h"
80 #include "frameworks/bridge/common/dom/dom_picker_dialog.h"
81 #include "frameworks/bridge/common/dom/dom_piece.h"
82 #include "frameworks/bridge/common/dom/dom_popup.h"
83 #include "frameworks/bridge/common/dom/dom_rating.h"
84 #include "frameworks/bridge/common/dom/dom_select.h"
85 #include "frameworks/bridge/common/dom/dom_tab_bar.h"
86 #include "frameworks/bridge/common/dom/dom_tab_content.h"
87 #include "frameworks/bridge/common/dom/dom_tool_bar.h"
88 #if defined(PLAYER_FRAMEWORK_EXISTS) && defined(VIDEO_SUPPORTED)
89 #include "frameworks/bridge/common/dom/dom_video.h"
90 #endif
91 #if !defined(PREVIEW)
92 #ifdef WEB_SUPPORTED
93 #include "frameworks/bridge/common/dom/dom_web.h"
94 #endif
95 #endif
96 #endif
97
98 namespace OHOS::Ace::Framework {
99 RefPtr<PixelMap> DOMDocument::pixelMap_;
100 int32_t DOMDocument::pixelMapOffsetX_ = 0;
101 int32_t DOMDocument::pixelMapOffsetY_ = 0;
102 namespace {
103
104 // avoid same with root node id
105 constexpr int32_t PROXY_ID = 10000000;
106 const char PROXY_PREFIX[] = "proxy_";
107 const int32_t ROOT_STACK_ID = -1;
108 const char ROOT_STACK_NAME[] = "ComposedStack";
109
110 template<class T>
DOMNodeCreator(NodeId nodeId, const std::string& tag, int32_t)111 RefPtr<DOMNode> DOMNodeCreator(NodeId nodeId, const std::string& tag, int32_t)
112 {
113 return AceType::MakeRefPtr<T>(nodeId, tag);
114 }
115
116 template<class T>
DOMListItemCreator(NodeId nodeId, const std::string& tag, int32_t itemIndex)117 RefPtr<DOMNode> DOMListItemCreator(NodeId nodeId, const std::string& tag, int32_t itemIndex)
118 {
119 return AceType::MakeRefPtr<T>(nodeId, tag, itemIndex);
120 }
121
122 } // namespace
123
~DOMDocument()124 DOMDocument::~DOMDocument()
125 {
126 CHECK_RUN_ON(UI);
127 }
128
CreateNodeWithId(const std::string& tag, NodeId nodeId, int32_t itemIndex)129 RefPtr<DOMNode> DOMDocument::CreateNodeWithId(const std::string& tag, NodeId nodeId, int32_t itemIndex)
130 {
131 static const LinearMapNode<RefPtr<DOMNode> (*)(NodeId, const std::string&, int32_t)> domNodeCreators[] = {
132 { DOM_NODE_TAG_ANIMATE, &DOMNodeCreator<DOMSvgAnimate> },
133 { DOM_NODE_TAG_ANIMATE_MOTION, &DOMNodeCreator<DOMSvgAnimateMotion> },
134 { DOM_NODE_TAG_ANIMATE_TRANSFORM, &DOMNodeCreator<DOMSvgAnimateTransform> },
135 { DOM_NODE_TAG_BADGE, &DOMNodeCreator<DOMBadge> },
136 { DOM_NODE_TAG_BUTTON, &DOMNodeCreator<DOMButton> },
137 { DOM_NODE_TAG_CALENDAR, &DOMNodeCreator<DomCalendar> },
138 #ifndef WEARABLE_PRODUCT
139 #if defined(CAMERA_FRAMEWORK_EXISTS) && defined(PLAYER_FRAMEWORK_EXISTS)
140 { DOM_NODE_TAG_CAMERA, &DOMNodeCreator<DOMCamera> },
141 #endif
142 #endif
143 { DOM_NODE_TAG_CANVAS, &DOMNodeCreator<DOMCanvas> },
144 { DOM_NODE_TAG_CHART, &DOMNodeCreator<DOMChart> },
145 { DOM_NODE_TAG_CIRCLE, &DOMNodeCreator<DOMSvgCircle> },
146 { DOM_NODE_TAG_CLOCK, &DOMNodeCreator<DOMClock> },
147 { DOM_NODE_TAG_DEFS, &DOMNodeCreator<DOMSvgDefs> },
148 { DOM_NODE_TAG_DIALOG, &DOMNodeCreator<DOMDialog> },
149 { DOM_NODE_TAG_DIV, &DOMNodeCreator<DOMDiv> },
150 { DOM_NODE_TAG_DIVIDER, &DOMNodeCreator<DOMDivider> },
151 { DOM_NODE_TAG_ELLIPSE, &DOMNodeCreator<DOMSvgEllipse> },
152 { DOM_NODE_TAG_FE_COLORMATRIX, &DOMNodeCreator<DOMSvgFeColorMatrix> },
153 { DOM_NODE_TAG_FE_COMPOSITE, &DOMNodeCreator<DOMSvgFeComposite> },
154 { DOM_NODE_TAG_FE_GAUSSIANBLUR, &DOMNodeCreator<DOMSvgFeGaussianBlur> },
155 { DOM_NODE_TAG_FE_OFFSET, &DOMNodeCreator<DOMSvgFeOffset> },
156 { DOM_NODE_TAG_FILTER, &DOMNodeCreator<DOMSvgFilter> },
157 { DOM_NODE_TAG_FORM, &DOMNodeCreator<DOMForm> },
158 { DOM_NODE_TAG_G, &DOMNodeCreator<DOMSvgG> },
159 { DOM_NODE_TAG_GRID_COLUMN, &DOMNodeCreator<DomGridColumn> },
160 { DOM_NODE_TAG_GRID_CONTAINER, &DOMNodeCreator<DomGridContainer> },
161 { DOM_NODE_TAG_GRID_ROW, &DOMNodeCreator<DomGridRow> },
162 { DOM_NODE_TAG_IMAGE, &DOMNodeCreator<DOMImage> },
163 { DOM_NODE_TAG_IMAGE_ANIMATOR, &DOMNodeCreator<DOMImageAnimator> },
164 { DOM_NODE_TAG_INPUT, &DOMNodeCreator<DOMInput> },
165 { DOM_NODE_TAG_LABEL, &DOMNodeCreator<DOMLabel> },
166 { DOM_NODE_TAG_LINE, &DOMNodeCreator<DOMSvgLine> },
167 { DOM_NODE_TAG_LIST, &DOMNodeCreator<DOMList> },
168 { DOM_NODE_TAG_LIST_ITEM, &DOMListItemCreator<DOMListItem> },
169 { DOM_NODE_TAG_LIST_ITEM_GROUP, &DOMListItemCreator<DOMListItemGroup> },
170 { DOM_NODE_TAG_MARQUEE, &DOMNodeCreator<DOMMarquee> },
171 { DOM_NODE_TAG_MASK, &DOMNodeCreator<DOMSvgMask> },
172 #ifndef WEARABLE_PRODUCT
173 { DOM_NODE_TAG_MENU, &DOMNodeCreator<DOMMenu> },
174 #endif
175 { DOM_NODE_TAG_NAVIGATION_BAR, &DOMNodeCreator<DomNavigationBar> },
176 #ifndef WEARABLE_PRODUCT
177 { DOM_NODE_TAG_NAVIGATION_MENU, &DOMNodeCreator<DOMNavigationMenu> },
178 { DOM_NODE_TAG_OPTION, &DOMNodeCreator<DOMOption> },
179 { DOM_NODE_TAG_PANEL, &DOMNodeCreator<DOMPanel> },
180 #endif
181 { DOM_NODE_TAG_PATH, &DOMNodeCreator<DOMSvgPath> },
182 #ifndef WEARABLE_PRODUCT
183 { DOM_NODE_TAG_PICKER_DIALOG, &DOMNodeCreator<DOMPickerDialog> },
184 #endif
185 { DOM_NODE_TAG_PICKER_VIEW, &DOMNodeCreator<DOMPickerView> },
186 { DOM_NODE_TAG_POLYGON, &DOMNodeCreator<DOMSvgPolygon> },
187 { DOM_NODE_TAG_POLYLINE, &DOMNodeCreator<DOMSvgPolyline> },
188 #ifndef WEARABLE_PRODUCT
189 { DOM_NODE_TAG_POPUP, &DOMNodeCreator<DOMPopup> },
190 #endif
191 { DOM_NODE_TAG_PROGRESS, &DOMNodeCreator<DOMProgress> },
192 { DOM_NODE_TAG_QRCODE, &DOMNodeCreator<DOMQrcode> },
193 #ifndef WEARABLE_PRODUCT
194 { DOM_NODE_TAG_RATING, &DOMNodeCreator<DOMRating> },
195 #endif
196 { DOM_NODE_TAG_RECT, &DOMNodeCreator<DOMSvgRect> },
197 { DOM_NODE_TAG_REFRESH, &DOMNodeCreator<DOMRefresh> },
198 #ifdef WEB_SUPPORTED
199 { DOM_NODE_TAG_RICH_TEXT, &DOMNodeCreator<DOMRichText> },
200 #endif
201 { DOM_NODE_TAG_SEARCH, &DOMNodeCreator<DOMSearch> },
202 #ifndef WEARABLE_PRODUCT
203 { DOM_NODE_TAG_SELECT, &DOMNodeCreator<DOMSelect> },
204 #endif
205 { DOM_NODE_TAG_SLIDER, &DOMNodeCreator<DOMSlider> },
206 { DOM_NODE_TAG_SPAN, &DOMNodeCreator<DOMSpan> },
207 { DOM_NODE_TAG_STACK, &DOMNodeCreator<DOMStack> },
208 #ifndef WEARABLE_PRODUCT
209 { DOM_NODE_TAG_STEPPER, &DOMNodeCreator<DOMStepper> },
210 { DOM_NODE_TAG_STEPPER_ITEM, &DOMListItemCreator<DOMStepperItem> },
211 #endif
212 { DOM_NODE_TAG_SVG, &DOMNodeCreator<DOMSvg> },
213 { DOM_NODE_TAG_SVG_TEXT, &DOMNodeCreator<DOMSvgText> },
214 { DOM_NODE_TAG_SWIPER, &DOMNodeCreator<DOMSwiper> },
215 { DOM_NODE_TAG_SWITCH, &DOMNodeCreator<DOMSwitch> },
216 #ifndef WEARABLE_PRODUCT
217 { DOM_NODE_TAG_TAB_BAR, &DOMNodeCreator<DOMTabBar> },
218 { DOM_NODE_TAG_TAB_CONTENT, &DOMNodeCreator<DOMTabContent> },
219 { DOM_NODE_TAG_TABS, &DOMNodeCreator<DOMTabs> },
220 #endif
221 { DOM_NODE_TAG_TEXT, &DOMNodeCreator<DOMText> },
222 { DOM_NODE_TAG_TEXTAREA, &DOMNodeCreator<DOMTextarea> },
223 { DOM_NODE_TAG_TEXT_PATH, &DOMNodeCreator<DOMSvgTextPath> },
224 { DOM_NODE_TAG_TOGGLE, &DOMNodeCreator<DOMToggle> },
225 #ifndef WEARABLE_PRODUCT
226 { DOM_NODE_TAG_TOOL_BAR, &DOMNodeCreator<DOMToolBar> },
227 { DOM_NODE_TAG_TOOL_BAR_ITEM, &DOMNodeCreator<DOMToolBarItem> },
228 #endif
229 { DOM_NODE_TAG_TSPAN, &DOMNodeCreator<DOMSvgTspan> },
230 { DOM_NODE_TAG_USE, &DOMNodeCreator<DOMSvgUse> },
231 #ifndef WEARABLE_PRODUCT
232 #if defined(PLAYER_FRAMEWORK_EXISTS) && defined(VIDEO_SUPPORTED)
233 { DOM_NODE_TAG_VIDEO, &DOMNodeCreator<DOMVideo> },
234 #endif
235 #ifdef WEB_SUPPORTED
236 { DOM_NODE_TAG_WEB, &DOMNodeCreator<DOMWeb> },
237 #endif
238 #endif
239 #ifdef XCOMPONENT_SUPPORTED
240 { DOM_NODE_TAG_XCOMPONENT, &DOMNodeCreator<DOMXComponent> },
241 #endif
242 };
243 #ifndef WEARABLE_PRODUCT
244 static const LinearMapNode<RefPtr<DOMNode> (*)(NodeId, const std::string&, int32_t)> phoneNodeCreators[] = {
245 { DOM_NODE_TAG_PIECE, &DOMNodeCreator<DOMPiece> },
246 };
247 #endif
248
249 RefPtr<DOMNode> domNode;
250 int64_t creatorIndex = BinarySearchFindIndex(domNodeCreators, ArraySize(domNodeCreators), tag.c_str());
251 if (creatorIndex >= 0) {
252 domNode = domNodeCreators[creatorIndex].value(nodeId, tag, itemIndex);
253 #ifndef WEARABLE_PRODUCT
254 } else {
255 if (SystemProperties::GetDeviceType() == DeviceType::PHONE ||
256 SystemProperties::GetDeviceType() == DeviceType::TABLET ||
257 SystemProperties::GetDeviceType() == DeviceType::TWO_IN_ONE) {
258 creatorIndex = BinarySearchFindIndex(phoneNodeCreators, ArraySize(phoneNodeCreators), tag.c_str());
259 if (creatorIndex >= 0) {
260 domNode = phoneNodeCreators[creatorIndex].value(nodeId, tag, itemIndex);
261 }
262 } else {
263 return nullptr;
264 }
265 #endif
266 }
267 if (!domNode) {
268 #if defined(PREVIEW)
269 if (std::strcmp(tag.c_str(), DOM_NODE_TAG_WEB) == 0 || std::strcmp(tag.c_str(), DOM_NODE_TAG_XCOMPONENT) == 0 ||
270 std::strcmp(tag.c_str(), DOM_NODE_TAG_RICH_TEXT) == 0) {
271 LOGW("[Engine Log] Unable to use the %{public}s component in the Previewer. Perform this operation on the "
272 "emulator or a real device instead.",
273 tag.c_str());
274 }
275 #endif
276 return nullptr;
277 }
278
279 auto result = domNodes_.try_emplace(nodeId, domNode);
280 if (!result.second) {
281 return nullptr;
282 }
283 domNode->SetIsRootNode(nodeId == rootNodeId_);
284 domNode->SetPageId(rootNodeId_ - DOM_ROOT_NODE_ID_BASE);
285 return domNode;
286 }
287
CreateProxyNodeWithId(const std::string& tag, NodeId nodeId)288 RefPtr<DOMProxy> DOMDocument::CreateProxyNodeWithId(const std::string& tag, NodeId nodeId)
289 {
290 // generate proxy tag and id, proxy id marked different from root tag id
291 std::string proxyTag = std::string(PROXY_PREFIX) + tag;
292 NodeId proxyId = PROXY_ID + nodeId;
293 auto proxy = AceType::MakeRefPtr<DOMProxy>(proxyId, proxyTag);
294 auto result = domNodes_.try_emplace(proxyId, proxy);
295 if (!result.second) {
296 return nullptr;
297 }
298 proxyRelatedNode_.emplace(nodeId);
299 return proxy;
300 }
301
GetDOMNodeById(NodeId nodeId) const302 RefPtr<DOMNode> DOMDocument::GetDOMNodeById(NodeId nodeId) const
303 {
304 const auto itNode = domNodes_.find(nodeId);
305 if (itNode == domNodes_.end()) {
306 LOGI("the node is not in the map");
307 return nullptr;
308 }
309 return itNode->second;
310 }
311
RemoveNodes(const RefPtr<DOMNode>& node, bool scheduleUpdate)312 void DOMDocument::RemoveNodes(const RefPtr<DOMNode>& node, bool scheduleUpdate)
313 {
314 if (!node) {
315 return;
316 }
317 auto children = node->GetChildList();
318 for (auto it = children.begin(); it != children.end();) {
319 RemoveNodes(*it++, scheduleUpdate);
320 }
321 auto parentId = node->GetParentId();
322 RefPtr<DOMNode> parentNode;
323 if (parentId != -1) {
324 parentNode = GetDOMNodeById(parentId);
325 if (parentNode) {
326 parentNode->RemoveNode(node);
327 }
328 }
329 // Fixed positioned node and navigation bar node need to delete the relative proxy node.
330 if (node->GetPosition() == PositionType::PTFIXED && rootStackComponent_) {
331 rootStackComponent_->RemoveChild(node->GetRootComponent());
332 auto context = node->GetPipelineContext().Upgrade();
333 if (context && scheduleUpdate) {
334 context->ScheduleUpdate(rootComposedStack_);
335 }
336 auto proxyId = node->GetNodeId() + PROXY_ID;
337 auto proxy = GetDOMNodeById(proxyId);
338 if (proxy) {
339 if (parentNode) {
340 parentNode->RemoveNode(proxy);
341 }
342 domNodes_.erase(proxyId);
343 proxyRelatedNode_.erase(node->GetNodeId());
344 }
345 }
346 if (node->GetTag() == DOM_NODE_TAG_NAVIGATION_BAR && rootStackComponent_ &&
347 rootStackComponent_->HasNavigationBar()) {
348 auto rootColumn = AceType::DynamicCast<ColumnComponent>(rootStackComponent_->GetChildren().front());
349 if (rootColumn) {
350 rootColumn->RemoveChild(node->GetRootComponent());
351 auto proxyId = node->GetNodeId() + PROXY_ID;
352 auto proxy = GetDOMNodeById(proxyId);
353 if (proxy) {
354 if (parentNode) {
355 parentNode->RemoveNode(proxy);
356 }
357 domNodes_.erase(proxyId);
358 proxyRelatedNode_.erase(node->GetNodeId());
359 }
360 }
361 }
362 domNodes_.erase(node->GetNodeId());
363 }
364
AddNodeWithId(const std::string& key, const RefPtr<DOMNode>& domNode)365 void DOMDocument::AddNodeWithId(const std::string& key, const RefPtr<DOMNode>& domNode)
366 {
367 nodeWithIdVec_.emplace_back(key, domNode);
368 }
369
AddNodeWithTarget(const std::string& key, const RefPtr<DOMNode>& domNode)370 void DOMDocument::AddNodeWithTarget(const std::string& key, const RefPtr<DOMNode>& domNode)
371 {
372 // Always save only one (the last) 'target' dom node
373 for (auto iter = nodeWithTargetVec_.begin(); iter != nodeWithTargetVec_.end();) {
374 if (iter->first == key) {
375 iter = nodeWithTargetVec_.erase(iter);
376 } else {
377 ++iter;
378 }
379 }
380 nodeWithTargetVec_.emplace_back(key, domNode);
381 }
382
HandleComponentPostBinding()383 void DOMDocument::HandleComponentPostBinding()
384 {
385 for (auto iterTarget = nodeWithTargetVec_.begin(); iterTarget != nodeWithTargetVec_.end();) {
386 auto targetNode = iterTarget->second.Upgrade();
387 if (!targetNode) {
388 LOGW("DOM Node with target %{public}s has been invalid", iterTarget->first.c_str());
389 iterTarget = nodeWithTargetVec_.erase(iterTarget);
390 continue;
391 }
392
393 for (auto iterId = nodeWithIdVec_.begin(); iterId != nodeWithIdVec_.end();) {
394 auto idNode = iterId->second.Upgrade();
395 if (!idNode) {
396 LOGW("DOM Node with id %{public}s has been invalid, add targetNode fail", iterId->first.c_str());
397 iterId = nodeWithIdVec_.erase(iterId);
398 continue;
399 }
400
401 if (iterTarget->first != iterId->first) {
402 ++iterId;
403 continue;
404 }
405
406 auto component = targetNode->GetSpecializedComponent();
407 if (AceType::InstanceOf<TouchListenerComponent>(component)) {
408 auto labelNode = AceType::DynamicCast<DOMLabel>(targetNode);
409 if (labelNode) {
410 labelNode->SetTargetNode(idNode);
411 }
412 #ifndef WEARABLE_PRODUCT
413 } else if (AceType::InstanceOf<PopupComponent>(component)) {
414 auto popupNode = AceType::DynamicCast<DOMPopup>(targetNode);
415 if (popupNode) {
416 // DOMPopup bind node with ID node
417 popupNode->BindIdNode(idNode);
418 }
419 } else if (AceType::InstanceOf<MenuComponent>(component)) {
420 auto menuNode = AceType::DynamicCast<DOMMenu>(targetNode);
421 if (menuNode) {
422 // DOMMenu bind node with ID node
423 menuNode->BindIdNode(idNode);
424 }
425 } else if (AceType::InstanceOf<DOMTabBar>(targetNode)) {
426 auto tabBarNode = AceType::DynamicCast<DOMTabBar>(targetNode);
427 // DOMTabBar in navigation bar bind tabs with ID node
428 tabBarNode->BindToTabs(idNode);
429 #endif
430 }
431 ++iterId;
432 }
433 ++iterTarget;
434 }
435 }
436
HandlePageLoadFinish()437 void DOMDocument::HandlePageLoadFinish()
438 {
439 for (auto iter : domNodes_) {
440 if (iter.second) {
441 iter.second->OnPageLoadFinish();
442 }
443 }
444 }
445
SetUpRootComponent(const RefPtr<DOMNode>& node)446 void DOMDocument::SetUpRootComponent(const RefPtr<DOMNode>& node)
447 {
448 if (!node) {
449 EventReport::SendComponentException(ComponentExcepType::SET_ROOT_DOM_NODE_ERR);
450 return;
451 }
452 std::list<RefPtr<Component>> stackChildren { node->GetRootComponent() };
453 rootStackComponent_ = AceType::MakeRefPtr<StackComponent>(
454 Alignment::TOP_LEFT, StackFit::INHERIT, Overflow::OBSERVABLE, stackChildren);
455 auto context = pipelineContext_.Upgrade();
456 if (context && !context->IsFullScreenModal()) {
457 rootStackComponent_->SetMainStackSize(MainStackSize::MIN);
458 rootStackComponent_->SetStackFit(StackFit::FIRST_CHILD);
459 } else {
460 rootStackComponent_->SetMainStackSize(MainStackSize::MAX);
461 }
462 rootComposedStack_ =
463 AceType::MakeRefPtr<ComposedComponent>(std::to_string(ROOT_STACK_ID - rootNodeId_), ROOT_STACK_NAME);
464 rootComposedStack_->SetChild(rootStackComponent_);
465 }
466
467 } // namespace OHOS::Ace::Framework
468