1 /*
2  * Copyright (c) 2021 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_dialog.h"
17 
18 #include "base/log/event_report.h"
19 #include "frameworks/bridge/common/utils/utils.h"
20 
21 namespace OHOS::Ace::Framework {
22 
DOMDialog(NodeId nodeId,const std::string & nodeName)23 DOMDialog::DOMDialog(NodeId nodeId, const std::string& nodeName) : DOMNode(nodeId, nodeName)
24 {
25     dialogChild_ = AceType::MakeRefPtr<CustomDialogComponent>(std::to_string(nodeId), nodeName);
26 }
27 
PrepareSpecializedComponent()28 void DOMDialog::PrepareSpecializedComponent()
29 {
30     dialogChild_->SetTextDirection(IsRightToLeft() ? TextDirection::RTL : TextDirection::LTR);
31     if (dialogWidth_.second) {
32         dialogChild_->SetWidth(dialogWidth_.first);
33     }
34     if (dialogHeight_.second) {
35         dialogChild_->SetHeight(dialogHeight_.first);
36     }
37     dialogChild_->SetIsDragable(dragable_);
38     if (display_) {
39         display_->SetVisible(isShow_ ? VisibleType::VISIBLE : VisibleType::GONE);
40     }
41 
42     if (customizedMargin_) {
43         auto margin = Edge(marginLeft_, marginTop_, marginRight_, marginBottom_);
44         dialogChild_->SetMargin(margin);
45     }
46 }
47 
SetSpecializedStyle(const std::pair<std::string,std::string> & style)48 bool DOMDialog::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
49 {
50     static const LinearMapNode<void (*)(const std::string&, DOMDialog&)> styleOperators[] = {
51         { DOM_HEIGHT,
52             [](const std::string& val, DOMDialog& dialog) {
53                 dialog.dialogHeight_.first = dialog.ParseDimension(val);
54                 dialog.dialogHeight_.second = true;
55             } },
56         { DOM_MARGIN_BOTTOM,
57             [](const std::string& val, DOMDialog& dialog) {
58                 dialog.marginBottom_ = dialog.ParseDimension(val);
59                 dialog.customizedMargin_ = true;
60             } },
61         { DOM_MARGIN_END,
62             [](const std::string& val, DOMDialog& dialog) {
63                 if (dialog.IsRightToLeft()) {
64                     dialog.marginLeft_ = dialog.ParseDimension(val);
65                 } else {
66                     dialog.marginRight_ = dialog.ParseDimension(val);
67                 }
68                 dialog.customizedMargin_ = true;
69             } },
70         { DOM_MARGIN_LEFT,
71             [](const std::string& val, DOMDialog& dialog) {
72                 dialog.marginLeft_ = dialog.ParseDimension(val);
73                 dialog.customizedMargin_ = true;
74             } },
75         { DOM_MARGIN_RIGHT,
76             [](const std::string& val, DOMDialog& dialog) {
77                 dialog.marginRight_ = dialog.ParseDimension(val);
78                 dialog.customizedMargin_ = true;
79             } },
80         { DOM_MARGIN_START,
81             [](const std::string& val, DOMDialog& dialog) {
82                 if (dialog.IsRightToLeft()) {
83                     dialog.marginRight_ = dialog.ParseDimension(val);
84                 } else {
85                     dialog.marginLeft_ = dialog.ParseDimension(val);
86                 }
87                 dialog.customizedMargin_ = true;
88             } },
89         { DOM_MARGIN_TOP,
90             [](const std::string& val, DOMDialog& dialog) {
91                 dialog.marginTop_ = dialog.ParseDimension(val);
92                 dialog.customizedMargin_ = true;
93             } },
94         { DOM_WIDTH,
95             [](const std::string& val, DOMDialog& dialog) {
96                 dialog.dialogWidth_.first = dialog.ParseDimension(val);
97                 dialog.dialogWidth_.second = true;
98             } },
99     };
100     auto operatorIter = BinarySearchFindIndex(styleOperators, ArraySize(styleOperators), style.first.c_str());
101     if (operatorIter != -1) {
102         styleOperators[operatorIter].value(style.second, *this);
103         return true;
104     }
105     return false;
106 }
107 
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)108 bool DOMDialog::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
109 {
110     if (attr.first == DOM_SHOW) {
111         isShow_ = StringToBool(attr.second);
112         return true;
113     } else if (attr.first == DOM_DIALOG_STYLE_DRAGABLE) {
114         dragable_ = StringToBool(attr.second);
115         return true;
116     }
117     return false;
118 }
119 
CallSpecializedMethod(const std::string & method,const std::string & args)120 void DOMDialog::CallSpecializedMethod(const std::string& method, const std::string& args)
121 {
122     if (method == DOM_DIALOG_METHOD_SHOW) {
123         const auto& controller = dialogChild_->GetDialogController();
124         if (!controller) {
125             return;
126         }
127         controller->ShowDialog();
128     } else if (method == DOM_DIALOG_METHOD_CLOSE) {
129         const auto& controller = dialogChild_->GetDialogController();
130         if (!controller) {
131             return;
132         }
133         controller->CloseDialog();
134     } else {
135         LOGW("no such method available.");
136     }
137 }
138 
OnChildNodeAdded(const RefPtr<DOMNode> & child,int32_t slot)139 void DOMDialog::OnChildNodeAdded(const RefPtr<DOMNode>& child, int32_t slot)
140 {
141     if (!display_) {
142         display_ = AceType::MakeRefPtr<DisplayComponent>(child->GetRootComponent());
143     }
144     display_->SetVisible(isShow_ ? VisibleType::VISIBLE : VisibleType::GONE);
145     dialogChild_->SetChild(display_);
146 }
147 
OnChildNodeRemoved(const RefPtr<DOMNode> & child)148 void DOMDialog::OnChildNodeRemoved(const RefPtr<DOMNode>& child)
149 {
150     dialogChild_->SetChild(nullptr);
151 }
152 
AddSpecializedEvent(int32_t pageId,const std::string & event)153 bool DOMDialog::AddSpecializedEvent(int32_t pageId, const std::string& event)
154 {
155     if (event == DOM_DIALOG_EVENT_CANCEL) {
156         dialogChild_->SetOnCancel(EventMarker(GetNodeIdForEvent(), event, pageId));
157         return true;
158     } else if (event == DOM_DIALOG_METHOD_SHOW) {
159         dialogChild_->SetOnShow(EventMarker(GetNodeIdForEvent(), event, pageId));
160         return true;
161     } else if (event == DOM_DIALOG_METHOD_CLOSE) {
162         dialogChild_->SetOnClose(EventMarker(GetNodeIdForEvent(), event, pageId));
163         return true;
164     }
165 
166     LOGE("unsupported event: %{public}s.", event.c_str());
167     EventReport::SendComponentException(ComponentExcepType::DIALOG_EVENT_ERR);
168     return false;
169 }
170 
CompositeSpecializedComponent(const std::vector<RefPtr<SingleChild>> & components)171 RefPtr<Component> DOMDialog::CompositeSpecializedComponent(const std::vector<RefPtr<SingleChild>>& components)
172 {
173     auto box = AceType::MakeRefPtr<BoxComponent>();
174     box->SetChild(dialogChild_);
175     return box;
176 }
177 
178 } // namespace OHOS::Ace::Framework
179