• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/card_frontend/js_card_parser.h"
17 
18 #include <array>
19 
20 #include "base/i18n/localization.h"
21 #include "base/resource/ace_res_config.h"
22 #include "base/utils/utils.h"
23 #include "core/common/ace_application_info.h"
24 #include "frameworks/base/log/event_report.h"
25 #include "frameworks/bridge/common/utils/utils.h"
26 
27 namespace OHOS::Ace::Framework {
28 namespace {
29 
30 const char I18N_FOLDER[] = "i18n/";
31 const char FILE_TYPE_JSON[] = ".json";
32 const char RESOURCES_FOLDER[] = "resources/";
33 const char DEFAULTS_RESOURCES_JSON_FILE[] = "res-defaults.json";
34 const char BLOCK_VALUE[] = "blockValue";
35 
36 const std::string REPEAT_INDEX = "$idx";
37 const std::string REPEAT_ITEM = "$item";
38 const std::string TRUE = "true";
39 const std::string FALSE = "false";
40 
41 class VersionData {
42 public:
AddRecord(const std::string & key,const std::string & value)43     void AddRecord(const std::string& key, const std::string& value)
44     {
45         records_.emplace_back(StringUtils::StringToInt(key), value);
46     }
47 
GetVersionPatch()48     std::vector<std::string> GetVersionPatch()
49     {
50         std::vector<std::string> result;
51         int32_t sysApiVersion = StringUtils::StringToInt(SystemProperties::GetApiVersion());
52         if (sysApiVersion <= 0) {
53             LOGE("get system api version failed!");
54             return result;
55         }
56         std::sort(records_.begin(), records_.end(),
57             [](const std::pair<uint32_t, std::string>& recordA, const std::pair<uint32_t, std::string>& recordB) {
58                 return recordA.first > recordB.first;
59             });
60         for (const auto& record : records_) {
61             if (record.first <= sysApiVersion) {
62                 result.emplace_back(record.second);
63             }
64         }
65         // prepare patches in order of api version from smallest to largest.
66         std::reverse(result.begin(), result.end());
67         return result;
68     }
69 
70 private:
71     std::vector<std::pair<int32_t, std::string>> records_;
72 };
73 
GetJsonValue(const std::vector<std::string> & keys,const std::unique_ptr<JsonValue> & fileData)74 std::unique_ptr<JsonValue> GetJsonValue(
75     const std::vector<std::string>& keys, const std::unique_ptr<JsonValue>& fileData)
76 {
77     auto it = keys.begin();
78     CHECK_NULL_RETURN_NOLOG(fileData, nullptr);
79     if (!fileData->IsValid() || !fileData->Contains(*it)) {
80         return nullptr;
81     }
82     auto data = fileData->GetValue(*it);
83     for (++it; it != keys.end(); ++it) {
84         if (data->IsValid() && data->Contains(*it)) {
85             data = data->GetValue(*it);
86         } else {
87             return nullptr;
88         }
89     }
90 
91     return data;
92 }
93 
GetDeviceDpi(double dpi)94 std::string GetDeviceDpi(double dpi)
95 {
96     static const LinearMapNode<bool (*)(double)> dpiMap[] = {
97         { "ldpi", [](double dpi) { return GreatNotEqual(dpi, 0.0) && LessNotEqual(dpi, 0.875); } },
98         { "mdpi", [](double dpi) { return GreatOrEqual(dpi, 0.875) && LessNotEqual(dpi, 1.25); } },
99         { "hdpi", [](double dpi) { return GreatOrEqual(dpi, 1.25) && LessNotEqual(dpi, 1.75); } },
100         { "xhdpi", [](double dpi) { return GreatOrEqual(dpi, 1.75) && LessNotEqual(dpi, 2.5); } },
101         { "xxhdpi", [](double dpi) { return GreatOrEqual(dpi, 2.5) && LessNotEqual(dpi, 3.5); } },
102         { "xxxhdpi", [](double dpi) { return GreatOrEqual(dpi, 3.5); } },
103     };
104     for (const auto& idx : dpiMap) {
105         if (idx.value(dpi)) {
106             return idx.key;
107         }
108     }
109     return "mdpi";
110 }
111 
GetAttrOptionsSeriesPoint(const std::unique_ptr<JsonValue> & jsonPoint,PointInfo & pointInfo)112 void GetAttrOptionsSeriesPoint(const std::unique_ptr<JsonValue>& jsonPoint, PointInfo& pointInfo)
113 {
114     CHECK_NULL_VOID_NOLOG(jsonPoint);
115     if (!jsonPoint->IsValid() || !jsonPoint->IsObject()) {
116         return;
117     }
118 
119     pointInfo.SetDisplay(true);
120     auto child = jsonPoint->GetChild();
121     while (child && child->IsValid()) {
122         static const LinearMapNode<void (*)(std::unique_ptr<JsonValue>&, PointInfo&)> chartOptionsPointMap[] = {
123             { "display",
124                 [](std::unique_ptr<JsonValue>& child, PointInfo& pointInfo) {
125                     if (child->IsBool()) {
126                         pointInfo.SetDisplay(child->GetBool());
127                     }
128                 } },
129             { "fillColor",
130                 [](std::unique_ptr<JsonValue>& child, PointInfo& pointInfo) {
131                     const auto& valStr = child->GetString();
132                     pointInfo.SetFillColorString(valStr);
133                 } },
134             { "shape",
135                 [](std::unique_ptr<JsonValue>& child, PointInfo& pointInfo) {
136                     const auto& valStr = child->GetString();
137                     PointShape shape = (valStr == "circle")
138                                            ? PointShape::CIRCLE
139                                            : (valStr == "square") ? PointShape::SQUARE : PointShape::TRIANGLE;
140                     pointInfo.SetPointShape(shape);
141                 } },
142             { "size",
143                 [](std::unique_ptr<JsonValue>& child, PointInfo& pointInfo) {
144                     auto valStr = child->IsString() ? child->GetString() : child->ToString();
145                     pointInfo.SetPointSize(StringToDimension(valStr));
146                 } },
147             { "strokeColor",
148                 [](std::unique_ptr<JsonValue>& child, PointInfo& pointInfo) {
149                     auto valStr = child->GetString();
150                     pointInfo.SetStrokeColorString(valStr);
151                 } },
152             { "strokeWidth",
153                 [](std::unique_ptr<JsonValue>& child, PointInfo& pointInfo) {
154                     auto valStr = child->IsString() ? child->GetString() : child->ToString();
155                     pointInfo.SetPointStrokeWidth(StringToDimension(valStr));
156                 } },
157         };
158         auto key = child->GetKey();
159         auto iter = BinarySearchFindIndex(chartOptionsPointMap, ArraySize(chartOptionsPointMap), key.c_str());
160         if (iter != -1) {
161             chartOptionsPointMap[iter].value(child, pointInfo);
162         } else {
163             LOGD("key : %{public}s unsupported. Ignoring!", key.c_str());
164         }
165         child = child->GetNext();
166     }
167 }
168 
GetChartAttrOptionsSeriesLineStyle(const std::unique_ptr<JsonValue> & jsonLineStyle,ChartOptions & options)169 void GetChartAttrOptionsSeriesLineStyle(const std::unique_ptr<JsonValue>& jsonLineStyle, ChartOptions& options)
170 {
171     CHECK_NULL_VOID_NOLOG(jsonLineStyle);
172     if (!jsonLineStyle->IsValid() || !jsonLineStyle->IsObject()) {
173         return;
174     }
175 
176     auto child = jsonLineStyle->GetChild();
177     while (child && child->IsValid()) {
178         auto key = child->GetKey();
179         if (key == "smooth" && child->IsBool()) {
180             options.SetSmoothFlag(child->GetBool());
181         } else if (key == "width") {
182             auto valStr = child->IsString() ? child->GetString() : child->ToString();
183             options.SetLineWidth(StringToDouble(valStr));
184         }
185         child = child->GetNext();
186     }
187 }
188 
GetChartAttrOptionsSeries(const std::unique_ptr<JsonValue> & jsonSeries,ChartOptions & options)189 void GetChartAttrOptionsSeries(const std::unique_ptr<JsonValue>& jsonSeries, ChartOptions& options)
190 {
191     CHECK_NULL_VOID_NOLOG(jsonSeries);
192     if (!jsonSeries->IsValid()) {
193         return;
194     }
195     auto child = jsonSeries->GetChild();
196     while (child && child->IsValid()) {
197         if (child->IsObject()) {
198             static const LinearMapNode<void (*)(const std::unique_ptr<JsonValue>&, ChartOptions&)>
199                 chartOptionsSeriesMap[] = {
200                     { "bottomPoint",
201                         [](const std::unique_ptr<JsonValue>& jsonVal, ChartOptions& chartOptions) {
202                             PointInfo pointInfo;
203                             GetAttrOptionsSeriesPoint(jsonVal, pointInfo);
204                             chartOptions.SetBottomPoint(pointInfo);
205                         } },
206                     { "headPoint",
207                         [](const std::unique_ptr<JsonValue>& jsonVal, ChartOptions& chartOptions) {
208                             PointInfo pointInfo;
209                             GetAttrOptionsSeriesPoint(jsonVal, pointInfo);
210                             chartOptions.SetHeadPoint(pointInfo);
211                         } },
212                     { "lineStyle",
213                         [](const std::unique_ptr<JsonValue>& jsonVal, ChartOptions& chartOptions) {
214                             GetChartAttrOptionsSeriesLineStyle(jsonVal, chartOptions);
215                         } },
216                     { "topPoint",
217                         [](const std::unique_ptr<JsonValue>& jsonVal, ChartOptions& chartOptions) {
218                             PointInfo pointInfo;
219                             GetAttrOptionsSeriesPoint(jsonVal, pointInfo);
220                             chartOptions.SetTopPoint(pointInfo);
221                         } },
222                 };
223             auto key = child->GetKey();
224             auto iter = BinarySearchFindIndex(chartOptionsSeriesMap, ArraySize(chartOptionsSeriesMap), key.c_str());
225             if (iter != -1) {
226                 chartOptionsSeriesMap[iter].value(child, options);
227             } else {
228                 LOGD("key : %{public}s unsupported. Ignoring!", key.c_str());
229             }
230         }
231         child = child->GetNext();
232     }
233 }
234 
GetAttrOptionsAxis(const std::unique_ptr<JsonValue> & jsonAxis,AxisOption & axisOption)235 void GetAttrOptionsAxis(const std::unique_ptr<JsonValue>& jsonAxis, AxisOption& axisOption)
236 {
237     CHECK_NULL_VOID(jsonAxis);
238     if (!jsonAxis->IsValid() || !jsonAxis->IsObject()) {
239         return;
240     }
241 
242     auto child = jsonAxis->GetChild();
243     while (child && child->IsValid()) {
244         static const LinearMapNode<void (*)(const std::unique_ptr<JsonValue>&, AxisOption&)> chartOptionsAxisMap[] = {
245             { "axisTick",
246                 [](const std::unique_ptr<JsonValue>& jsonAxis, AxisOption& axis) {
247                     if (jsonAxis->IsNumber()) {
248                         axis.tickNumber = jsonAxis->GetInt();
249                     }
250                 } },
251             { "color",
252                 [](const std::unique_ptr<JsonValue>& jsonAxis, AxisOption& axis) {
253                     const auto& valStr = jsonAxis->GetString();
254                     axis.color = Color::FromString(valStr);
255                 } },
256             { "display",
257                 [](const std::unique_ptr<JsonValue>& jsonAxis, AxisOption& axis) {
258                     if (jsonAxis->IsBool()) {
259                         axis.display = jsonAxis->GetBool();
260                     }
261                 } },
262             { "max",
263                 [](const std::unique_ptr<JsonValue>& jsonAxis, AxisOption& axis) {
264                     if (jsonAxis->IsNumber()) {
265                         axis.max = jsonAxis->GetDouble();
266                     }
267                 } },
268             { "min",
269                 [](const std::unique_ptr<JsonValue>& jsonAxis, AxisOption& axis) {
270                     if (jsonAxis->IsNumber()) {
271                         axis.min = jsonAxis->GetDouble();
272                     }
273                 } },
274         };
275         auto key = child->GetKey();
276         auto iter = BinarySearchFindIndex(chartOptionsAxisMap, ArraySize(chartOptionsAxisMap), key.c_str());
277         if (iter != -1) {
278             chartOptionsAxisMap[iter].value(child, axisOption);
279         } else {
280             LOGD("key : %{public}s unsupported. Ignoring!", key.c_str());
281         }
282         child = child->GetNext();
283     }
284 }
285 
GetAttrOptions(const std::unique_ptr<JsonValue> & jsonOption,ChartOptions & options)286 void GetAttrOptions(const std::unique_ptr<JsonValue>& jsonOption, ChartOptions& options)
287 {
288     CHECK_NULL_VOID_NOLOG(jsonOption);
289     if (!jsonOption->IsValid() || !jsonOption->IsObject()) {
290         return;
291     }
292     auto child = jsonOption->GetChild();
293     while (child && child->IsValid()) {
294         static const LinearMapNode<void (*)(const std::unique_ptr<JsonValue>&, ChartOptions&)> chartOptionsMap[] = {
295             { "series", [](const std::unique_ptr<JsonValue>& jsonSeries,
296                             ChartOptions& chartOptions) { GetChartAttrOptionsSeries(jsonSeries, chartOptions); } },
297             { "xAxis",
298                 [](const std::unique_ptr<JsonValue>& jsonOption, ChartOptions& chartOptions) {
299                     AxisOption xAxis;
300                     GetAttrOptionsAxis(jsonOption, xAxis);
301                     chartOptions.SetXAxis(xAxis);
302                 } },
303             { "yAxis",
304                 [](const std::unique_ptr<JsonValue>& jsonOption, ChartOptions& chartOptions) {
305                     AxisOption yAxis;
306                     GetAttrOptionsAxis(jsonOption, yAxis);
307                     chartOptions.SetYAxis(yAxis);
308                 } },
309         };
310         auto key = child->GetKey();
311         auto iter = BinarySearchFindIndex(chartOptionsMap, ArraySize(chartOptionsMap), key.c_str());
312         if (iter != -1) {
313             chartOptionsMap[iter].value(child, options);
314         } else {
315             LOGD("key : %{public}s unsupported. Ignoring!", key.c_str());
316         }
317         child = child->GetNext();
318     }
319 }
320 
ParseLineDash(const std::string & val,SegmentInfo & segmentInfo)321 void ParseLineDash(const std::string& val, SegmentInfo& segmentInfo)
322 {
323     std::vector<std::string> dash;
324     StringUtils::StringSplitter(val, ',', dash);
325     if (!dash.empty()) {
326         segmentInfo.SetLineType(dash[0] == "dashed" ? LineType::DASHED : LineType::SOLID);
327     }
328     if (dash.size() > 1) {
329         segmentInfo.SetSolidWidth(Framework::StringToDouble(dash[1]));
330     }
331     if (dash.size() > 2) {
332         segmentInfo.SetSpaceWidth(Framework::StringToDouble(dash[2]));
333     }
334 }
335 
ParseTextPlacement(const std::string & val,TextInfo & textInfo)336 void ParseTextPlacement(const std::string& val, TextInfo& textInfo)
337 {
338     if (val == "top") {
339         textInfo.SetPlacement(Placement::TOP);
340     } else if (val == "bottom") {
341         textInfo.SetPlacement(Placement::BOTTOM);
342     } else if (val == "none") {
343         textInfo.SetPlacement(Placement::NONE);
344     }
345 }
346 
GetAttrDataSetData(const std::unique_ptr<JsonValue> & jsonData,MainChart & dataset)347 void GetAttrDataSetData(const std::unique_ptr<JsonValue>& jsonData, MainChart& dataset)
348 {
349     CHECK_NULL_VOID_NOLOG(jsonData);
350     if (!jsonData->IsValid() || !jsonData->IsArray()) {
351         return;
352     }
353     std::vector<LineInfo> line;
354     for (int32_t i = 0; i < jsonData->GetArraySize(); ++i) {
355         PointInfo pointInfo;
356         TextInfo textInfo;
357         SegmentInfo segmentInfo;
358         if (jsonData->GetArrayItem(i)->IsNumber()) {
359             pointInfo.SetX(static_cast<double>(i));
360             pointInfo.SetY(jsonData->GetArrayItem(i)->GetDouble());
361         } else if (jsonData->GetArrayItem(i)->IsObject()) {
362             auto data = jsonData->GetArrayItem(i)->GetChild();
363             while (data && data->IsValid()) {
364                 auto key = data->GetKey();
365                 auto val = data->GetString();
366                 if (key == "description") {
367                     textInfo.SetTextValue(val);
368                 } else if (key == "textLocation") {
369                     ParseTextPlacement(val, textInfo);
370                 } else if (key == "lineDash") {
371                     ParseLineDash(val, segmentInfo);
372                 } else if (key == "lineColor") {
373                     segmentInfo.SetColorString(val);
374                 } else if (key == "textColor") {
375                     textInfo.SetColorString(val);
376                 } else if (key == "value" && data->IsNumber()) {
377                     pointInfo.SetX(static_cast<double>(i));
378                     pointInfo.SetY(data->GetDouble());
379                 } else if (key == "pointStyle" && data->IsObject()) {
380                     GetAttrOptionsSeriesPoint(data, pointInfo);
381                 } else {
382                     LOGW("key is %{public}s. Ignoring!", key.c_str());
383                 }
384                 data = data->GetNext();
385             }
386         } else {
387             continue;
388         }
389         LineInfo lineInfo;
390         lineInfo.SetPointInfo(pointInfo);
391         lineInfo.SetTextInfo(textInfo);
392         lineInfo.SetSegmentInfo(segmentInfo);
393         line.emplace_back(lineInfo);
394     }
395     dataset.SetData(line);
396 }
397 
GetAttrDataset(const std::unique_ptr<JsonValue> & jsonDataSet,MainChart & dataset)398 void GetAttrDataset(const std::unique_ptr<JsonValue>& jsonDataSet, MainChart& dataset)
399 {
400     CHECK_NULL_VOID_NOLOG(jsonDataSet);
401     if (!jsonDataSet->IsValid()) {
402         return;
403     }
404     auto data = jsonDataSet->GetChild();
405     while (data && data->IsValid()) {
406         auto key = data->GetKey();
407         if (key == "gradient") {
408             dataset.SetGradient(data->GetBool());
409         } else if (key == "strokeColor") {
410             dataset.SetStrokeColor(Color::FromString(data->GetString()));
411         } else if (key == "fillColor") {
412             dataset.SetFillColor(Color::FromString(data->GetString()));
413         } else if (key == "data" && data->IsArray()) {
414             GetAttrDataSetData(data, dataset);
415         }
416         data = data->GetNext();
417     }
418 }
419 
GetAttrDatasets(const std::unique_ptr<JsonValue> & jsonDataSets,std::vector<MainChart> & datasets)420 void GetAttrDatasets(const std::unique_ptr<JsonValue>& jsonDataSets, std::vector<MainChart>& datasets)
421 {
422     CHECK_NULL_VOID_NOLOG(jsonDataSets);
423     if (!jsonDataSets->IsValid() || !jsonDataSets->IsArray()) {
424         return;
425     }
426     for (int32_t i = 0; i < jsonDataSets->GetArraySize(); ++i) {
427         auto item = jsonDataSets->GetArrayItem(i);
428         if (item->IsObject()) {
429             MainChart chart;
430             GetAttrDataset(item, chart);
431             datasets.emplace_back(chart);
432         }
433     }
434 }
435 
ParseSegmentObject(const std::unique_ptr<JsonValue> & jsonDataSet,Segment & segment)436 void ParseSegmentObject(const std::unique_ptr<JsonValue>& jsonDataSet, Segment& segment)
437 {
438     CHECK_NULL_VOID_NOLOG(jsonDataSet);
439     if (!jsonDataSet->IsValid()) {
440         return;
441     }
442     auto data = jsonDataSet->GetChild();
443     while (data && data->IsValid()) {
444         auto key = data->GetKey();
445         if (key == "startColor") {
446             segment.SetStartColor(Color::FromString(data->GetString()));
447             segment.SetColorType(SegmentStyleType::USE_COLOR);
448         } else if (key == "endColor") {
449             segment.SetEndColor(Color::FromString(data->GetString()));
450             segment.SetColorType(SegmentStyleType::USE_COLOR);
451         } else if (key == "value") {
452             segment.SetValue(data->GetDouble());
453         } else if (key == "name") {
454             segment.SetSegmentName(data->GetString());
455         } else {
456             LOGD("json parser %{public}s fail", key.c_str());
457         }
458         data = data->GetNext();
459     }
460 }
461 
ParseSegments(const std::unique_ptr<JsonValue> & jsonDataSets,std::vector<Segment> & datasets)462 void ParseSegments(const std::unique_ptr<JsonValue>& jsonDataSets, std::vector<Segment>& datasets)
463 {
464     CHECK_NULL_VOID_NOLOG(jsonDataSets);
465     if (!jsonDataSets->IsValid()) {
466         return;
467     }
468     if (jsonDataSets->IsObject()) {
469         Segment segment;
470         ParseSegmentObject(jsonDataSets, segment);
471         datasets.emplace_back(segment);
472     } else if (jsonDataSets->IsArray()) {
473         for (int32_t i = 0; i < jsonDataSets->GetArraySize(); ++i) {
474             auto item = jsonDataSets->GetArrayItem(i);
475             if (item && item->IsObject()) {
476                 Segment segment;
477                 ParseSegmentObject(item, segment);
478                 datasets.emplace_back(segment);
479             }
480         }
481     }
482 }
483 
GetBadgeConfig(const std::unique_ptr<JsonValue> & jsonDataSets,BadgeConfig & badgeConfig)484 void GetBadgeConfig(const std::unique_ptr<JsonValue>& jsonDataSets, BadgeConfig& badgeConfig)
485 {
486     CHECK_NULL_VOID_NOLOG(jsonDataSets);
487     if (!jsonDataSets->IsValid()) {
488         return;
489     }
490     auto data = jsonDataSets->GetChild();
491     while (data && data->IsValid()) {
492         auto key = data->GetKey();
493         auto valStr = data->GetString();
494         if (valStr.empty()) {
495             valStr = data->ToString();
496         }
497         static const LinearMapNode<void (*)(const std::string&, BadgeConfig&)> badgeConfigOperators[] = {
498             { DOM_BADGE_COLOR,
499                 [](const std::string& valStr, BadgeConfig& badgeConfig) {
500                     badgeConfig.badgeColor = { Color::FromString(valStr), true };
501                 } },
502             { DOM_BADGE_CIRCLE_SIZE,
503                 [](const std::string& valStr, BadgeConfig& badgeConfig) {
504                     badgeConfig.badgeSize = { StringToDimension(valStr), true };
505                 } },
506             { DOM_BADGE_TEXT_COLOR,
507                 [](const std::string& valStr, BadgeConfig& badgeConfig) {
508                     badgeConfig.textColor = { Color::FromString(valStr), true };
509                 } },
510             { DOM_BADGE_TEXT_FONT_SIZE,
511                 [](const std::string& valStr, BadgeConfig& badgeConfig) {
512                     badgeConfig.textSize = { StringToDimension(valStr), true };
513                 } },
514         };
515         auto operatorIter = BinarySearchFindIndex(badgeConfigOperators, ArraySize(badgeConfigOperators), key.c_str());
516         if (operatorIter != -1) {
517             badgeConfigOperators[operatorIter].value(valStr, badgeConfig);
518         } else {
519             LOGD("key : %{public}s unsupported. Ignoring!", key.c_str());
520         }
521         data = data->GetNext();
522     }
523 }
524 
GetStrValue(const std::string & key,std::stack<std::string> & keyStack)525 bool GetStrValue(const std::string& key, std::stack<std::string>& keyStack)
526 {
527     auto topKey = keyStack.top();
528     auto data = JsonUtil::ParseJsonString(topKey);
529     CHECK_NULL_RETURN_NOLOG(data, false);
530     if (!data->IsValid() || !data->Contains(key)) {
531         return false;
532     }
533     keyStack.pop();
534     auto dataValue = data->GetValue(key);
535     auto dataStr = dataValue->IsString() ? dataValue->GetString() : dataValue->ToString();
536     keyStack.emplace(dataStr);
537     return true;
538 }
539 
GetIndexValue(const std::string & key,std::stack<std::string> & keyStack)540 bool GetIndexValue(const std::string& key, std::stack<std::string>& keyStack)
541 {
542     auto topValue = keyStack.top();
543     auto data = JsonUtil::ParseJsonString(topValue);
544     CHECK_NULL_RETURN_NOLOG(data, false);
545     auto index = StringToInt(key);
546     if (!data->IsValid() || !data->IsArray() || (data->IsArray() && index >= data->GetArraySize())) {
547         return false;
548     }
549     keyStack.pop();
550     auto dataValue = data->GetArrayItem(index);
551     auto dataStr = dataValue->IsString() ? dataValue->GetString() : dataValue->ToString();
552     keyStack.emplace(dataStr);
553     return true;
554 }
555 
IsVariable(const std::string & value)556 bool IsVariable(const std::string& value)
557 {
558     return StartWith(value, "{{") && EndWith(value, "}}");
559 }
560 
IsJsonObject(const std::string & value)561 bool IsJsonObject(const std::string& value)
562 {
563     if (!StartWith(value, "{") || !EndWith(value, "}")) {
564         return false;
565     }
566 
567     if (IsVariable(value)) {
568         return false;
569     }
570 
571     return true;
572 }
573 
IsJsonArray(const std::string & value)574 bool IsJsonArray(const std::string& value)
575 {
576     return StartWith(value, "[") && EndWith(value, "]");
577 }
578 
GetVecFromArrStr(const std::string & value)579 std::vector<std::string> GetVecFromArrStr(const std::string& value)
580 {
581     if (value.empty() || value.length() < 2) {
582         return {};
583     }
584     std::string tmp = value.substr(1, value.length() - 2);
585     tmp.erase(std::remove(tmp.begin(), tmp.end(), '"'), tmp.end());
586     tmp.erase(std::remove(tmp.begin(), tmp.end(), ' '), tmp.end());
587     std::regex strDivider(",");
588     std::vector<std::string> strVec(std::sregex_token_iterator(tmp.begin(), tmp.end(), strDivider, -1),
589         std::sregex_token_iterator());
590     return strVec;
591 }
592 
GetArrStrFromVec(const std::vector<std::string> & vec)593 std::string GetArrStrFromVec(const std::vector<std::string>& vec)
594 {
595     std::string res = "[";
596     for (auto iter = vec.begin(); iter != vec.end(); ++iter) {
597         res += "\"";
598         res += *iter;
599         res += "\",";
600     }
601     if (res.length() > 1) {
602         res = res.substr(0, res.length() - 1);
603     }
604     res += "]";
605     return res;
606 }
607 
IsMultiVariable(const std::string & value)608 bool IsMultiVariable(const std::string& value)
609 {
610     return StartWith(value, "$f(") && EndWith(value, ")");
611 }
612 
613 } // namespace
614 
UpdateProps(const std::string & key,std::string value,const std::unique_ptr<JsonValue> & propsJson)615 void JsCardParser::UpdateProps(const std::string& key, std::string value, const std::unique_ptr<JsonValue>& propsJson)
616 {
617     CHECK_NULL_VOID_NOLOG(propsJson);
618     auto propsObject = propsJson->GetValue(key);
619     CHECK_NULL_VOID_NOLOG(propsObject);
620     if (!propsObject->IsValid()) {
621         return;
622     }
623     if (IsVariable(value)) {
624         ParseVariable(value);
625     }
626     if (!propsObject->Contains("value")) {
627         propsObject->Put("value", propsObject->GetValue("default")->ToString().c_str());
628     } else {
629         propsObject->Replace("value", value.c_str());
630     }
631 }
632 
ParseAttributes(const std::unique_ptr<JsonValue> & rootJson,int32_t nodeId,std::vector<std::pair<std::string,std::string>> & attrs,JsCommandDomElementOperator * command,const std::unique_ptr<JsonValue> & dataJson,const std::unique_ptr<JsonValue> & propsJson)633 void JsCardParser::ParseAttributes(const std::unique_ptr<JsonValue>& rootJson, int32_t nodeId,
634     std::vector<std::pair<std::string, std::string>>& attrs, JsCommandDomElementOperator* command,
635     const std::unique_ptr<JsonValue>& dataJson, const std::unique_ptr<JsonValue>& propsJson)
636 {
637     auto attrList = rootJson->GetValue("attr");
638     CHECK_NULL_VOID_NOLOG(attrList);
639     if (!attrList->IsValid()) {
640         return;
641     }
642     auto attr = attrList->GetChild();
643     while (attr && attr->IsValid()) {
644         auto key = attr->GetKey();
645         auto value = attr->IsString() ? attr->GetString() : attr->ToString();
646         static const LinearMapNode<void (*)(std::string&, JsCommandDomElementOperator*, JsCardParser&)>
647             attrOperators[] = {
648                 { "clockconfig",
649                     [](std::string& value, JsCommandDomElementOperator* command, JsCardParser& jsCardParser) {
650                         ClockConfig clockConfig;
651                         jsCardParser.ParseSpecialAttr<ClockConfig>(
652                             std::bind(&JsCardParser::GetClockConfig, &jsCardParser, std::placeholders::_1,
653                                 std::placeholders::_2),
654                             value, clockConfig);
655                         command->SetClockConfig(clockConfig);
656                     } },
657                 { "config",
658                     [](std::string& value, JsCommandDomElementOperator* command, JsCardParser& jsCardParser) {
659                         BadgeConfig badgeConfig;
660                         jsCardParser.ParseSpecialAttr<BadgeConfig>(GetBadgeConfig, value, badgeConfig);
661                         command->SetBadgeConfig(badgeConfig);
662                     } },
663                 { "datasets",
664                     [](std::string& value, JsCommandDomElementOperator* command, JsCardParser& jsCardParser) {
665                         std::vector<MainChart> datasets;
666                         jsCardParser.ParseSpecialAttr<MainChart>(GetAttrDatasets, value, datasets);
667                         command->SetDatasets(datasets);
668                     } },
669                 { "options",
670                     [](std::string& value, JsCommandDomElementOperator* command, JsCardParser& jsCardParser) {
671                         ChartOptions options;
672                         jsCardParser.ParseSpecialAttr<ChartOptions>(GetAttrOptions, value, options);
673                         command->SetOptions(options);
674                     } },
675                 { "segments",
676                     [](std::string& value, JsCommandDomElementOperator* command, JsCardParser& jsCardParser) {
677                         std::vector<Segment> segments;
678                         jsCardParser.ParseSpecialAttr<Segment>(ParseSegments, value, segments);
679                         command->SetSegments(segments);
680                     } },
681             };
682         auto operatorIter = BinarySearchFindIndex(attrOperators, ArraySize(attrOperators), key.c_str());
683         if (operatorIter != -1) {
684             attrOperators[operatorIter].value(value, command, *this);
685             attr = attr->GetNext();
686             continue;
687         }
688         if (IsVariable(value)) {
689             ParseVariable(value, dataJson, propsJson);
690         } else if (IsMultiVariable(value)) {
691             ParseMultiVariable(value, dataJson, propsJson);
692         }
693         attrs.emplace_back(std::make_pair(key, value));
694         attr = attr->GetNext();
695     }
696 }
697 
GetShownValue(std::string & value,const std::unique_ptr<JsonValue> & datajson,const std::unique_ptr<JsonValue> & propsjson)698 bool JsCardParser::GetShownValue(
699     std::string& value, const std::unique_ptr<JsonValue>& datajson, const std::unique_ptr<JsonValue>& propsjson)
700 {
701     std::vector<std::string> splitResult;
702     StringUtils::SplitStr(value, "&&", splitResult);
703     bool showValue = true;
704     for (const auto& splitStr : splitResult) {
705         if (IsVariable(splitStr)) {
706             auto key = splitStr;
707             ParseVariable(key, datajson, propsjson);
708             showValue = showValue && StringToBool(key);
709         } else if (StartWith(splitStr, "!{{") && EndWith(splitStr, "}}")) {
710             // !{{value}} --> {{value}}
711             auto key = splitStr.substr(1, splitStr.size() - 1);
712             ParseVariable(key, datajson, propsjson);
713             showValue = showValue && !StringToBool(key);
714         } else {
715             return false;
716         }
717     }
718     value = showValue ? TRUE : FALSE;
719     return true;
720 }
721 
GetRepeatData(std::unique_ptr<JsonValue> & repeatValue,std::string & key)722 bool JsCardParser::GetRepeatData(std::unique_ptr<JsonValue>& repeatValue, std::string& key)
723 {
724     CHECK_NULL_RETURN(repeatValue, false);
725     if (!repeatValue->IsValid()) {
726         LOGE("GetRepeatData failed, repeat value is invalid.");
727         return false;
728     }
729     auto dataValue = repeatValue->IsString() ? repeatValue->GetString() : repeatValue->ToString();
730     if (IsVariable(dataValue)) {
731         // {{value}} --> value
732         key = dataValue.substr(2, dataValue.size() - 4);
733         if (!dataJson_->Contains(key)) {
734             return false;
735         }
736         repeatValue = dataJson_->GetValue(key);
737     }
738     return true;
739 }
740 
SetRepeatItemValue(uint32_t index,const std::unique_ptr<JsonValue> & repeatValue,bool hasKeyValue)741 void JsCardParser::SetRepeatItemValue(uint32_t index, const std::unique_ptr<JsonValue>& repeatValue, bool hasKeyValue)
742 {
743     CHECK_NULL_VOID(repeatValue);
744     if (!repeatValue->IsValid()) {
745         LOGE("SetRepeatItemValue failed, repeat value is invalid.");
746         return;
747     }
748     auto idx = std::to_string(index);
749     auto itemValue = repeatValue->GetArrayItem(index);
750 
751     // update $idx and $item value.
752     repeatJson_->Contains(REPEAT_INDEX) ? repeatJson_->Replace(REPEAT_INDEX.c_str(), idx.c_str())
753                                         : repeatJson_->Put(REPEAT_INDEX.c_str(), idx.c_str());
754     repeatJson_->Contains(REPEAT_ITEM) ? repeatJson_->Replace(REPEAT_ITEM.c_str(), itemValue)
755                                        : repeatJson_->Put(REPEAT_ITEM.c_str(), itemValue);
756     CHECK_NULL_VOID_NOLOG(hasKeyValue);
757     // update the user-defined index and item value.
758     if (!repeatIndex_.empty()) {
759         repeatJson_->Contains(repeatIndex_) ? repeatJson_->Replace(repeatIndex_.c_str(), idx.c_str())
760                                             : repeatJson_->Put(repeatIndex_.c_str(), idx.c_str());
761     }
762     if (!repeatItem_.empty()) {
763         repeatJson_->Contains(repeatItem_) ? repeatJson_->Replace(repeatItem_.c_str(), itemValue)
764                                            : repeatJson_->Put(repeatItem_.c_str(), itemValue);
765     }
766 }
767 
ParseRepeatIndexItem(const std::unique_ptr<JsonValue> & repeatValue)768 void JsCardParser::ParseRepeatIndexItem(const std::unique_ptr<JsonValue>& repeatValue)
769 {
770     CHECK_NULL_VOID(repeatValue);
771     if (!repeatValue->IsValid()) {
772         LOGE("ParseRepeatIndexItem failed, repeat value is invalid.");
773         return;
774     }
775     if (repeatValue->Contains("key")) {
776         repeatIndex_ = repeatValue->GetValue("key")->GetString();
777     }
778     if (repeatValue->Contains("value")) {
779         repeatItem_ = repeatValue->GetValue("value")->GetString();
780     }
781 }
ResetRepeatIndexItem()782 void JsCardParser::ResetRepeatIndexItem()
783 {
784     repeatIndex_.clear();
785     repeatItem_.clear();
786 }
787 
LoadResImageUrl(const std::string & jsonFile,const std::string & splitStr,std::string & value)788 void JsCardParser::LoadResImageUrl(const std::string& jsonFile, const std::string& splitStr, std::string& value)
789 {
790     if (!resourceJson_->Contains(jsonFile)) {
791         return;
792     }
793     // Path only print relative path
794     LOGI("load res image file is %{public}s", jsonFile.c_str());
795     auto content = resourceJson_->GetValue(jsonFile);
796     CHECK_NULL_VOID(content);
797     if (!content->IsValid()) {
798         LOGE("LoadResImageUrl failed, content is invalid.");
799         return;
800     }
801     std::vector<std::string> keys;
802     StringUtils::StringSplitter(splitStr, '.', keys);
803     auto result = GetJsonValue(keys, content);
804     if (result && result->IsValid()) {
805         value = result->GetString();
806     }
807 }
808 
GetResImageUrl(std::string & value)809 void JsCardParser::GetResImageUrl(std::string& value)
810 {
811     static std::array<std::string, 2> themeArray = { "", "dark" };
812     auto mode = static_cast<int32_t>(colorMode_);
813     // $r('value') --> value
814     auto splitStr = value.substr(4, value.size() - 6);
815     auto iter = imageUrlMap_.find(splitStr + themeArray[mode]);
816     if (iter != imageUrlMap_.end()) {
817         value = iter->second;
818         return;
819     }
820     std::string imagePath;
821     auto jsonFile = std::string(RESOURCES_FOLDER) + "res-" + themeArray[mode] + (themeArray[mode].empty() ? "" : "-") +
822                     GetDeviceDpi(density_) + std::string(FILE_TYPE_JSON);
823     LoadResImageUrl(jsonFile, splitStr, imagePath);
824 
825     if (!themeArray[mode].empty() && imagePath.empty()) {
826         jsonFile =
827             std::string(RESOURCES_FOLDER) + "res-" + themeArray[mode] + "-" + "defaults" + std::string(FILE_TYPE_JSON);
828         LoadResImageUrl(jsonFile, splitStr, imagePath);
829     }
830 
831     if (!themeArray[mode].empty() && imagePath.empty()) {
832         jsonFile =
833             std::string(RESOURCES_FOLDER) + "res-" + themeArray[mode] + std::string(FILE_TYPE_JSON);
834         LoadResImageUrl(jsonFile, splitStr, imagePath);
835     }
836 
837     if (imagePath.empty()) {
838         jsonFile = std::string(RESOURCES_FOLDER) + std::string(DEFAULTS_RESOURCES_JSON_FILE);
839         LoadResImageUrl(jsonFile, splitStr, imagePath);
840     }
841     value = imagePath;
842     imageUrlMap_.emplace(splitStr + themeArray[mode], imagePath);
843 }
844 
GetI18nData(std::string & value)845 bool JsCardParser::GetI18nData(std::string& value)
846 {
847     std::vector<std::string> keys;
848     StringUtils::StringSplitter(value, '.', keys);
849     std::vector<std::string> files;
850     auto context = context_.Upgrade();
851     CHECK_NULL_RETURN_NOLOG(context, false);
852 
853     auto assetManager = assetManager_.Upgrade();
854     CHECK_NULL_RETURN_NOLOG(assetManager, false);
855     assetManager->GetAssetList(I18N_FOLDER, files);
856 
857     std::vector<std::string> fileNameList;
858     for (const auto& file : files) {
859         if (EndWith(file, FILE_TYPE_JSON)) {
860             std::string filename = file.substr(0, file.size() - (sizeof(FILE_TYPE_JSON) - 1));
861             size_t pos = filename.find_last_of("/");
862             pos = (pos == std::string::npos) ? 0 : (pos + 1);
863             fileNameList.emplace_back(filename.substr(pos, filename.size() - pos));
864         }
865     }
866     auto localeTag = AceApplicationInfo::GetInstance().GetLocaleTag();
867     auto priorityFileName = AceResConfig::GetLocaleFallback(localeTag, fileNameList);
868     for (const auto& fileName : priorityFileName) {
869         auto filePath = std::string(I18N_FOLDER) + fileName + std::string(FILE_TYPE_JSON);
870         std::string content;
871         if (GetAssetContentImpl(assetManager, filePath, content)) {
872             auto fileData = ParseFileData(content);
873             auto result = GetJsonValue(keys, fileData);
874             if (result && result->IsValid()) {
875                 value = result->IsString() ? result->GetString() : result->ToString();
876                 return true;
877             }
878         }
879     }
880     return false;
881 }
882 
GetPlurals(std::string & value)883 void JsCardParser::GetPlurals(std::string& value)
884 {
885     // $tc('strings.plurals', 2) --> 'strings.plurals', 2
886     auto variable = value.substr(4, value.size() - 5);
887     std::vector<std::string> splitStr;
888     StringUtils::SplitStr(variable, ",", splitStr);
889     if (splitStr.size() != 2) {
890         return;
891     }
892     if (!StartWith(splitStr[0], "'") || !EndWith(splitStr[0], "'")) {
893         return;
894     }
895     // 'strings.plurals' --> strings.plurals
896     auto tempStr = splitStr[0].substr(1, splitStr[0].size() - 2);
897     GetI18nData(tempStr);
898     auto plurals = ParseFileData(tempStr);
899     auto key = Localization::GetInstance()->PluralRulesFormat(StringUtils::StringToDouble(splitStr[1]));
900     if (plurals->IsValid() && plurals->Contains(key)) {
901         value = plurals->GetValue(key)->GetString();
902     }
903 }
904 
ParseStyles(const std::unique_ptr<JsonValue> & rootJson,int32_t nodeId,std::vector<std::pair<std::string,std::string>> & styles,const std::unique_ptr<JsonValue> & styleJson)905 void JsCardParser::ParseStyles(const std::unique_ptr<JsonValue>& rootJson, int32_t nodeId,
906     std::vector<std::pair<std::string, std::string>>& styles, const std::unique_ptr<JsonValue>& styleJson)
907 {
908     // parse class style
909     auto classList = rootJson->GetValue("classList");
910     if (classList && classList->IsValid()) {
911         auto styleList = classList->GetChild();
912         while (styleList && styleList->IsValid()) {
913             auto value = styleList->GetString();
914             if (IsVariable(value)) {
915                 ParseVariable(value);
916             }
917             std::string styleClass("." + value);
918             SelectStyle(styleClass, styleJson, styles);
919             SelectMediaQueryStyle(styleClass, styles);
920             styleList = styleList->GetNext();
921         }
922     }
923 
924     // parse id style
925     if (rootJson->Contains("id")) {
926         auto value = rootJson->GetValue("id")->GetString();
927         if (IsVariable(value)) {
928             ParseVariable(value);
929         }
930         std::string idStyle("#" + value);
931         SelectStyle(idStyle, styleJson, styles);
932         SelectMediaQueryStyle(idStyle, styles);
933     }
934 
935     // parse inline style
936     ParseInlineStyles(rootJson, styles);
937 }
938 
ParseInlineStyles(const std::unique_ptr<JsonValue> & rootJson,std::vector<std::pair<std::string,std::string>> & styles)939 void JsCardParser::ParseInlineStyles(
940     const std::unique_ptr<JsonValue>& rootJson, std::vector<std::pair<std::string, std::string>>& styles)
941 {
942     auto styleList = rootJson->GetValue("style");
943     CHECK_NULL_VOID_NOLOG(styleList);
944     if (!styleList->IsValid()) {
945         return;
946     }
947     auto style = styleList->GetChild();
948     while (style && style->IsValid()) {
949         auto key = style->GetKey();
950         auto value = style->IsString() ? style->GetString() : style->ToString();
951         if (IsVariable(value)) {
952             ParseVariable(value);
953         }
954         if (key == "fontFamily") {
955             RegisterFont(value);
956         }
957         styles.emplace_back(std::make_pair(key, value));
958         style = style->GetNext();
959     }
960 }
961 
SelectStyle(const std::string & className,const std::unique_ptr<JsonValue> & styleClass,std::vector<std::pair<std::string,std::string>> & styles)962 bool JsCardParser::SelectStyle(const std::string& className, const std::unique_ptr<JsonValue>& styleClass,
963     std::vector<std::pair<std::string, std::string>>& styles)
964 {
965     auto styleDetail = styleClass->GetValue(className);
966     CHECK_NULL_RETURN_NOLOG(styleDetail, false);
967     if (!styleDetail->IsValid()) {
968         return false;
969     }
970     auto style = styleDetail->GetChild();
971     while (style && style->IsValid()) {
972         auto key = style->GetKey();
973         auto styleValue = style->IsString() ? style->GetString() : style->ToString();
974         if (key == "fontFamily") {
975             RegisterFont(styleValue);
976         }
977         styles.emplace_back(std::make_pair(key, styleValue));
978         style = style->GetNext();
979     }
980     return true;
981 }
982 
SelectMediaQueryStyle(const std::string & styleClass,std::vector<std::pair<std::string,std::string>> & styles)983 void JsCardParser::SelectMediaQueryStyle(
984     const std::string& styleClass, std::vector<std::pair<std::string, std::string>>& styles)
985 {
986     const auto& mediaFeature = mediaQueryer_.GetMediaFeature();
987     for (const auto& iter : mediaQueryStyles_) {
988         if (mediaQueryer_.MatchCondition(iter.first, mediaFeature)) {
989             auto mediaIter = mediaQueryStyles_.find(iter.first);
990             if (mediaIter != mediaQueryStyles_.end()) {
991                 if (!SelectStyle(styleClass, mediaIter->second, styles)) {
992                     continue;
993                 }
994                 LOGI("current condition is %{public}s, style class is %{public}s", mediaIter->first.c_str(),
995                     styleClass.c_str());
996             }
997         }
998     }
999 }
1000 
RegisterFont(const std::string & fontFamily)1001 void JsCardParser::RegisterFont(const std::string& fontFamily)
1002 {
1003     auto fontFaceValue = styleJson_->GetValue("@FONT-FACE");
1004     CHECK_NULL_VOID_NOLOG(fontFaceValue);
1005     if (!fontFaceValue->IsValid()) {
1006         return;
1007     }
1008     auto fontFace = fontFaceValue->GetChild();
1009     while (fontFace && fontFace->IsValid()) {
1010         if (fontFace->GetValue("fontFamily")->GetString() == fontFamily) {
1011             auto fontSrc = fontFace->GetValue("src")->GetString();
1012             if (fontSrc.size() > 7) {
1013                 // url("src") --> src
1014                 fontSrc = fontSrc.substr(5, fontSrc.size() - 7);
1015                 auto context = context_.Upgrade();
1016                 if (context) {
1017                     context->RegisterFont(fontFamily, fontSrc);
1018                     return;
1019                 }
1020             }
1021         }
1022         fontFace = fontFace->GetNext();
1023     }
1024 }
1025 
PreUpdateMethodToAction(const std::unique_ptr<JsonValue> & rootJson)1026 void JsCardParser::PreUpdateMethodToAction(const std::unique_ptr<JsonValue>& rootJson)
1027 {
1028     auto eventList = rootJson->GetValue("events");
1029     CHECK_NULL_VOID_NOLOG(eventList);
1030     if (!eventList->IsValid()) {
1031         return;
1032     }
1033     auto event = eventList->GetChild();
1034     while (event && event->IsValid()) {
1035         auto key = event->GetKey();
1036         auto value = event->GetString();
1037         auto actionJson = eventJson_->GetValue(value);
1038         auto eventAction = actionJson->ToString();
1039         methodToAction_[key] = eventAction;
1040         event = event->GetNext();
1041     }
1042 }
1043 
ParseEvents(const std::unique_ptr<JsonValue> & rootJson,const std::unique_ptr<JsonValue> & eventJson,std::vector<std::string> & events,const RefPtr<Framework::JsAcePage> & page,int32_t nodeId)1044 void JsCardParser::ParseEvents(const std::unique_ptr<JsonValue>& rootJson, const std::unique_ptr<JsonValue>& eventJson,
1045     std::vector<std::string>& events, const RefPtr<Framework::JsAcePage>& page, int32_t nodeId)
1046 {
1047     LOGD("ParseEvents json:%{public}s", eventJson->ToString().c_str());
1048     auto eventList = rootJson->GetValue("events");
1049     CHECK_NULL_VOID_NOLOG(eventList);
1050     if (!eventList->IsValid()) {
1051         return;
1052     }
1053     auto event = eventList->GetChild();
1054     while (event && event->IsValid()) {
1055         auto key = event->GetKey();
1056         auto value = event->GetString();
1057         events.emplace_back(key);
1058         auto actionJson = eventJson->GetValue(value);
1059         auto eventAction = GetEventAction(actionJson->ToString(), key, nodeId);
1060         if (actionJson->Contains("action") && actionJson->GetString("action") == "proxy") {
1061             auto linkedEventKey = actionJson->GetString("method");
1062             eventAction = methodToAction_[linkedEventKey];
1063             eventJson_->Put(value.c_str(), JsonUtil::ParseJsonString(eventAction));
1064         }
1065         if (!key.empty() && !eventAction.empty()) {
1066             page->AddNodeEvent(nodeId, key, eventAction);
1067         }
1068         event = event->GetNext();
1069     }
1070 }
1071 
GetEventAction(const std::string & action,const std::string & actionType,int32_t nodeId)1072 std::string JsCardParser::GetEventAction(const std::string& action, const std::string& actionType, int32_t nodeId)
1073 {
1074     auto actionDetail = JsonUtil::ParseJsonString(action);
1075     CHECK_NULL_RETURN(actionDetail, "");
1076     if (!actionDetail->IsValid()) {
1077         LOGE("GetEventAction: action detail is invalid");
1078         return "";
1079     }
1080     ReplaceParam(actionDetail);
1081     return actionDetail->ToString();
1082 }
1083 
ReplaceParam(const std::unique_ptr<JsonValue> & node)1084 void JsCardParser::ReplaceParam(const std::unique_ptr<JsonValue>& node)
1085 {
1086     auto child = node->GetChild();
1087     while (child && child->IsValid()) {
1088         auto key = child->GetKey();
1089         auto value = child->IsString() ? child->GetString() : child->ToString();
1090         auto oldChild = std::move(child);
1091         child = oldChild->GetNext();
1092 
1093         if (IsVariable(value)) {
1094             ParseVariable(value);
1095             node->Replace(key.c_str(), value.c_str());
1096         } else if (IsJsonArray(value)) {
1097             auto strVec = GetVecFromArrStr(value);
1098             for (auto iter = strVec.begin(); iter != strVec.end(); ++iter) {
1099                 if (IsVariable(*iter)) {
1100                     ParseVariable(*iter);
1101                 }
1102             }
1103             value = GetArrStrFromVec(strVec);
1104             node->Replace(key.c_str(), value.c_str());
1105         } else if (IsJsonObject(value)) {
1106             ReplaceParam(oldChild);
1107             node->Replace(key.c_str(), oldChild);
1108         }
1109     }
1110 }
1111 
LoadMediaQueryStyle()1112 void JsCardParser::LoadMediaQueryStyle()
1113 {
1114     auto media = styleJson_->GetValue("@MEDIA");
1115     CHECK_NULL_VOID_NOLOG(media);
1116     if (!media->IsValid()) {
1117         return;
1118     }
1119     static const std::string CONDITION_KEY = "condition";
1120     auto mediaChild = media->GetChild();
1121     while (mediaChild && mediaChild->IsValid()) {
1122         auto condition = mediaChild->GetString(CONDITION_KEY, "");
1123         if (condition.empty()) {
1124             mediaChild = mediaChild->GetNext();
1125             continue;
1126         }
1127 
1128         // record media query style
1129         std::unique_ptr<JsonValue> mediaQueryStyle;
1130         auto iter = mediaQueryStyles_.find(condition);
1131         if (iter != mediaQueryStyles_.end()) {
1132             // already exist same media condition
1133             mediaQueryStyle = std::move(iter->second);
1134         } else {
1135             mediaQueryStyle = JsonUtil::Create(true);
1136         }
1137         auto child = mediaChild->GetChild();
1138         while (child && child->IsValid()) {
1139             if (child->GetKey() != CONDITION_KEY) {
1140                 mediaQueryStyle->Put(child->GetKey().c_str(), child);
1141             }
1142             child = child->GetNext();
1143         }
1144 
1145         mediaQueryStyles_[condition] = std::move(mediaQueryStyle);
1146         mediaChild = mediaChild->GetNext();
1147     }
1148 }
1149 
GetResourceValue(const std::string & path)1150 void JsCardParser::GetResourceValue(const std::string& path)
1151 {
1152     auto assetManager = assetManager_.Upgrade();
1153     CHECK_NULL_VOID_NOLOG(assetManager);
1154     std::string content;
1155     if (GetAssetContentImpl(assetManager, path, content) && !content.empty()) {
1156         auto jsonBody = ParseFileData(content);
1157         resourceJson_->Put(path.c_str(), jsonBody);
1158     }
1159 }
1160 
LoadImageInfo()1161 void JsCardParser::LoadImageInfo()
1162 {
1163     resourceJson_ = JsonUtil::Create(true);
1164 
1165     std::string path = std::string(RESOURCES_FOLDER) + std::string(DEFAULTS_RESOURCES_JSON_FILE);
1166     GetResourceValue(path);
1167     path = std::string(RESOURCES_FOLDER) + "res-" + GetDeviceDpi(density_) + std::string(FILE_TYPE_JSON);
1168     GetResourceValue(path);
1169     path = std::string(RESOURCES_FOLDER) + "res-" + "dark-defaults" + std::string(FILE_TYPE_JSON);
1170     GetResourceValue(path);
1171     path = std::string(RESOURCES_FOLDER) + "res-" + "dark-" + GetDeviceDpi(density_) + std::string(FILE_TYPE_JSON);
1172     GetResourceValue(path);
1173 }
1174 
UpdatePageData(const std::string & dataList,const RefPtr<JsAcePage> & page)1175 void JsCardParser::UpdatePageData(const std::string& dataList, const RefPtr<JsAcePage>& page)
1176 {
1177     LOGI("update data is %{private}s card hap path %{public}s", dataList.c_str(), cardHapPath_.c_str());
1178     CHECK_NULL_VOID(page);
1179     if (dataList.empty()) {
1180         LOGE("update data is null");
1181         return;
1182     }
1183     const auto& rootData = JsonUtil::ParseJsonString(dataList);
1184     CHECK_NULL_VOID_NOLOG(rootData);
1185     if (!rootData->IsValid()) {
1186         return;
1187     }
1188     auto data = rootData->GetChild();
1189     CHECK_NULL_VOID(data);
1190     if (!data->IsValid()) {
1191         LOGE("update card data error");
1192         return;
1193     }
1194     while (data && data->IsValid()) {
1195         auto key = data->GetKey();
1196         dataJson_->Replace(key.c_str(), data);
1197         repeatJson_->Replace(key.c_str(), data);
1198         data = data->GetNext();
1199     }
1200     SetUpdateStatus(page);
1201 }
1202 
UpdateStyle(const RefPtr<JsAcePage> & page)1203 void JsCardParser::UpdateStyle(const RefPtr<JsAcePage>& page)
1204 {
1205     CHECK_NULL_VOID(page);
1206     SetUpdateStatus(page);
1207 }
1208 
ParseComplexExpression(std::string & value,const std::unique_ptr<JsonValue> & json)1209 bool JsCardParser::ParseComplexExpression(std::string& value, const std::unique_ptr<JsonValue>& json)
1210 {
1211     if (value.find('[') == std::string::npos && value.find('.') == std::string::npos) {
1212         return false;
1213     }
1214     std::stack<std::string> keyStack;
1215     auto key = value;
1216     if (!ParseArrayExpression(key, keyStack, json) || keyStack.size() != 1) {
1217         return false;
1218     }
1219     auto result = keyStack.top();
1220     keyStack.pop();
1221     value = result;
1222     return true;
1223 }
1224 
ParseArrayExpression(const std::string & expression,std::stack<std::string> & keyStack,const std::unique_ptr<JsonValue> & json)1225 bool JsCardParser::ParseArrayExpression(
1226     const std::string& expression, std::stack<std::string>& keyStack, const std::unique_ptr<JsonValue>& json)
1227 {
1228     auto dataJson = isRepeat_ ? repeatJson_->ToString() : json->ToString();
1229     auto dataValue = JsonUtil::ParseJsonString(dataJson);
1230     std::string tmpKey;
1231     for (char i : expression) {
1232         switch (i) {
1233             case '[':
1234                 if (tmpKey.empty()) {
1235                     return false;
1236                 }
1237                 if (!ParsePointOperator(tmpKey, keyStack, dataJson)) {
1238                     return false;
1239                 }
1240                 tmpKey.clear();
1241                 break;
1242             case ']':
1243                 if (StringUtils::IsNumber(tmpKey)) {
1244                     if (!GetIndexValue(tmpKey, keyStack)) {
1245                         return false;
1246                     }
1247                 } else if (tmpKey.empty() && keyStack.size() >= 2) {
1248                     auto topValue = keyStack.top();
1249                     keyStack.pop();
1250                     if (!GetStrValue(topValue, keyStack) && !GetIndexValue(topValue, keyStack)) {
1251                         return false;
1252                     }
1253                 } else if (!tmpKey.empty() && dataValue->Contains(tmpKey)) {
1254                     auto data = dataValue->GetValue(tmpKey);
1255                     auto dataStr = data->IsString() ? data->GetString() : data->ToString();
1256                     if (!GetStrValue(dataStr, keyStack) && !GetIndexValue(dataStr, keyStack)) {
1257                         return false;
1258                     }
1259                 } else if (tmpKey.find('.') != std::string::npos) {
1260                     std::vector<std::string> keys;
1261                     StringUtils::StringSplitter(tmpKey, '.', keys);
1262                     auto jsonValue = GetJsonValue(keys, dataValue);
1263                     if (jsonValue && jsonValue->IsValid()) {
1264                         auto result = jsonValue->IsString() ? jsonValue->GetString() : jsonValue->ToString();
1265                         if (!GetStrValue(result, keyStack) && !GetIndexValue(result, keyStack)) {
1266                             return false;
1267                         }
1268                     }
1269                 } else {
1270                     return false;
1271                 }
1272                 tmpKey.clear();
1273                 break;
1274             default: {
1275                 tmpKey += i;
1276                 break;
1277             }
1278         }
1279     }
1280     if (!tmpKey.empty()) {
1281         return ParsePointOperator(tmpKey, keyStack, dataJson);
1282     }
1283     return true;
1284 }
1285 
UpdateDomNode(const RefPtr<Framework::JsAcePage> & page,const std::unique_ptr<JsonValue> & rootJson,int32_t parentId,const std::vector<int> & idArray,const std::unique_ptr<JsonValue> & dataJson,const std::unique_ptr<JsonValue> & styleJson,const std::unique_ptr<JsonValue> & propsJson)1286 void JsCardParser::UpdateDomNode(const RefPtr<Framework::JsAcePage>& page, const std::unique_ptr<JsonValue>& rootJson,
1287     int32_t parentId, const std::vector<int>& idArray, const std::unique_ptr<JsonValue>& dataJson,
1288     const std::unique_ptr<JsonValue>& styleJson, const std::unique_ptr<JsonValue>& propsJson)
1289 {
1290     LOGD("UpdateDomNode root json: %{public}s", rootJson->ToString().c_str());
1291     CHECK_NULL_VOID(page);
1292     if (!rootJson->IsValid()) {
1293         LOGE("fail to UpdateDomNode due to page or root is invalid");
1294         return;
1295     }
1296     if (rootJson->Contains("repeat") && !isRepeat_) {
1297         CreateRepeatDomNode(page, rootJson, parentId);
1298         return;
1299     }
1300     auto type = rootJson->GetString("type");
1301     if (type == "block") {
1302         CreateBlockNode(page, rootJson, parentId);
1303         return;
1304     }
1305     int32_t selfId = 0;
1306     if (!isRepeat_) {
1307         selfId = parentId < 0 ? DOM_ROOT_NODE_ID_BASE : nodeId_;
1308         ++nodeId_;
1309     } else {
1310         if (listNodeIndex_ < static_cast<int32_t>(idArray.size())) {
1311             selfId = idArray[listNodeIndex_];
1312             ++listNodeIndex_;
1313         }
1314     }
1315     bool shouldShow = true;
1316     bool hasShownAttr = false;
1317     GetShownAttr(rootJson, dataJson, propsJson, shouldShow, hasShownAttr);
1318     type = rootJson->GetValue("type")->GetString();
1319     if (rootBody_->Contains(type)) {
1320         // if rootBody contains this type, it must be a customer component.
1321         auto customJson = rootBody_->GetValue(type);
1322         auto customJsonTemplate = customJson->GetValue("template");
1323         auto customJsonData = customJson->GetValue("data");
1324         auto customJsonProps = customJson->GetValue("props");
1325         auto customJsonStyle = customJson->GetValue("styles");
1326         auto attrList = rootJson->GetValue("attr");
1327         CHECK_NULL_VOID_NOLOG(attrList);
1328         if (!attrList->IsValid()) {
1329             return;
1330         }
1331         auto attr = attrList->GetChild();
1332         while (attr && attr->IsValid()) {
1333             auto key = attr->GetKey();
1334             auto value = attr->IsString() ? attr->GetString() : attr->ToString();
1335             UpdateProps(key, value, customJsonProps);
1336             attr = attr->GetNext();
1337         }
1338         ParseStyles(rootJson, selfId, customStyles_, styleJson);
1339         UpdateDomNode(page, customJsonTemplate, parentId, idArray, customJsonData, customJsonStyle, customJsonProps);
1340         return;
1341     }
1342     std::vector<std::pair<std::string, std::string>> attrs;
1343     std::vector<std::pair<std::string, std::string>> styles(customStyles_);
1344     customStyles_.clear();
1345     std::vector<std::string> events;
1346     auto styleCommand = Referenced::MakeRefPtr<JsCommandUpdateDomElementStyles>(selfId);
1347     auto attrCommand = Referenced::MakeRefPtr<JsCommandUpdateDomElementAttrs>(selfId);
1348     auto ptr = Referenced::RawPtr(attrCommand);
1349     if (shouldShow && hasShownAttr) {
1350         attrs.emplace_back(std::make_pair("show", TRUE));
1351     }
1352     ParseAttributes(rootJson, selfId, attrs, static_cast<JsCommandDomElementOperator*>(ptr), dataJson, propsJson);
1353     if (!shouldShow && hasShownAttr) {
1354         attrs.emplace_back(std::make_pair("show", FALSE));
1355     }
1356     ParseStyles(rootJson, selfId, styles, styleJson);
1357     ParseEvents(rootJson, events, page, selfId);
1358     attrCommand->SetAttributes(std::move(attrs));
1359     styleCommand->SetStyles(std::move(styles));
1360     page->PushCommand(attrCommand);
1361     page->PushCommand(styleCommand);
1362 
1363     auto childList = rootJson->GetValue("children");
1364     if (childList && childList->IsValid()) {
1365         auto child = childList->GetChild();
1366         while (child && child->IsValid()) {
1367             UpdateDomNode(page, child, selfId, idArray, dataJson, styleJson, propsJson);
1368             child = child->GetNext();
1369         }
1370     }
1371 }
1372 
ParseVariable(std::string & value,const std::unique_ptr<JsonValue> & dataJson,const std::unique_ptr<JsonValue> & propsJson)1373 void JsCardParser::ParseVariable(
1374     std::string& value, const std::unique_ptr<JsonValue>& dataJson, const std::unique_ptr<JsonValue>& propsJson)
1375 {
1376     // {{value}} --> value
1377     auto variable = value.substr(2, value.size() - 4);
1378     if (GetAndParseProps(variable, propsJson) || ParseComplexExpression(variable, dataJson) ||
1379         GetVariable(variable, dataJson) || ParseSpecialVariable(variable) ||
1380         ParseTernaryExpression(variable, propsJson) || ParseLogicalExpression(variable, propsJson)) {
1381         value = variable;
1382 
1383         if (IsVariable(value)) {
1384             ParseVariable(value, dataJson, propsJson);
1385         }
1386     }
1387 }
1388 
ParseMultiVariable(std::string & value,const std::unique_ptr<JsonValue> & dataJson,const std::unique_ptr<JsonValue> & propsJson)1389 void JsCardParser::ParseMultiVariable(
1390     std::string& value, const std::unique_ptr<JsonValue>& dataJson, const std::unique_ptr<JsonValue>& propsJson)
1391 {
1392     if (value.size() < 4) {
1393         return;
1394     }
1395     // $f({{key1}} {{key2}}) --> {{key1}} {{key2}}
1396     auto variable = value.substr(3, value.size() - 4);
1397 
1398     value = "";
1399     // Splicing Between Variables and constants,like variable = "my name is {{name}}, and i am from {{city}}."
1400     while (variable.find("{{") != std::string::npos && variable.find("}}") != std::string::npos) {
1401         auto startPos = variable.find("{{");
1402         auto endPos = variable.find("}}");
1403         if (endPos < startPos) {
1404             break;
1405         }
1406         // var = {{name}}, after parsing, var = "tom".
1407         std::string var = variable.substr(startPos, endPos - startPos + 2);
1408         ParseVariable(var, dataJson, propsJson);
1409 
1410         // after parsing, value = "my name is tom".
1411         value += variable.substr(0, startPos) + var;
1412 
1413         // variable = ", and i am from {{city}}."
1414         variable = variable.substr(endPos + 2, variable.size() - endPos - 2);
1415     }
1416     value += variable;
1417 }
1418 
ParseTernaryExpression(std::string & value,const std::unique_ptr<JsonValue> & propsJson)1419 bool JsCardParser::ParseTernaryExpression(std::string& value, const std::unique_ptr<JsonValue>& propsJson)
1420 {
1421     if (value.find('?') == std::string::npos || value.find(':') == std::string::npos) {
1422         return false;
1423     }
1424     // eg:{{flag ? key1 : key2}}, flagStr[0] = "flag", flagStr[1] = "key1 : key2".
1425     std::vector<std::string> flagStr;
1426     StringUtils::SplitStr(value, "?", flagStr);
1427     if (flagStr.size() != 2) {
1428         return false;
1429     }
1430     bool flag = false;
1431     if (GetAndParseProps(flagStr[0], propsJson) || GetVariable(flagStr[0])) {
1432         flag = flagStr[0] == TRUE;
1433     }
1434 
1435     std::vector<std::string> keyStr;
1436     StringUtils::SplitStr(flagStr[1], ":", keyStr);
1437     if (keyStr.size() != 2) {
1438         return false;
1439     }
1440     for (auto& key : keyStr) {
1441         if (StartWith(key, "\'") && EndWith(key, "\'")) {
1442             key = key.substr(1, key.size() - 2);
1443         }
1444         if (StartWith(key, "\"") && EndWith(key, "\"")) {
1445             key = key.substr(1, key.size() - 2);
1446         }
1447     }
1448 
1449     // parse key1 and key2.
1450     GetVariable(keyStr[0]);
1451     GetVariable(keyStr[1]);
1452     value = flag ? keyStr[0] : keyStr[1];
1453     return true;
1454 }
1455 
ParseLogicalExpression(std::string & value,const std::unique_ptr<JsonValue> & propsJson)1456 bool JsCardParser::ParseLogicalExpression(std::string& value, const std::unique_ptr<JsonValue>& propsJson)
1457 {
1458     std::vector<std::string> splitStr;
1459     if (value.find("&&") != std::string::npos) {
1460         // for {{flag1 && flag2}}.
1461         StringUtils::SplitStr(value, "&&", splitStr);
1462         if (splitStr.size() != 2) {
1463             return false;
1464         }
1465         if ((GetAndParseProps(splitStr[0], propsJson) || GetVariable(splitStr[0])) &&
1466             (GetAndParseProps(splitStr[1], propsJson) || GetVariable(splitStr[1]))) {
1467             value = (splitStr[0] == TRUE && splitStr[1] == TRUE) ? TRUE : FALSE;
1468             return true;
1469         }
1470     } else if (value.find("||") != std::string::npos) {
1471         // for {{flag1 || flag2}}.
1472         StringUtils::SplitStr(value, "||", splitStr);
1473         if (splitStr.size() != 2) {
1474             return false;
1475         }
1476         if ((GetAndParseProps(splitStr[0], propsJson) || GetVariable(splitStr[0])) &&
1477             (GetAndParseProps(splitStr[1], propsJson) || GetVariable(splitStr[1]))) {
1478             value = (splitStr[0] == TRUE || splitStr[1] == TRUE) ? TRUE : FALSE;
1479             return true;
1480         }
1481     } else if (value.find('!') != std::string::npos) {
1482         // for {{!flag1}}.
1483         StringUtils::SplitStr(value, "!", splitStr);
1484         if (splitStr.size() != 1) {
1485             return false;
1486         }
1487         if (GetAndParseProps(splitStr[0], propsJson) || GetVariable(splitStr[0])) {
1488             value = splitStr[0] == TRUE ? FALSE : TRUE;
1489             return true;
1490         }
1491     }
1492     return false;
1493 }
1494 
GetAndParseProps(std::string & value,const std::unique_ptr<JsonValue> & propsJson)1495 bool JsCardParser::GetAndParseProps(std::string& value, const std::unique_ptr<JsonValue>& propsJson)
1496 {
1497     CHECK_NULL_RETURN_NOLOG(propsJson, false);
1498     if (ParsePropsArray(value, propsJson) || ParsePropsVariable(value, propsJson)) {
1499         return true;
1500     }
1501     return false;
1502 }
1503 
ParsePropsVariable(std::string & value,const std::unique_ptr<JsonValue> & propsJson)1504 bool JsCardParser::ParsePropsVariable(std::string& value, const std::unique_ptr<JsonValue>& propsJson)
1505 {
1506     auto propsObject = propsJson->GetValue(value);
1507     CHECK_NULL_RETURN(propsObject, false);
1508     if (!propsObject->IsValid()) {
1509         LOGI("GetAndParseProps propsObject is empty or propsObject->IsValid()");
1510         return false;
1511     }
1512     auto propValueJson = propsObject->GetValue("value");
1513     auto defaultJson = propsObject->GetValue("default");
1514     if (propValueJson && propValueJson->IsValid()) {
1515         value = propValueJson->IsString() ? propValueJson->GetString() : propValueJson->ToString();
1516     } else {
1517         // no need to check valid, the json will recover from error state
1518         value = defaultJson->IsString() ? defaultJson->GetString() : defaultJson->ToString();
1519     }
1520     // after user use current value in json, need to reset back to default
1521 
1522     propsObject->Replace(
1523         "value", defaultJson->IsString() ? defaultJson->GetString().c_str() : defaultJson->ToString().c_str());
1524     return true;
1525 }
1526 
GetArrayItemSubstring(const std::string & s)1527 std::string GetArrayItemSubstring(const std::string& s)
1528 {
1529     std::string result;
1530     auto endIndex = s.find("[");
1531     if (endIndex != std::string::npos) {
1532         result = s.substr(0, endIndex);
1533     }
1534     return result;
1535 }
1536 
ParsePropsArray(std::string & value,const std::unique_ptr<JsonValue> & propsJson)1537 bool JsCardParser::ParsePropsArray(std::string& value, const std::unique_ptr<JsonValue>& propsJson)
1538 {
1539     const auto arrayParam = GetArrayItemSubstring(value);
1540     if (arrayParam.empty()) {
1541         return false;
1542     }
1543     auto propsObject = propsJson->GetValue(arrayParam);
1544     CHECK_NULL_RETURN(propsObject, false);
1545     if (!propsObject->IsValid()) {
1546         LOGI("GetAndParseProps propsObject is empty or propsObject->IsValid()");
1547         return false;
1548     }
1549     auto propValueJson = propsObject->GetValue("value");
1550     auto defaultJson = propsObject->GetValue("default");
1551     auto arrayPropJson = JsonUtil::Create(true);
1552     if (propValueJson && propValueJson->IsValid()) {
1553         arrayPropJson->Put(arrayParam.c_str(), propValueJson);
1554     } else {
1555         arrayPropJson->Put(arrayParam.c_str(), defaultJson);
1556     }
1557 
1558     if (ParseComplexExpression(value, arrayPropJson)) {
1559         // after user use current value in json, need to reset back to default
1560         propsObject->Replace(
1561             "value", defaultJson->IsString() ? defaultJson->GetString().c_str() : defaultJson->ToString().c_str());
1562         return true;
1563     }
1564     return false;
1565 }
1566 
ParseSpecialVariable(std::string & value)1567 bool JsCardParser::ParseSpecialVariable(std::string& value)
1568 {
1569     if (StartWith(value, "$r('") && EndWith(value, "')")) {
1570         GetResImageUrl(value);
1571         return true;
1572     } else if (StartWith(value, "$t('") && EndWith(value, "')")) {
1573         // $t('value') --> value
1574         value = value.substr(4, value.size() - 6);
1575         auto result = GetI18nData(value);
1576         LOGI("Get i18n data is %{public}s, card hap path %{public}s", value.c_str(), cardHapPath_.c_str());
1577         return result;
1578     } else if (StartWith(value, "$tc(") && EndWith(value, ")")) {
1579         GetPlurals(value);
1580         return true;
1581     }
1582     return false;
1583 }
1584 
GetVariable(std::string & value,const std::unique_ptr<JsonValue> & dataJson)1585 bool JsCardParser::GetVariable(std::string& value, const std::unique_ptr<JsonValue>& dataJson)
1586 {
1587     auto key = value;
1588     if (!repeatJson_->Contains(key) && isRepeat_) {
1589         return false;
1590     }
1591 
1592     CHECK_NULL_RETURN(dataJson, false);
1593     LOGD("GetVariable value :%{private}s dataJson:%{private}s", value.c_str(), dataJson->ToString().c_str());
1594     auto dataValue = dataJson->GetValue(key);
1595     if (isRepeat_) {
1596         dataValue = repeatJson_->GetValue(key);
1597     }
1598     CHECK_NULL_RETURN_NOLOG(dataValue, false);
1599     if (!dataValue->IsValid()) {
1600         return false;
1601     }
1602     value = dataValue->IsString() ? dataValue->GetString() : dataValue->ToString();
1603     if (IsVariable(value)) {
1604         ParseVariable(value, dataJson);
1605     }
1606     LOGD("return value :%{private}s", value.c_str());
1607     return true;
1608 }
1609 
1610 template<typename T>
ParseSpecialAttr(const std::function<void (const std::unique_ptr<JsonValue> &,std::vector<T> &)> & function,std::string & value,std::vector<T> & vector)1611 void JsCardParser::ParseSpecialAttr(
1612     const std::function<void(const std::unique_ptr<JsonValue>&, std::vector<T>&)>& function, std::string& value,
1613     std::vector<T>& vector)
1614 {
1615     if (IsVariable(value)) {
1616         ParseVariable(value);
1617         auto jsonValue = JsonUtil::ParseJsonString(value);
1618         function(jsonValue, vector);
1619     } else {
1620         auto jsonValue = JsonUtil::ParseJsonString(value);
1621         function(jsonValue, vector);
1622     }
1623 }
1624 
1625 template<typename T>
ParseSpecialAttr(const std::function<void (const std::unique_ptr<JsonValue> &,T &)> & function,std::string & variable,T & value)1626 void JsCardParser::ParseSpecialAttr(
1627     const std::function<void(const std::unique_ptr<JsonValue>&, T&)>& function, std::string& variable, T& value)
1628 {
1629     if (IsVariable(variable)) {
1630         ParseVariable(variable);
1631         auto jsonValue = JsonUtil::ParseJsonString(variable);
1632         function(jsonValue, value);
1633     } else {
1634         auto jsonValue = JsonUtil::ParseJsonString(variable);
1635         function(jsonValue, value);
1636     }
1637 }
1638 
ParsePointOperator(const std::string & tmpKey,std::stack<std::string> & keyStack,const std::string & dataJson)1639 bool JsCardParser::ParsePointOperator(
1640     const std::string& tmpKey, std::stack<std::string>& keyStack, const std::string& dataJson)
1641 {
1642     std::unique_ptr<JsonValue> data;
1643     if (tmpKey[0] == '.') {
1644         if (keyStack.empty()) {
1645             return false;
1646         }
1647         data = JsonUtil::ParseJsonString(keyStack.top());
1648         keyStack.pop();
1649     } else {
1650         data = JsonUtil::ParseJsonString(dataJson);
1651     }
1652     std::vector<std::string> keys;
1653     StringUtils::StringSplitter(tmpKey, '.', keys);
1654     auto result = GetJsonValue(keys, data);
1655     if (result && result->IsValid()) {
1656         auto dataStr = result->IsString() ? result->GetString() : result->ToString();
1657         keyStack.emplace(dataStr);
1658         return true;
1659     }
1660     return false;
1661 }
1662 
CreateDomNode(const RefPtr<Framework::JsAcePage> & page,const std::unique_ptr<JsonValue> & rootJson,int32_t parentId,const std::unique_ptr<JsonValue> & dataJson,const std::unique_ptr<JsonValue> & actionJson,const std::unique_ptr<JsonValue> & styleJson,const std::unique_ptr<JsonValue> & propsJson,bool isNewNode)1663 void JsCardParser::CreateDomNode(const RefPtr<Framework::JsAcePage>& page, const std::unique_ptr<JsonValue>& rootJson,
1664     int32_t parentId, const std::unique_ptr<JsonValue>& dataJson, const std::unique_ptr<JsonValue>& actionJson,
1665     const std::unique_ptr<JsonValue>& styleJson, const std::unique_ptr<JsonValue>& propsJson, bool isNewNode)
1666 {
1667     CHECK_NULL_VOID(page);
1668     if (!rootJson->IsValid()) {
1669         LOGE("fail to CreateDomNode due to page or root is invalid");
1670         EventReport::SendFormException(FormExcepType::CREATE_NODE_ERR);
1671         return;
1672     }
1673     if (rootJson->Contains("repeat") && !isRepeat_) {
1674         CreateRepeatDomNode(page, rootJson, parentId);
1675         return;
1676     }
1677     auto type = rootJson->GetString("type");
1678     if (type == "block") {
1679         CreateBlockNode(page, rootJson, parentId);
1680         return;
1681     }
1682     int32_t nodeId = 0;
1683     if (!isNewNode) {
1684         nodeId = parentId < 0 ? DOM_ROOT_NODE_ID_BASE : nodeId_;
1685         ++nodeId_;
1686     } else {
1687         nodeId = maxNodeId_++;
1688     }
1689     if (isRepeat_) {
1690         idArray_.emplace_back(nodeId);
1691     }
1692     bool shouldShow = true;
1693     bool hasShownAttr = false;
1694     GetShownAttr(rootJson, dataJson, propsJson, shouldShow, hasShownAttr);
1695     type = rootJson->GetValue("type")->GetString();
1696     if (rootBody_->Contains(type)) {
1697         // if rootBody contains this type, it must be a customer component.
1698         auto customJson = rootBody_->GetValue(type);
1699         auto customJsonTemplate = customJson->GetValue("template");
1700         auto customJsonData = customJson->GetValue("data");
1701         auto customJsonProps = customJson->GetValue("props");
1702         auto customJsonActions = customJson->GetValue("actions");
1703         auto customJsonStyle = customJson->GetValue("styles");
1704         auto attrList = rootJson->GetValue("attr");
1705         CHECK_NULL_VOID_NOLOG(attrList);
1706         if (!attrList->IsValid()) {
1707             return;
1708         }
1709         auto attr = attrList->GetChild();
1710         while (attr && attr->IsValid()) {
1711             auto key = attr->GetKey();
1712             auto value = attr->IsString() ? attr->GetString() : attr->ToString();
1713             UpdateProps(key, value, customJsonProps);
1714             attr = attr->GetNext();
1715         }
1716         ParseStyles(rootJson, nodeId, customStyles_, styleJson);
1717         PreUpdateMethodToAction(rootJson);
1718         CreateDomNode(page, customJsonTemplate, parentId, customJsonData, customJsonActions, customJsonStyle,
1719             customJsonProps, isNewNode);
1720         return;
1721     }
1722     std::vector<std::pair<std::string, std::string>> attrs;
1723     std::vector<std::pair<std::string, std::string>> styles(customStyles_);
1724     customStyles_.clear();
1725     std::vector<std::string> events;
1726     RefPtr<Framework::JsCommandDomElementCreator> command;
1727     if (parentId < 0) {
1728         command = Referenced::MakeRefPtr<Framework::JsCommandCreateDomBody>(type, nodeId);
1729     } else {
1730         command = Referenced::MakeRefPtr<Framework::JsCommandAddDomElement>(type, nodeId, parentId);
1731     }
1732     command->SetPipelineContext(AceType::DynamicCast<PipelineContext>(context_));
1733     auto ptr = Referenced::RawPtr(command);
1734     if (shouldShow && hasShownAttr) {
1735         attrs.emplace_back(std::make_pair("show", TRUE));
1736     }
1737     ParseAttributes(rootJson, nodeId, attrs, (Framework::JsCommandDomElementOperator*)ptr, dataJson, propsJson);
1738     if (!shouldShow && hasShownAttr) {
1739         attrs.emplace_back(std::make_pair("show", FALSE));
1740     }
1741     ParseStyles(rootJson, nodeId, styles, styleJson);
1742     ParseEvents(rootJson, actionJson, events, page, nodeId);
1743     command->SetAttributes(std::move(attrs));
1744     command->SetStyles(std::move(styles));
1745     command->AddEvents(std::move(events));
1746     page->PushCommand(command);
1747 
1748     auto childList = rootJson->GetValue("children");
1749     if (childList && childList->IsValid()) {
1750         auto child = childList->GetChild();
1751         while (child && child->IsValid()) {
1752             CreateDomNode(page, child, nodeId, dataJson, actionJson, styleJson, propsJson, isNewNode);
1753             child = child->GetNext();
1754         }
1755     }
1756 }
1757 
CreateRepeatDomNode(const RefPtr<Framework::JsAcePage> & page,const std::unique_ptr<JsonValue> & rootJson,int32_t parentId)1758 void JsCardParser::CreateRepeatDomNode(
1759     const RefPtr<Framework::JsAcePage>& page, const std::unique_ptr<JsonValue>& rootJson, int32_t parentId)
1760 {
1761     auto repeatValue = rootJson->GetValue("repeat");
1762     CHECK_NULL_VOID(repeatValue);
1763     if (!repeatValue->IsValid()) {
1764         LOGE("CreateRepeatDomNode failed, repeat value is invalid.");
1765         return;
1766     }
1767     isRepeat_ = true;
1768     std::string key;
1769     if (repeatValue->IsString()) {
1770         // eg: repeatValue = {{list}}.
1771         if (!GetRepeatData(repeatValue, key)) {
1772             LOGE("CreateRepeatDomNode failed, root data does not contains repeat value.");
1773             isRepeat_ = false;
1774             return;
1775         }
1776         ProcessRepeatNode(page, rootJson, key, parentId, false, repeatValue);
1777     } else {
1778         // eg: repeatValue = {"exp": {{list}}, "key":"index", "value": "item"}.
1779         if (!repeatValue->Contains("exp")) {
1780             LOGE("CreateRepeatDomNode failed, repeat value does not contains exp.");
1781             isRepeat_ = false;
1782             return;
1783         }
1784         auto expValue = repeatValue->GetValue("exp");
1785         if (!GetRepeatData(expValue, key)) {
1786             LOGE("CreateRepeatDomNode failed, root data does not contains exp value.");
1787             isRepeat_ = false;
1788             return;
1789         }
1790         ParseRepeatIndexItem(repeatValue);
1791         ProcessRepeatNode(page, rootJson, key, parentId, true, expValue);
1792         ResetRepeatIndexItem();
1793     }
1794     isRepeat_ = false;
1795 }
1796 
GetClockConfig(const std::unique_ptr<JsonValue> & jsonDataSets,ClockConfig & clockConfig)1797 void JsCardParser::GetClockConfig(const std::unique_ptr<JsonValue>& jsonDataSets, ClockConfig& clockConfig)
1798 {
1799     CHECK_NULL_VOID_NOLOG(jsonDataSets);
1800     if (!jsonDataSets->IsValid()) {
1801         return;
1802     }
1803     auto data = jsonDataSets->GetChild();
1804     while (data && data->IsValid()) {
1805         auto key = data->GetKey();
1806         auto valStr = data->IsString() ? data->GetString() : data->ToString();
1807         static const LinearMapNode<void (*)(std::string&, ClockConfig&, JsCardParser&)> clockConfigOperators[] = {
1808             { DOM_DIGIT_COLOR,
1809                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1810                     clockConfig.digitColor_ = valStr;
1811                 } },
1812             { DOM_DIGIT_COLOR_NIGHT,
1813                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1814                     clockConfig.digitColorNight_ = valStr;
1815                 } },
1816             { DOM_DIGIT_RADIUS_RATIO,
1817                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1818                     clockConfig.digitRadiusRatio_ = StringToDouble(valStr);
1819                 } },
1820             { DOM_DIGIT_SIZE_RATIO,
1821                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1822                     clockConfig.digitSizeRatio_ = StringToDouble(valStr);
1823                 } },
1824             { DOM_CLOCK_FACE_SOURCE,
1825                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1826                     if (IsVariable(valStr)) {
1827                         jsCardParser.ParseVariable(valStr);
1828                     }
1829                     clockConfig.clockFaceSrc_ = valStr;
1830                 } },
1831             { DOM_CLOCK_FACE_SOURCE_NIGHT,
1832                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1833                     if (IsVariable(valStr)) {
1834                         jsCardParser.ParseVariable(valStr);
1835                     }
1836                     clockConfig.clockFaceNightSrc_ = valStr;
1837                 } },
1838             { DOM_HOUR_HAND_SOURCE,
1839                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1840                     if (IsVariable(valStr)) {
1841                         jsCardParser.ParseVariable(valStr);
1842                     }
1843                     clockConfig.hourHandSrc_ = valStr;
1844                 } },
1845             { DOM_HOUR_HAND_SOURCE_NIGHT,
1846                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1847                     if (IsVariable(valStr)) {
1848                         jsCardParser.ParseVariable(valStr);
1849                     }
1850                     clockConfig.hourHandNightSrc_ = valStr;
1851                 } },
1852             { DOM_MINUTE_HAND_SOURCE,
1853                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1854                     if (IsVariable(valStr)) {
1855                         jsCardParser.ParseVariable(valStr);
1856                     }
1857                     clockConfig.minuteHandSrc_ = valStr;
1858                 } },
1859             { DOM_MINUTE_HAND_SOURCE_NIGHT,
1860                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1861                     if (IsVariable(valStr)) {
1862                         jsCardParser.ParseVariable(valStr);
1863                     }
1864                     clockConfig.minuteHandNightSrc_ = valStr;
1865                 } },
1866             { DOM_SECOND_HAND_SOURCE,
1867                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1868                     if (IsVariable(valStr)) {
1869                         jsCardParser.ParseVariable(valStr);
1870                     }
1871                     clockConfig.secondHandSrc_ = valStr;
1872                 } },
1873             { DOM_SECOND_HAND_SOURCE_NIGHT,
1874                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1875                     if (IsVariable(valStr)) {
1876                         jsCardParser.ParseVariable(valStr);
1877                     }
1878                     clockConfig.secondHandNightSrc_ = valStr;
1879                 } },
1880         };
1881         auto operatorIter = BinarySearchFindIndex(clockConfigOperators, ArraySize(clockConfigOperators), key.c_str());
1882         if (operatorIter != -1) {
1883             clockConfigOperators[operatorIter].value(valStr, clockConfig, *this);
1884         } else {
1885             LOGD("key : %{public}s unsupported. Ignoring!", key.c_str());
1886         }
1887         data = data->GetNext();
1888     }
1889 }
1890 
ProcessRepeatNode(const RefPtr<Framework::JsAcePage> & page,const std::unique_ptr<JsonValue> & rootJson,const std::string & key,int32_t parentId,bool hasKeyValue,std::unique_ptr<JsonValue> & repeatValue)1891 void JsCardParser::ProcessRepeatNode(const RefPtr<Framework::JsAcePage>& page,
1892     const std::unique_ptr<JsonValue>& rootJson, const std::string& key, int32_t parentId, bool hasKeyValue,
1893     std::unique_ptr<JsonValue>& repeatValue)
1894 {
1895     ++numberOfForNode_;
1896     if (parsingStatus_ == ParsingStatus::CREATE) {
1897         if (repeatValue->GetArraySize() == 0) {
1898             listIdMap_.emplace(numberOfForNode_, std::make_pair(idArray_, 0));
1899             singleLoopMap_.emplace(numberOfForNode_, 0);
1900             return;
1901         }
1902         for (auto i = 0; i < repeatValue->GetArraySize(); i++) {
1903             SetRepeatItemValue(i, repeatValue, hasKeyValue);
1904             CreateDomNode(page, rootJson, parentId);
1905         }
1906         // Number of nodes in a single loop
1907         auto factor = idArray_.size() / repeatValue->GetArraySize();
1908         listIdMap_.emplace(numberOfForNode_, std::make_pair(idArray_, static_cast<int32_t>(idArray_.size())));
1909         singleLoopMap_.emplace(numberOfForNode_, factor);
1910     } else if (parsingStatus_ == ParsingStatus::UPDATE) {
1911         auto iter = listIdMap_.find(numberOfForNode_);
1912         auto loopIter = singleLoopMap_.find(numberOfForNode_);
1913         if (iter == listIdMap_.end() || loopIter == singleLoopMap_.end()) {
1914             return;
1915         }
1916         auto array = iter->second.first;
1917         auto factor = loopIter->second;
1918         int32_t lastSize = factor > 0 ? array.size() / factor : 0;
1919         auto updateSize = std::min(static_cast<int32_t>(lastSize), repeatValue->GetArraySize());
1920         for (auto i = 0; i < updateSize; ++i) {
1921             SetRepeatItemValue(i, repeatValue, hasKeyValue);
1922             UpdateDomNode(page, rootJson, parentId, array);
1923         }
1924 
1925         if (repeatValue->GetArraySize() > lastSize) {
1926             for (auto i = lastSize; i < repeatValue->GetArraySize(); ++i) {
1927                 SetRepeatItemValue(i, repeatValue, hasKeyValue);
1928                 CreateDomNode(page, rootJson, parentId, true);
1929             }
1930             if (factor == 0) {
1931                 factor = static_cast<int32_t>(idArray_.size()) / repeatValue->GetArraySize();
1932                 loopIter->second = factor;
1933             }
1934             iter->second.first.insert(iter->second.first.end(), idArray_.begin(), idArray_.end());
1935         } else if (lastSize > repeatValue->GetArraySize()) {
1936             for (int32_t i = array.size() - factor; i >= repeatValue->GetArraySize() * factor; i = i - factor) {
1937                 auto nodeId = iter->second.first[i];
1938                 page->PushCommand(Referenced::MakeRefPtr<JsCommandRemoveDomElement>(nodeId));
1939             }
1940             iter->second.first.erase(
1941                 iter->second.first.end() - (array.size() - static_cast<size_t>(repeatValue->GetArraySize() * factor)),
1942                 iter->second.first.end());
1943         }
1944         nodeId_ += iter->second.second;
1945     }
1946     idArray_.clear();
1947     listNodeIndex_ = 0;
1948 }
1949 
SetUpdateStatus(const RefPtr<Framework::JsAcePage> & page)1950 void JsCardParser::SetUpdateStatus(const RefPtr<Framework::JsAcePage>& page)
1951 {
1952     parsingStatus_ = ParsingStatus::UPDATE;
1953     UpdateDomNode(page, rootJson_, -1);
1954     nodeId_ = 0;
1955     numberOfForNode_ = 0;
1956     page->FlushCommands();
1957 }
1958 
GetShownAttr(const std::unique_ptr<JsonValue> & rootJson,const std::unique_ptr<JsonValue> & dataJson,const std::unique_ptr<JsonValue> & propsJson,bool & shouldShow,bool & hasShownAttr)1959 void JsCardParser::GetShownAttr(const std::unique_ptr<JsonValue>& rootJson, const std::unique_ptr<JsonValue>& dataJson,
1960     const std::unique_ptr<JsonValue>& propsJson, bool& shouldShow, bool& hasShownAttr)
1961 {
1962     GetBoolValue(rootJson, dataJson, propsJson, "shown", shouldShow, hasShownAttr);
1963     bool blockValue = false;
1964     bool hasBlock = false;
1965     GetBoolValue(rootJson, BLOCK_VALUE, blockValue, hasBlock);
1966     if (hasBlock) {
1967         shouldShow = shouldShow && blockValue;
1968         hasShownAttr = true;
1969     }
1970 }
1971 
ParseVersionAndUpdateData()1972 void JsCardParser::ParseVersionAndUpdateData()
1973 {
1974     LOGI("parse version info and update data field");
1975     auto versionJson = rootBody_->GetValue("apiVersion");
1976     CHECK_NULL_VOID_NOLOG(versionJson);
1977     if (!versionJson->IsValid()) {
1978         return;
1979     }
1980     auto child = versionJson->GetChild();
1981     VersionData versionData;
1982     while (child && child->IsValid()) {
1983         if (child->IsObject()) {
1984             auto key = child->GetKey();
1985             auto value = child->IsString() ? child->GetString() : child->ToString();
1986             versionData.AddRecord(key, value);
1987         }
1988         child = child->GetNext();
1989     }
1990     auto versionPatch = versionData.GetVersionPatch();
1991     for (const auto& patchInfo : versionPatch) {
1992         auto patchJson = JsonUtil::ParseJsonString(patchInfo);
1993         if (!patchJson || !patchJson->IsValid()) {
1994             LOGW("parse version patch failed, patchInfo = %{public}s", patchInfo.c_str());
1995             continue;
1996         }
1997         auto patchItem = patchJson->GetChild();
1998         while (patchItem && patchItem->IsValid()) {
1999             auto key = patchItem->GetKey();
2000             if (dataJson_->Contains(key)) {
2001                 dataJson_->Replace(key.c_str(), patchItem);
2002             } else {
2003                 dataJson_->Put(key.c_str(), patchItem);
2004             }
2005             patchItem = patchItem->GetNext();
2006         }
2007     }
2008 }
2009 
Initialize()2010 bool JsCardParser::Initialize()
2011 {
2012     rootJson_ = rootBody_->GetValue("template");
2013     styleJson_ = rootBody_->GetValue("styles");
2014     eventJson_ = rootBody_->GetValue("actions");
2015     dataJson_ = rootBody_->GetValue("data");
2016 
2017     CHECK_NULL_RETURN_NOLOG(rootJson_, false);
2018     CHECK_NULL_RETURN_NOLOG(styleJson_, false);
2019     CHECK_NULL_RETURN_NOLOG(eventJson_, false);
2020     CHECK_NULL_RETURN_NOLOG(dataJson_, false);
2021     if (!rootJson_->IsValid() || !styleJson_->IsValid() || !eventJson_->IsValid() || !dataJson_->IsValid()) {
2022         LOGE("the json template is error");
2023         return false;
2024     }
2025 
2026     ParseVersionAndUpdateData();
2027     // repeatJson contains dataJson.
2028     repeatJson_ = JsonUtil::ParseJsonString(dataJson_->ToString());
2029     LoadMediaQueryStyle();
2030     return true;
2031 }
2032 
OnSurfaceChanged(int32_t width,int32_t height)2033 void JsCardParser::OnSurfaceChanged(int32_t width, int32_t height)
2034 {
2035     mediaQueryer_.SetSurfaceSize(width, height);
2036 }
2037 
CreateBlockNode(const OHOS::Ace::RefPtr<OHOS::Ace::Framework::JsAcePage> & page,const std::unique_ptr<JsonValue> & rootJson,int32_t parentId)2038 void JsCardParser::CreateBlockNode(const OHOS::Ace::RefPtr<OHOS::Ace::Framework::JsAcePage>& page,
2039     const std::unique_ptr<JsonValue>& rootJson, int32_t parentId)
2040 {
2041     auto blockChild = rootJson->GetValue("children");
2042     bool shouldShow = true;
2043     bool hasShownAttr = false;
2044     GetBoolValue(rootJson, "shown", shouldShow, hasShownAttr);
2045     const char* value = shouldShow ? "true" : "false";
2046     if (blockChild && blockChild->IsValid()) {
2047         auto child = blockChild->GetChild();
2048         while (child && child->IsValid()) {
2049             if (child->Contains(BLOCK_VALUE)) {
2050                 child->Replace(BLOCK_VALUE, value);
2051             } else {
2052                 child->Put(BLOCK_VALUE, value);
2053             }
2054             parsingStatus_ == ParsingStatus::UPDATE ? UpdateDomNode(page, child, parentId)
2055                                                     : CreateDomNode(page, child, parentId);
2056             child = child->GetNext();
2057         }
2058     }
2059 }
2060 
GetBoolValue(const std::unique_ptr<JsonValue> & rootJson,const std::unique_ptr<JsonValue> & dataJson,const std::unique_ptr<JsonValue> & propsJson,const std::string & key,bool & value,bool & hasAttr)2061 void JsCardParser::GetBoolValue(const std::unique_ptr<JsonValue>& rootJson, const std::unique_ptr<JsonValue>& dataJson,
2062     const std::unique_ptr<JsonValue>& propsJson, const std::string& key, bool& value, bool& hasAttr)
2063 {
2064     auto result = rootJson->GetValue(key);
2065     if (result && result->IsValid()) {
2066         if (result->IsString()) {
2067             auto strValue = result->GetString();
2068             GetShownValue(strValue, dataJson, propsJson);
2069             value = strValue == "true";
2070             hasAttr = true;
2071             return;
2072         } else if (result->IsBool()) {
2073             value = result->GetBool();
2074             hasAttr = true;
2075             return;
2076         }
2077     }
2078     hasAttr = false;
2079 }
2080 
SetColorMode(ColorMode colorMode)2081 void JsCardParser::SetColorMode(ColorMode colorMode)
2082 {
2083     LOGI("current color mode is %{public}d", colorMode);
2084     colorMode_ = colorMode;
2085     mediaQueryer_.SetColorMode(colorMode);
2086 }
2087 
2088 } // namespace OHOS::Ace::Framework
2089