• 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             fileNameList.emplace_back(file.substr(0, file.size() - (sizeof(FILE_TYPE_JSON) - 1)));
861         }
862     }
863     auto localeTag = AceApplicationInfo::GetInstance().GetLocaleTag();
864     auto priorityFileName = AceResConfig::GetLocaleFallback(localeTag, fileNameList);
865     for (const auto& fileName : priorityFileName) {
866         auto filePath = std::string(I18N_FOLDER) + fileName + std::string(FILE_TYPE_JSON);
867         std::string content;
868         if (GetAssetContentImpl(assetManager, filePath, content)) {
869             auto fileData = ParseFileData(content);
870             auto result = GetJsonValue(keys, fileData);
871             if (result && result->IsValid()) {
872                 value = result->IsString() ? result->GetString() : result->ToString();
873                 return true;
874             }
875         }
876     }
877     return false;
878 }
879 
GetPlurals(std::string & value)880 void JsCardParser::GetPlurals(std::string& value)
881 {
882     // $tc('strings.plurals', 2) --> 'strings.plurals', 2
883     auto variable = value.substr(4, value.size() - 5);
884     std::vector<std::string> splitStr;
885     StringUtils::SplitStr(variable, ",", splitStr);
886     if (splitStr.size() != 2) {
887         return;
888     }
889     if (!StartWith(splitStr[0], "'") || !EndWith(splitStr[0], "'")) {
890         return;
891     }
892     // 'strings.plurals' --> strings.plurals
893     auto tempStr = splitStr[0].substr(1, splitStr[0].size() - 2);
894     GetI18nData(tempStr);
895     auto plurals = ParseFileData(tempStr);
896     auto key = Localization::GetInstance()->PluralRulesFormat(StringUtils::StringToDouble(splitStr[1]));
897     if (plurals->IsValid() && plurals->Contains(key)) {
898         value = plurals->GetValue(key)->GetString();
899     }
900 }
901 
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)902 void JsCardParser::ParseStyles(const std::unique_ptr<JsonValue>& rootJson, int32_t nodeId,
903     std::vector<std::pair<std::string, std::string>>& styles, const std::unique_ptr<JsonValue>& styleJson)
904 {
905     // parse class style
906     auto classList = rootJson->GetValue("classList");
907     if (classList && classList->IsValid()) {
908         auto styleList = classList->GetChild();
909         while (styleList && styleList->IsValid()) {
910             auto value = styleList->GetString();
911             if (IsVariable(value)) {
912                 ParseVariable(value);
913             }
914             std::string styleClass("." + value);
915             SelectStyle(styleClass, styleJson, styles);
916             SelectMediaQueryStyle(styleClass, styles);
917             styleList = styleList->GetNext();
918         }
919     }
920 
921     // parse id style
922     if (rootJson->Contains("id")) {
923         auto value = rootJson->GetValue("id")->GetString();
924         if (IsVariable(value)) {
925             ParseVariable(value);
926         }
927         std::string idStyle("#" + value);
928         SelectStyle(idStyle, styleJson, styles);
929         SelectMediaQueryStyle(idStyle, styles);
930     }
931 
932     // parse inline style
933     ParseInlineStyles(rootJson, styles);
934 }
935 
ParseInlineStyles(const std::unique_ptr<JsonValue> & rootJson,std::vector<std::pair<std::string,std::string>> & styles)936 void JsCardParser::ParseInlineStyles(
937     const std::unique_ptr<JsonValue>& rootJson, std::vector<std::pair<std::string, std::string>>& styles)
938 {
939     auto styleList = rootJson->GetValue("style");
940     CHECK_NULL_VOID_NOLOG(styleList);
941     if (!styleList->IsValid()) {
942         return;
943     }
944     auto style = styleList->GetChild();
945     while (style && style->IsValid()) {
946         auto key = style->GetKey();
947         auto value = style->IsString() ? style->GetString() : style->ToString();
948         if (IsVariable(value)) {
949             ParseVariable(value);
950         }
951         if (key == "fontFamily") {
952             RegisterFont(value);
953         }
954         styles.emplace_back(std::make_pair(key, value));
955         style = style->GetNext();
956     }
957 }
958 
SelectStyle(const std::string & className,const std::unique_ptr<JsonValue> & styleClass,std::vector<std::pair<std::string,std::string>> & styles)959 bool JsCardParser::SelectStyle(const std::string& className, const std::unique_ptr<JsonValue>& styleClass,
960     std::vector<std::pair<std::string, std::string>>& styles)
961 {
962     auto styleDetail = styleClass->GetValue(className);
963     CHECK_NULL_RETURN_NOLOG(styleDetail, false);
964     if (!styleDetail->IsValid()) {
965         return false;
966     }
967     auto style = styleDetail->GetChild();
968     while (style && style->IsValid()) {
969         auto key = style->GetKey();
970         auto styleValue = style->IsString() ? style->GetString() : style->ToString();
971         if (key == "fontFamily") {
972             RegisterFont(styleValue);
973         }
974         styles.emplace_back(std::make_pair(key, styleValue));
975         style = style->GetNext();
976     }
977     return true;
978 }
979 
SelectMediaQueryStyle(const std::string & styleClass,std::vector<std::pair<std::string,std::string>> & styles)980 void JsCardParser::SelectMediaQueryStyle(
981     const std::string& styleClass, std::vector<std::pair<std::string, std::string>>& styles)
982 {
983     const auto& mediaFeature = mediaQueryer_.GetMediaFeature();
984     for (const auto& iter : mediaQueryStyles_) {
985         if (mediaQueryer_.MatchCondition(iter.first, mediaFeature)) {
986             auto mediaIter = mediaQueryStyles_.find(iter.first);
987             if (mediaIter != mediaQueryStyles_.end()) {
988                 if (!SelectStyle(styleClass, mediaIter->second, styles)) {
989                     continue;
990                 }
991                 LOGI("current condition is %{public}s, style class is %{public}s", mediaIter->first.c_str(),
992                     styleClass.c_str());
993             }
994         }
995     }
996 }
997 
RegisterFont(const std::string & fontFamily)998 void JsCardParser::RegisterFont(const std::string& fontFamily)
999 {
1000     auto fontFaceValue = styleJson_->GetValue("@FONT-FACE");
1001     CHECK_NULL_VOID_NOLOG(fontFaceValue);
1002     if (!fontFaceValue->IsValid()) {
1003         return;
1004     }
1005     auto fontFace = fontFaceValue->GetChild();
1006     while (fontFace && fontFace->IsValid()) {
1007         if (fontFace->GetValue("fontFamily")->GetString() == fontFamily) {
1008             auto fontSrc = fontFace->GetValue("src")->GetString();
1009             if (fontSrc.size() > 7) {
1010                 // url("src") --> src
1011                 fontSrc = fontSrc.substr(5, fontSrc.size() - 7);
1012                 auto context = context_.Upgrade();
1013                 if (context) {
1014                     context->RegisterFont(fontFamily, fontSrc);
1015                     return;
1016                 }
1017             }
1018         }
1019         fontFace = fontFace->GetNext();
1020     }
1021 }
1022 
PreUpdateMethodToAction(const std::unique_ptr<JsonValue> & rootJson)1023 void JsCardParser::PreUpdateMethodToAction(const std::unique_ptr<JsonValue>& rootJson)
1024 {
1025     auto eventList = rootJson->GetValue("events");
1026     CHECK_NULL_VOID_NOLOG(eventList);
1027     if (!eventList->IsValid()) {
1028         return;
1029     }
1030     auto event = eventList->GetChild();
1031     while (event && event->IsValid()) {
1032         auto key = event->GetKey();
1033         auto value = event->GetString();
1034         auto actionJson = eventJson_->GetValue(value);
1035         auto eventAction = actionJson->ToString();
1036         methodToAction_[key] = eventAction;
1037         event = event->GetNext();
1038     }
1039 }
1040 
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)1041 void JsCardParser::ParseEvents(const std::unique_ptr<JsonValue>& rootJson, const std::unique_ptr<JsonValue>& eventJson,
1042     std::vector<std::string>& events, const RefPtr<Framework::JsAcePage>& page, int32_t nodeId)
1043 {
1044     LOGD("ParseEvents json:%{public}s", eventJson->ToString().c_str());
1045     auto eventList = rootJson->GetValue("events");
1046     CHECK_NULL_VOID_NOLOG(eventList);
1047     if (!eventList->IsValid()) {
1048         return;
1049     }
1050     auto event = eventList->GetChild();
1051     while (event && event->IsValid()) {
1052         auto key = event->GetKey();
1053         auto value = event->GetString();
1054         events.emplace_back(key);
1055         auto actionJson = eventJson->GetValue(value);
1056         auto eventAction = GetEventAction(actionJson->ToString(), key, nodeId);
1057         if (actionJson->Contains("action") && actionJson->GetString("action") == "proxy") {
1058             auto linkedEventKey = actionJson->GetString("method");
1059             eventAction = methodToAction_[linkedEventKey];
1060             eventJson_->Put(value.c_str(), JsonUtil::ParseJsonString(eventAction));
1061         }
1062         if (!key.empty() && !eventAction.empty()) {
1063             page->AddNodeEvent(nodeId, key, eventAction);
1064         }
1065         event = event->GetNext();
1066     }
1067 }
1068 
GetEventAction(const std::string & action,const std::string & actionType,int32_t nodeId)1069 std::string JsCardParser::GetEventAction(const std::string& action, const std::string& actionType, int32_t nodeId)
1070 {
1071     auto actionDetail = JsonUtil::ParseJsonString(action);
1072     CHECK_NULL_RETURN(actionDetail, "");
1073     if (!actionDetail->IsValid()) {
1074         LOGE("GetEventAction: action detail is invalid");
1075         return "";
1076     }
1077     ReplaceParam(actionDetail);
1078     return actionDetail->ToString();
1079 }
1080 
ReplaceParam(const std::unique_ptr<JsonValue> & node)1081 void JsCardParser::ReplaceParam(const std::unique_ptr<JsonValue>& node)
1082 {
1083     auto child = node->GetChild();
1084     while (child && child->IsValid()) {
1085         auto key = child->GetKey();
1086         auto value = child->IsString() ? child->GetString() : child->ToString();
1087         auto oldChild = std::move(child);
1088         child = oldChild->GetNext();
1089 
1090         if (IsVariable(value)) {
1091             ParseVariable(value);
1092             node->Replace(key.c_str(), value.c_str());
1093         } else if (IsJsonArray(value)) {
1094             auto strVec = GetVecFromArrStr(value);
1095             for (auto iter = strVec.begin(); iter != strVec.end(); ++iter) {
1096                 if (IsVariable(*iter)) {
1097                     ParseVariable(*iter);
1098                 }
1099             }
1100             value = GetArrStrFromVec(strVec);
1101             node->Replace(key.c_str(), value.c_str());
1102         } else if (IsJsonObject(value)) {
1103             ReplaceParam(oldChild);
1104             node->Replace(key.c_str(), oldChild);
1105         }
1106     }
1107 }
1108 
LoadMediaQueryStyle()1109 void JsCardParser::LoadMediaQueryStyle()
1110 {
1111     auto media = styleJson_->GetValue("@MEDIA");
1112     CHECK_NULL_VOID_NOLOG(media);
1113     if (!media->IsValid()) {
1114         return;
1115     }
1116     static const std::string CONDITION_KEY = "condition";
1117     auto mediaChild = media->GetChild();
1118     while (mediaChild && mediaChild->IsValid()) {
1119         auto condition = mediaChild->GetString(CONDITION_KEY, "");
1120         if (condition.empty()) {
1121             mediaChild = mediaChild->GetNext();
1122             continue;
1123         }
1124 
1125         // record media query style
1126         std::unique_ptr<JsonValue> mediaQueryStyle;
1127         auto iter = mediaQueryStyles_.find(condition);
1128         if (iter != mediaQueryStyles_.end()) {
1129             // already exist same media condition
1130             mediaQueryStyle = std::move(iter->second);
1131         } else {
1132             mediaQueryStyle = JsonUtil::Create(true);
1133         }
1134         auto child = mediaChild->GetChild();
1135         while (child && child->IsValid()) {
1136             if (child->GetKey() != CONDITION_KEY) {
1137                 mediaQueryStyle->Put(child->GetKey().c_str(), child);
1138             }
1139             child = child->GetNext();
1140         }
1141 
1142         mediaQueryStyles_[condition] = std::move(mediaQueryStyle);
1143         mediaChild = mediaChild->GetNext();
1144     }
1145 }
1146 
GetResourceValue(const std::string & path)1147 void JsCardParser::GetResourceValue(const std::string& path)
1148 {
1149     auto assetManager = assetManager_.Upgrade();
1150     CHECK_NULL_VOID_NOLOG(assetManager);
1151     std::string content;
1152     if (GetAssetContentImpl(assetManager, path, content) && !content.empty()) {
1153         auto jsonBody = ParseFileData(content);
1154         resourceJson_->Put(path.c_str(), jsonBody);
1155     }
1156 }
1157 
LoadImageInfo()1158 void JsCardParser::LoadImageInfo()
1159 {
1160     resourceJson_ = JsonUtil::Create(true);
1161 
1162     std::string path = std::string(RESOURCES_FOLDER) + std::string(DEFAULTS_RESOURCES_JSON_FILE);
1163     GetResourceValue(path);
1164     path = std::string(RESOURCES_FOLDER) + "res-" + GetDeviceDpi(density_) + std::string(FILE_TYPE_JSON);
1165     GetResourceValue(path);
1166     path = std::string(RESOURCES_FOLDER) + "res-" + "dark-defaults" + std::string(FILE_TYPE_JSON);
1167     GetResourceValue(path);
1168     path = std::string(RESOURCES_FOLDER) + "res-" + "dark-" + GetDeviceDpi(density_) + std::string(FILE_TYPE_JSON);
1169     GetResourceValue(path);
1170 }
1171 
UpdatePageData(const std::string & dataList,const RefPtr<JsAcePage> & page)1172 void JsCardParser::UpdatePageData(const std::string& dataList, const RefPtr<JsAcePage>& page)
1173 {
1174     LOGI("update data is %{private}s card hap path %{public}s", dataList.c_str(), cardHapPath_.c_str());
1175     CHECK_NULL_VOID(page);
1176     if (dataList.empty()) {
1177         LOGE("update data is null");
1178         return;
1179     }
1180     const auto& rootData = JsonUtil::ParseJsonString(dataList);
1181     CHECK_NULL_VOID_NOLOG(rootData);
1182     if (!rootData->IsValid()) {
1183         return;
1184     }
1185     auto data = rootData->GetChild();
1186     CHECK_NULL_VOID(data);
1187     if (!data->IsValid()) {
1188         LOGE("update card data error");
1189         return;
1190     }
1191     while (data && data->IsValid()) {
1192         auto key = data->GetKey();
1193         dataJson_->Replace(key.c_str(), data);
1194         repeatJson_->Replace(key.c_str(), data);
1195         data = data->GetNext();
1196     }
1197     SetUpdateStatus(page);
1198 }
1199 
UpdateStyle(const RefPtr<JsAcePage> & page)1200 void JsCardParser::UpdateStyle(const RefPtr<JsAcePage>& page)
1201 {
1202     CHECK_NULL_VOID(page);
1203     SetUpdateStatus(page);
1204 }
1205 
ParseComplexExpression(std::string & value,const std::unique_ptr<JsonValue> & json)1206 bool JsCardParser::ParseComplexExpression(std::string& value, const std::unique_ptr<JsonValue>& json)
1207 {
1208     if (value.find('[') == std::string::npos && value.find('.') == std::string::npos) {
1209         return false;
1210     }
1211     std::stack<std::string> keyStack;
1212     auto key = value;
1213     if (!ParseArrayExpression(key, keyStack, json) || keyStack.size() != 1) {
1214         return false;
1215     }
1216     auto result = keyStack.top();
1217     keyStack.pop();
1218     value = result;
1219     return true;
1220 }
1221 
ParseArrayExpression(const std::string & expression,std::stack<std::string> & keyStack,const std::unique_ptr<JsonValue> & json)1222 bool JsCardParser::ParseArrayExpression(
1223     const std::string& expression, std::stack<std::string>& keyStack, const std::unique_ptr<JsonValue>& json)
1224 {
1225     auto dataJson = isRepeat_ ? repeatJson_->ToString() : json->ToString();
1226     auto dataValue = JsonUtil::ParseJsonString(dataJson);
1227     std::string tmpKey;
1228     for (char i : expression) {
1229         switch (i) {
1230             case '[':
1231                 if (tmpKey.empty()) {
1232                     return false;
1233                 }
1234                 if (!ParsePointOperator(tmpKey, keyStack, dataJson)) {
1235                     return false;
1236                 }
1237                 tmpKey.clear();
1238                 break;
1239             case ']':
1240                 if (StringUtils::IsNumber(tmpKey)) {
1241                     if (!GetIndexValue(tmpKey, keyStack)) {
1242                         return false;
1243                     }
1244                 } else if (tmpKey.empty() && keyStack.size() >= 2) {
1245                     auto topValue = keyStack.top();
1246                     keyStack.pop();
1247                     if (!GetStrValue(topValue, keyStack) && !GetIndexValue(topValue, keyStack)) {
1248                         return false;
1249                     }
1250                 } else if (!tmpKey.empty() && dataValue->Contains(tmpKey)) {
1251                     auto data = dataValue->GetValue(tmpKey);
1252                     auto dataStr = data->IsString() ? data->GetString() : data->ToString();
1253                     if (!GetStrValue(dataStr, keyStack) && !GetIndexValue(dataStr, keyStack)) {
1254                         return false;
1255                     }
1256                 } else if (tmpKey.find('.') != std::string::npos) {
1257                     std::vector<std::string> keys;
1258                     StringUtils::StringSplitter(tmpKey, '.', keys);
1259                     auto jsonValue = GetJsonValue(keys, dataValue);
1260                     if (jsonValue && jsonValue->IsValid()) {
1261                         auto result = jsonValue->IsString() ? jsonValue->GetString() : jsonValue->ToString();
1262                         if (!GetStrValue(result, keyStack) && !GetIndexValue(result, keyStack)) {
1263                             return false;
1264                         }
1265                     }
1266                 } else {
1267                     return false;
1268                 }
1269                 tmpKey.clear();
1270                 break;
1271             default: {
1272                 tmpKey += i;
1273                 break;
1274             }
1275         }
1276     }
1277     if (!tmpKey.empty()) {
1278         return ParsePointOperator(tmpKey, keyStack, dataJson);
1279     }
1280     return true;
1281 }
1282 
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)1283 void JsCardParser::UpdateDomNode(const RefPtr<Framework::JsAcePage>& page, const std::unique_ptr<JsonValue>& rootJson,
1284     int32_t parentId, const std::vector<int>& idArray, const std::unique_ptr<JsonValue>& dataJson,
1285     const std::unique_ptr<JsonValue>& styleJson, const std::unique_ptr<JsonValue>& propsJson)
1286 {
1287     LOGD("UpdateDomNode root json: %{public}s", rootJson->ToString().c_str());
1288     CHECK_NULL_VOID(page);
1289     if (!rootJson->IsValid()) {
1290         LOGE("fail to UpdateDomNode due to page or root is invalid");
1291         return;
1292     }
1293     if (rootJson->Contains("repeat") && !isRepeat_) {
1294         CreateRepeatDomNode(page, rootJson, parentId);
1295         return;
1296     }
1297     auto type = rootJson->GetString("type");
1298     if (type == "block") {
1299         CreateBlockNode(page, rootJson, parentId);
1300         return;
1301     }
1302     int32_t selfId = 0;
1303     if (!isRepeat_) {
1304         selfId = parentId < 0 ? DOM_ROOT_NODE_ID_BASE : nodeId_;
1305         ++nodeId_;
1306     } else {
1307         if (listNodeIndex_ < static_cast<int32_t>(idArray.size())) {
1308             selfId = idArray[listNodeIndex_];
1309             ++listNodeIndex_;
1310         }
1311     }
1312     bool shouldShow = true;
1313     bool hasShownAttr = false;
1314     GetShownAttr(rootJson, dataJson, propsJson, shouldShow, hasShownAttr);
1315     type = rootJson->GetValue("type")->GetString();
1316     if (rootBody_->Contains(type)) {
1317         // if rootBody contains this type, it must be a customer component.
1318         auto customJson = rootBody_->GetValue(type);
1319         auto customJsonTemplate = customJson->GetValue("template");
1320         auto customJsonData = customJson->GetValue("data");
1321         auto customJsonProps = customJson->GetValue("props");
1322         auto customJsonStyle = customJson->GetValue("styles");
1323         auto attrList = rootJson->GetValue("attr");
1324         CHECK_NULL_VOID_NOLOG(attrList);
1325         if (!attrList->IsValid()) {
1326             return;
1327         }
1328         auto attr = attrList->GetChild();
1329         while (attr && attr->IsValid()) {
1330             auto key = attr->GetKey();
1331             auto value = attr->IsString() ? attr->GetString() : attr->ToString();
1332             UpdateProps(key, value, customJsonProps);
1333             attr = attr->GetNext();
1334         }
1335         ParseStyles(rootJson, selfId, customStyles_, styleJson);
1336         UpdateDomNode(page, customJsonTemplate, parentId, idArray, customJsonData, customJsonStyle, customJsonProps);
1337         return;
1338     }
1339     std::vector<std::pair<std::string, std::string>> attrs;
1340     std::vector<std::pair<std::string, std::string>> styles(customStyles_);
1341     customStyles_.clear();
1342     std::vector<std::string> events;
1343     auto styleCommand = Referenced::MakeRefPtr<JsCommandUpdateDomElementStyles>(selfId);
1344     auto attrCommand = Referenced::MakeRefPtr<JsCommandUpdateDomElementAttrs>(selfId);
1345     auto ptr = Referenced::RawPtr(attrCommand);
1346     if (shouldShow && hasShownAttr) {
1347         attrs.emplace_back(std::make_pair("show", TRUE));
1348     }
1349     ParseAttributes(rootJson, selfId, attrs, static_cast<JsCommandDomElementOperator*>(ptr), dataJson, propsJson);
1350     if (!shouldShow && hasShownAttr) {
1351         attrs.emplace_back(std::make_pair("show", FALSE));
1352     }
1353     ParseStyles(rootJson, selfId, styles, styleJson);
1354     ParseEvents(rootJson, events, page, selfId);
1355     attrCommand->SetAttributes(std::move(attrs));
1356     styleCommand->SetStyles(std::move(styles));
1357     page->PushCommand(attrCommand);
1358     page->PushCommand(styleCommand);
1359 
1360     auto childList = rootJson->GetValue("children");
1361     if (childList && childList->IsValid()) {
1362         auto child = childList->GetChild();
1363         while (child && child->IsValid()) {
1364             UpdateDomNode(page, child, selfId, idArray, dataJson, styleJson, propsJson);
1365             child = child->GetNext();
1366         }
1367     }
1368 }
1369 
ParseVariable(std::string & value,const std::unique_ptr<JsonValue> & dataJson,const std::unique_ptr<JsonValue> & propsJson)1370 void JsCardParser::ParseVariable(
1371     std::string& value, const std::unique_ptr<JsonValue>& dataJson, const std::unique_ptr<JsonValue>& propsJson)
1372 {
1373     // {{value}} --> value
1374     auto variable = value.substr(2, value.size() - 4);
1375     if (GetAndParseProps(variable, propsJson) || ParseComplexExpression(variable, dataJson) ||
1376         GetVariable(variable, dataJson) || ParseSpecialVariable(variable) ||
1377         ParseTernaryExpression(variable, propsJson) || ParseLogicalExpression(variable, propsJson)) {
1378         value = variable;
1379 
1380         if (IsVariable(value)) {
1381             ParseVariable(value, dataJson, propsJson);
1382         }
1383     }
1384 }
1385 
ParseMultiVariable(std::string & value,const std::unique_ptr<JsonValue> & dataJson,const std::unique_ptr<JsonValue> & propsJson)1386 void JsCardParser::ParseMultiVariable(
1387     std::string& value, const std::unique_ptr<JsonValue>& dataJson, const std::unique_ptr<JsonValue>& propsJson)
1388 {
1389     if (value.size() < 4) {
1390         return;
1391     }
1392     // $f({{key1}} {{key2}}) --> {{key1}} {{key2}}
1393     auto variable = value.substr(3, value.size() - 4);
1394 
1395     value = "";
1396     // Splicing Between Variables and constants,like variable = "my name is {{name}}, and i am from {{city}}."
1397     while (variable.find("{{") != std::string::npos && variable.find("}}") != std::string::npos) {
1398         auto startPos = variable.find("{{");
1399         auto endPos = variable.find("}}");
1400         if (endPos < startPos) {
1401             break;
1402         }
1403         // var = {{name}}, after parsing, var = "tom".
1404         std::string var = variable.substr(startPos, endPos - startPos + 2);
1405         ParseVariable(var, dataJson, propsJson);
1406 
1407         // after parsing, value = "my name is tom".
1408         value += variable.substr(0, startPos) + var;
1409 
1410         // variable = ", and i am from {{city}}."
1411         variable = variable.substr(endPos + 2, variable.size() - endPos - 2);
1412     }
1413     value += variable;
1414 }
1415 
ParseTernaryExpression(std::string & value,const std::unique_ptr<JsonValue> & propsJson)1416 bool JsCardParser::ParseTernaryExpression(std::string& value, const std::unique_ptr<JsonValue>& propsJson)
1417 {
1418     if (value.find('?') == std::string::npos || value.find(':') == std::string::npos) {
1419         return false;
1420     }
1421     // eg:{{flag ? key1 : key2}}, flagStr[0] = "flag", flagStr[1] = "key1 : key2".
1422     std::vector<std::string> flagStr;
1423     StringUtils::SplitStr(value, "?", flagStr);
1424     if (flagStr.size() != 2) {
1425         return false;
1426     }
1427     bool flag = false;
1428     if (GetAndParseProps(flagStr[0], propsJson) || GetVariable(flagStr[0])) {
1429         flag = flagStr[0] == TRUE;
1430     }
1431 
1432     std::vector<std::string> keyStr;
1433     StringUtils::SplitStr(flagStr[1], ":", keyStr);
1434     if (keyStr.size() != 2) {
1435         return false;
1436     }
1437     for (auto& key : keyStr) {
1438         if (StartWith(key, "\'") && EndWith(key, "\'")) {
1439             key = key.substr(1, key.size() - 2);
1440         }
1441         if (StartWith(key, "\"") && EndWith(key, "\"")) {
1442             key = key.substr(1, key.size() - 2);
1443         }
1444     }
1445 
1446     // parse key1 and key2.
1447     GetVariable(keyStr[0]);
1448     GetVariable(keyStr[1]);
1449     value = flag ? keyStr[0] : keyStr[1];
1450     return true;
1451 }
1452 
ParseLogicalExpression(std::string & value,const std::unique_ptr<JsonValue> & propsJson)1453 bool JsCardParser::ParseLogicalExpression(std::string& value, const std::unique_ptr<JsonValue>& propsJson)
1454 {
1455     std::vector<std::string> splitStr;
1456     if (value.find("&&") != std::string::npos) {
1457         // for {{flag1 && flag2}}.
1458         StringUtils::SplitStr(value, "&&", splitStr);
1459         if (splitStr.size() != 2) {
1460             return false;
1461         }
1462         if ((GetAndParseProps(splitStr[0], propsJson) || GetVariable(splitStr[0])) &&
1463             (GetAndParseProps(splitStr[1], propsJson) || GetVariable(splitStr[1]))) {
1464             value = (splitStr[0] == TRUE && splitStr[1] == TRUE) ? TRUE : FALSE;
1465             return true;
1466         }
1467     } else if (value.find("||") != std::string::npos) {
1468         // for {{flag1 || flag2}}.
1469         StringUtils::SplitStr(value, "||", splitStr);
1470         if (splitStr.size() != 2) {
1471             return false;
1472         }
1473         if ((GetAndParseProps(splitStr[0], propsJson) || GetVariable(splitStr[0])) &&
1474             (GetAndParseProps(splitStr[1], propsJson) || GetVariable(splitStr[1]))) {
1475             value = (splitStr[0] == TRUE || splitStr[1] == TRUE) ? TRUE : FALSE;
1476             return true;
1477         }
1478     } else if (value.find('!') != std::string::npos) {
1479         // for {{!flag1}}.
1480         StringUtils::SplitStr(value, "!", splitStr);
1481         if (splitStr.size() != 1) {
1482             return false;
1483         }
1484         if (GetAndParseProps(splitStr[0], propsJson) || GetVariable(splitStr[0])) {
1485             value = splitStr[0] == TRUE ? FALSE : TRUE;
1486             return true;
1487         }
1488     }
1489     return false;
1490 }
1491 
GetAndParseProps(std::string & value,const std::unique_ptr<JsonValue> & propsJson)1492 bool JsCardParser::GetAndParseProps(std::string& value, const std::unique_ptr<JsonValue>& propsJson)
1493 {
1494     CHECK_NULL_RETURN_NOLOG(propsJson, false);
1495     if (ParsePropsArray(value, propsJson) || ParsePropsVariable(value, propsJson)) {
1496         return true;
1497     }
1498     return false;
1499 }
1500 
ParsePropsVariable(std::string & value,const std::unique_ptr<JsonValue> & propsJson)1501 bool JsCardParser::ParsePropsVariable(std::string& value, const std::unique_ptr<JsonValue>& propsJson)
1502 {
1503     auto propsObject = propsJson->GetValue(value);
1504     CHECK_NULL_RETURN(propsObject, false);
1505     if (!propsObject->IsValid()) {
1506         LOGI("GetAndParseProps propsObject is empty or propsObject->IsValid()");
1507         return false;
1508     }
1509     auto propValueJson = propsObject->GetValue("value");
1510     auto defaultJson = propsObject->GetValue("default");
1511     if (propValueJson && propValueJson->IsValid()) {
1512         value = propValueJson->IsString() ? propValueJson->GetString() : propValueJson->ToString();
1513     } else {
1514         // no need to check valid, the json will recover from error state
1515         value = defaultJson->IsString() ? defaultJson->GetString() : defaultJson->ToString();
1516     }
1517     // after user use current value in json, need to reset back to default
1518 
1519     propsObject->Replace(
1520         "value", defaultJson->IsString() ? defaultJson->GetString().c_str() : defaultJson->ToString().c_str());
1521     return true;
1522 }
1523 
GetArrayItemSubstring(const std::string & s)1524 std::string GetArrayItemSubstring(const std::string& s)
1525 {
1526     std::string result;
1527     auto endIndex = s.find("[");
1528     if (endIndex != std::string::npos) {
1529         result = s.substr(0, endIndex);
1530     }
1531     return result;
1532 }
1533 
ParsePropsArray(std::string & value,const std::unique_ptr<JsonValue> & propsJson)1534 bool JsCardParser::ParsePropsArray(std::string& value, const std::unique_ptr<JsonValue>& propsJson)
1535 {
1536     const auto arrayParam = GetArrayItemSubstring(value);
1537     if (arrayParam.empty()) {
1538         return false;
1539     }
1540     auto propsObject = propsJson->GetValue(arrayParam);
1541     CHECK_NULL_RETURN(propsObject, false);
1542     if (!propsObject->IsValid()) {
1543         LOGI("GetAndParseProps propsObject is empty or propsObject->IsValid()");
1544         return false;
1545     }
1546     auto propValueJson = propsObject->GetValue("value");
1547     auto defaultJson = propsObject->GetValue("default");
1548     auto arrayPropJson = JsonUtil::Create(true);
1549     if (propValueJson && propValueJson->IsValid()) {
1550         arrayPropJson->Put(arrayParam.c_str(), propValueJson);
1551     } else {
1552         arrayPropJson->Put(arrayParam.c_str(), defaultJson);
1553     }
1554 
1555     if (ParseComplexExpression(value, arrayPropJson)) {
1556         // after user use current value in json, need to reset back to default
1557         propsObject->Replace(
1558             "value", defaultJson->IsString() ? defaultJson->GetString().c_str() : defaultJson->ToString().c_str());
1559         return true;
1560     }
1561     return false;
1562 }
1563 
ParseSpecialVariable(std::string & value)1564 bool JsCardParser::ParseSpecialVariable(std::string& value)
1565 {
1566     if (StartWith(value, "$r('") && EndWith(value, "')")) {
1567         GetResImageUrl(value);
1568         return true;
1569     } else if (StartWith(value, "$t('") && EndWith(value, "')")) {
1570         // $t('value') --> value
1571         value = value.substr(4, value.size() - 6);
1572         auto result = GetI18nData(value);
1573         LOGI("Get i18n data is %{public}s, card hap path %{public}s", value.c_str(), cardHapPath_.c_str());
1574         return result;
1575     } else if (StartWith(value, "$tc(") && EndWith(value, ")")) {
1576         GetPlurals(value);
1577         return true;
1578     }
1579     return false;
1580 }
1581 
GetVariable(std::string & value,const std::unique_ptr<JsonValue> & dataJson)1582 bool JsCardParser::GetVariable(std::string& value, const std::unique_ptr<JsonValue>& dataJson)
1583 {
1584     auto key = value;
1585     if (!repeatJson_->Contains(key) && isRepeat_) {
1586         return false;
1587     }
1588 
1589     CHECK_NULL_RETURN(dataJson, false);
1590     LOGD("GetVariable value :%{private}s dataJson:%{private}s", value.c_str(), dataJson->ToString().c_str());
1591     auto dataValue = dataJson->GetValue(key);
1592     if (isRepeat_) {
1593         dataValue = repeatJson_->GetValue(key);
1594     }
1595     CHECK_NULL_RETURN_NOLOG(dataValue, false);
1596     if (!dataValue->IsValid()) {
1597         return false;
1598     }
1599     value = dataValue->IsString() ? dataValue->GetString() : dataValue->ToString();
1600     if (IsVariable(value)) {
1601         ParseVariable(value, dataJson);
1602     }
1603     LOGD("return value :%{private}s", value.c_str());
1604     return true;
1605 }
1606 
1607 template<typename T>
ParseSpecialAttr(const std::function<void (const std::unique_ptr<JsonValue> &,std::vector<T> &)> & function,std::string & value,std::vector<T> & vector)1608 void JsCardParser::ParseSpecialAttr(
1609     const std::function<void(const std::unique_ptr<JsonValue>&, std::vector<T>&)>& function, std::string& value,
1610     std::vector<T>& vector)
1611 {
1612     if (IsVariable(value)) {
1613         ParseVariable(value);
1614         auto jsonValue = JsonUtil::ParseJsonString(value);
1615         function(jsonValue, vector);
1616     } else {
1617         auto jsonValue = JsonUtil::ParseJsonString(value);
1618         function(jsonValue, vector);
1619     }
1620 }
1621 
1622 template<typename T>
ParseSpecialAttr(const std::function<void (const std::unique_ptr<JsonValue> &,T &)> & function,std::string & variable,T & value)1623 void JsCardParser::ParseSpecialAttr(
1624     const std::function<void(const std::unique_ptr<JsonValue>&, T&)>& function, std::string& variable, T& value)
1625 {
1626     if (IsVariable(variable)) {
1627         ParseVariable(variable);
1628         auto jsonValue = JsonUtil::ParseJsonString(variable);
1629         function(jsonValue, value);
1630     } else {
1631         auto jsonValue = JsonUtil::ParseJsonString(variable);
1632         function(jsonValue, value);
1633     }
1634 }
1635 
ParsePointOperator(const std::string & tmpKey,std::stack<std::string> & keyStack,const std::string & dataJson)1636 bool JsCardParser::ParsePointOperator(
1637     const std::string& tmpKey, std::stack<std::string>& keyStack, const std::string& dataJson)
1638 {
1639     std::unique_ptr<JsonValue> data;
1640     if (tmpKey[0] == '.') {
1641         if (keyStack.empty()) {
1642             return false;
1643         }
1644         data = JsonUtil::ParseJsonString(keyStack.top());
1645         keyStack.pop();
1646     } else {
1647         data = JsonUtil::ParseJsonString(dataJson);
1648     }
1649     std::vector<std::string> keys;
1650     StringUtils::StringSplitter(tmpKey, '.', keys);
1651     auto result = GetJsonValue(keys, data);
1652     if (result && result->IsValid()) {
1653         auto dataStr = result->IsString() ? result->GetString() : result->ToString();
1654         keyStack.emplace(dataStr);
1655         return true;
1656     }
1657     return false;
1658 }
1659 
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)1660 void JsCardParser::CreateDomNode(const RefPtr<Framework::JsAcePage>& page, const std::unique_ptr<JsonValue>& rootJson,
1661     int32_t parentId, const std::unique_ptr<JsonValue>& dataJson, const std::unique_ptr<JsonValue>& actionJson,
1662     const std::unique_ptr<JsonValue>& styleJson, const std::unique_ptr<JsonValue>& propsJson, bool isNewNode)
1663 {
1664     CHECK_NULL_VOID(page);
1665     if (!rootJson->IsValid()) {
1666         LOGE("fail to CreateDomNode due to page or root is invalid");
1667         EventReport::SendFormException(FormExcepType::CREATE_NODE_ERR);
1668         return;
1669     }
1670     if (rootJson->Contains("repeat") && !isRepeat_) {
1671         CreateRepeatDomNode(page, rootJson, parentId);
1672         return;
1673     }
1674     auto type = rootJson->GetString("type");
1675     if (type == "block") {
1676         CreateBlockNode(page, rootJson, parentId);
1677         return;
1678     }
1679     int32_t nodeId = 0;
1680     if (!isNewNode) {
1681         nodeId = parentId < 0 ? DOM_ROOT_NODE_ID_BASE : nodeId_;
1682         ++nodeId_;
1683     } else {
1684         nodeId = maxNodeId_++;
1685     }
1686     if (isRepeat_) {
1687         idArray_.emplace_back(nodeId);
1688     }
1689     bool shouldShow = true;
1690     bool hasShownAttr = false;
1691     GetShownAttr(rootJson, dataJson, propsJson, shouldShow, hasShownAttr);
1692     type = rootJson->GetValue("type")->GetString();
1693     if (rootBody_->Contains(type)) {
1694         // if rootBody contains this type, it must be a customer component.
1695         auto customJson = rootBody_->GetValue(type);
1696         auto customJsonTemplate = customJson->GetValue("template");
1697         auto customJsonData = customJson->GetValue("data");
1698         auto customJsonProps = customJson->GetValue("props");
1699         auto customJsonActions = customJson->GetValue("actions");
1700         auto customJsonStyle = customJson->GetValue("styles");
1701         auto attrList = rootJson->GetValue("attr");
1702         CHECK_NULL_VOID_NOLOG(attrList);
1703         if (!attrList->IsValid()) {
1704             return;
1705         }
1706         auto attr = attrList->GetChild();
1707         while (attr && attr->IsValid()) {
1708             auto key = attr->GetKey();
1709             auto value = attr->IsString() ? attr->GetString() : attr->ToString();
1710             UpdateProps(key, value, customJsonProps);
1711             attr = attr->GetNext();
1712         }
1713         ParseStyles(rootJson, nodeId, customStyles_, styleJson);
1714         PreUpdateMethodToAction(rootJson);
1715         CreateDomNode(page, customJsonTemplate, parentId, customJsonData, customJsonActions, customJsonStyle,
1716             customJsonProps, isNewNode);
1717         return;
1718     }
1719     std::vector<std::pair<std::string, std::string>> attrs;
1720     std::vector<std::pair<std::string, std::string>> styles(customStyles_);
1721     customStyles_.clear();
1722     std::vector<std::string> events;
1723     RefPtr<Framework::JsCommandDomElementCreator> command;
1724     if (parentId < 0) {
1725         command = Referenced::MakeRefPtr<Framework::JsCommandCreateDomBody>(type, nodeId);
1726     } else {
1727         command = Referenced::MakeRefPtr<Framework::JsCommandAddDomElement>(type, nodeId, parentId);
1728     }
1729     command->SetPipelineContext(AceType::DynamicCast<PipelineContext>(context_));
1730     auto ptr = Referenced::RawPtr(command);
1731     if (shouldShow && hasShownAttr) {
1732         attrs.emplace_back(std::make_pair("show", TRUE));
1733     }
1734     ParseAttributes(rootJson, nodeId, attrs, (Framework::JsCommandDomElementOperator*)ptr, dataJson, propsJson);
1735     if (!shouldShow && hasShownAttr) {
1736         attrs.emplace_back(std::make_pair("show", FALSE));
1737     }
1738     ParseStyles(rootJson, nodeId, styles, styleJson);
1739     ParseEvents(rootJson, actionJson, events, page, nodeId);
1740     command->SetAttributes(std::move(attrs));
1741     command->SetStyles(std::move(styles));
1742     command->AddEvents(std::move(events));
1743     page->PushCommand(command);
1744 
1745     auto childList = rootJson->GetValue("children");
1746     if (childList && childList->IsValid()) {
1747         auto child = childList->GetChild();
1748         while (child && child->IsValid()) {
1749             CreateDomNode(page, child, nodeId, dataJson, actionJson, styleJson, propsJson, isNewNode);
1750             child = child->GetNext();
1751         }
1752     }
1753 }
1754 
CreateRepeatDomNode(const RefPtr<Framework::JsAcePage> & page,const std::unique_ptr<JsonValue> & rootJson,int32_t parentId)1755 void JsCardParser::CreateRepeatDomNode(
1756     const RefPtr<Framework::JsAcePage>& page, const std::unique_ptr<JsonValue>& rootJson, int32_t parentId)
1757 {
1758     auto repeatValue = rootJson->GetValue("repeat");
1759     CHECK_NULL_VOID(repeatValue);
1760     if (!repeatValue->IsValid()) {
1761         LOGE("CreateRepeatDomNode failed, repeat value is invalid.");
1762         return;
1763     }
1764     isRepeat_ = true;
1765     std::string key;
1766     if (repeatValue->IsString()) {
1767         // eg: repeatValue = {{list}}.
1768         if (!GetRepeatData(repeatValue, key)) {
1769             LOGE("CreateRepeatDomNode failed, root data does not contains repeat value.");
1770             isRepeat_ = false;
1771             return;
1772         }
1773         ProcessRepeatNode(page, rootJson, key, parentId, false, repeatValue);
1774     } else {
1775         // eg: repeatValue = {"exp": {{list}}, "key":"index", "value": "item"}.
1776         if (!repeatValue->Contains("exp")) {
1777             LOGE("CreateRepeatDomNode failed, repeat value does not contains exp.");
1778             isRepeat_ = false;
1779             return;
1780         }
1781         auto expValue = repeatValue->GetValue("exp");
1782         if (!GetRepeatData(expValue, key)) {
1783             LOGE("CreateRepeatDomNode failed, root data does not contains exp value.");
1784             isRepeat_ = false;
1785             return;
1786         }
1787         ParseRepeatIndexItem(repeatValue);
1788         ProcessRepeatNode(page, rootJson, key, parentId, true, expValue);
1789         ResetRepeatIndexItem();
1790     }
1791     isRepeat_ = false;
1792 }
1793 
GetClockConfig(const std::unique_ptr<JsonValue> & jsonDataSets,ClockConfig & clockConfig)1794 void JsCardParser::GetClockConfig(const std::unique_ptr<JsonValue>& jsonDataSets, ClockConfig& clockConfig)
1795 {
1796     CHECK_NULL_VOID_NOLOG(jsonDataSets);
1797     if (!jsonDataSets->IsValid()) {
1798         return;
1799     }
1800     auto data = jsonDataSets->GetChild();
1801     while (data && data->IsValid()) {
1802         auto key = data->GetKey();
1803         auto valStr = data->IsString() ? data->GetString() : data->ToString();
1804         static const LinearMapNode<void (*)(std::string&, ClockConfig&, JsCardParser&)> clockConfigOperators[] = {
1805             { DOM_DIGIT_COLOR,
1806                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1807                     clockConfig.digitColor_ = valStr;
1808                 } },
1809             { DOM_DIGIT_COLOR_NIGHT,
1810                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1811                     clockConfig.digitColorNight_ = valStr;
1812                 } },
1813             { DOM_DIGIT_RADIUS_RATIO,
1814                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1815                     clockConfig.digitRadiusRatio_ = StringToDouble(valStr);
1816                 } },
1817             { DOM_DIGIT_SIZE_RATIO,
1818                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1819                     clockConfig.digitSizeRatio_ = StringToDouble(valStr);
1820                 } },
1821             { DOM_CLOCK_FACE_SOURCE,
1822                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1823                     if (IsVariable(valStr)) {
1824                         jsCardParser.ParseVariable(valStr);
1825                     }
1826                     clockConfig.clockFaceSrc_ = valStr;
1827                 } },
1828             { DOM_CLOCK_FACE_SOURCE_NIGHT,
1829                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1830                     if (IsVariable(valStr)) {
1831                         jsCardParser.ParseVariable(valStr);
1832                     }
1833                     clockConfig.clockFaceNightSrc_ = valStr;
1834                 } },
1835             { DOM_HOUR_HAND_SOURCE,
1836                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1837                     if (IsVariable(valStr)) {
1838                         jsCardParser.ParseVariable(valStr);
1839                     }
1840                     clockConfig.hourHandSrc_ = valStr;
1841                 } },
1842             { DOM_HOUR_HAND_SOURCE_NIGHT,
1843                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1844                     if (IsVariable(valStr)) {
1845                         jsCardParser.ParseVariable(valStr);
1846                     }
1847                     clockConfig.hourHandNightSrc_ = valStr;
1848                 } },
1849             { DOM_MINUTE_HAND_SOURCE,
1850                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1851                     if (IsVariable(valStr)) {
1852                         jsCardParser.ParseVariable(valStr);
1853                     }
1854                     clockConfig.minuteHandSrc_ = valStr;
1855                 } },
1856             { DOM_MINUTE_HAND_SOURCE_NIGHT,
1857                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1858                     if (IsVariable(valStr)) {
1859                         jsCardParser.ParseVariable(valStr);
1860                     }
1861                     clockConfig.minuteHandNightSrc_ = valStr;
1862                 } },
1863             { DOM_SECOND_HAND_SOURCE,
1864                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1865                     if (IsVariable(valStr)) {
1866                         jsCardParser.ParseVariable(valStr);
1867                     }
1868                     clockConfig.secondHandSrc_ = valStr;
1869                 } },
1870             { DOM_SECOND_HAND_SOURCE_NIGHT,
1871                 [](std::string& valStr, ClockConfig& clockConfig, JsCardParser& jsCardParser) {
1872                     if (IsVariable(valStr)) {
1873                         jsCardParser.ParseVariable(valStr);
1874                     }
1875                     clockConfig.secondHandNightSrc_ = valStr;
1876                 } },
1877         };
1878         auto operatorIter = BinarySearchFindIndex(clockConfigOperators, ArraySize(clockConfigOperators), key.c_str());
1879         if (operatorIter != -1) {
1880             clockConfigOperators[operatorIter].value(valStr, clockConfig, *this);
1881         } else {
1882             LOGD("key : %{public}s unsupported. Ignoring!", key.c_str());
1883         }
1884         data = data->GetNext();
1885     }
1886 }
1887 
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)1888 void JsCardParser::ProcessRepeatNode(const RefPtr<Framework::JsAcePage>& page,
1889     const std::unique_ptr<JsonValue>& rootJson, const std::string& key, int32_t parentId, bool hasKeyValue,
1890     std::unique_ptr<JsonValue>& repeatValue)
1891 {
1892     ++numberOfForNode_;
1893     if (parsingStatus_ == ParsingStatus::CREATE) {
1894         if (repeatValue->GetArraySize() == 0) {
1895             listIdMap_.emplace(numberOfForNode_, std::make_pair(idArray_, 0));
1896             singleLoopMap_.emplace(numberOfForNode_, 0);
1897             return;
1898         }
1899         for (auto i = 0; i < repeatValue->GetArraySize(); i++) {
1900             SetRepeatItemValue(i, repeatValue, hasKeyValue);
1901             CreateDomNode(page, rootJson, parentId);
1902         }
1903         // Number of nodes in a single loop
1904         auto factor = idArray_.size() / repeatValue->GetArraySize();
1905         listIdMap_.emplace(numberOfForNode_, std::make_pair(idArray_, static_cast<int32_t>(idArray_.size())));
1906         singleLoopMap_.emplace(numberOfForNode_, factor);
1907     } else if (parsingStatus_ == ParsingStatus::UPDATE) {
1908         auto iter = listIdMap_.find(numberOfForNode_);
1909         auto loopIter = singleLoopMap_.find(numberOfForNode_);
1910         if (iter == listIdMap_.end() || loopIter == singleLoopMap_.end()) {
1911             return;
1912         }
1913         auto array = iter->second.first;
1914         auto factor = loopIter->second;
1915         int32_t lastSize = factor > 0 ? array.size() / factor : 0;
1916         auto updateSize = std::min(static_cast<int32_t>(lastSize), repeatValue->GetArraySize());
1917         for (auto i = 0; i < updateSize; ++i) {
1918             SetRepeatItemValue(i, repeatValue, hasKeyValue);
1919             UpdateDomNode(page, rootJson, parentId, array);
1920         }
1921 
1922         if (repeatValue->GetArraySize() > lastSize) {
1923             for (auto i = lastSize; i < repeatValue->GetArraySize(); ++i) {
1924                 SetRepeatItemValue(i, repeatValue, hasKeyValue);
1925                 CreateDomNode(page, rootJson, parentId, true);
1926             }
1927             if (factor == 0) {
1928                 factor = static_cast<int32_t>(idArray_.size()) / repeatValue->GetArraySize();
1929                 loopIter->second = factor;
1930             }
1931             iter->second.first.insert(iter->second.first.end(), idArray_.begin(), idArray_.end());
1932         } else if (lastSize > repeatValue->GetArraySize()) {
1933             for (int32_t i = array.size() - factor; i >= repeatValue->GetArraySize() * factor; i = i - factor) {
1934                 auto nodeId = iter->second.first[i];
1935                 page->PushCommand(Referenced::MakeRefPtr<JsCommandRemoveDomElement>(nodeId));
1936             }
1937             iter->second.first.erase(
1938                 iter->second.first.end() - (array.size() - static_cast<size_t>(repeatValue->GetArraySize() * factor)),
1939                 iter->second.first.end());
1940         }
1941         nodeId_ += iter->second.second;
1942     }
1943     idArray_.clear();
1944     listNodeIndex_ = 0;
1945 }
1946 
SetUpdateStatus(const RefPtr<Framework::JsAcePage> & page)1947 void JsCardParser::SetUpdateStatus(const RefPtr<Framework::JsAcePage>& page)
1948 {
1949     parsingStatus_ = ParsingStatus::UPDATE;
1950     UpdateDomNode(page, rootJson_, -1);
1951     nodeId_ = 0;
1952     numberOfForNode_ = 0;
1953     page->FlushCommands();
1954 }
1955 
GetShownAttr(const std::unique_ptr<JsonValue> & rootJson,const std::unique_ptr<JsonValue> & dataJson,const std::unique_ptr<JsonValue> & propsJson,bool & shouldShow,bool & hasShownAttr)1956 void JsCardParser::GetShownAttr(const std::unique_ptr<JsonValue>& rootJson, const std::unique_ptr<JsonValue>& dataJson,
1957     const std::unique_ptr<JsonValue>& propsJson, bool& shouldShow, bool& hasShownAttr)
1958 {
1959     GetBoolValue(rootJson, dataJson, propsJson, "shown", shouldShow, hasShownAttr);
1960     bool blockValue = false;
1961     bool hasBlock = false;
1962     GetBoolValue(rootJson, BLOCK_VALUE, blockValue, hasBlock);
1963     if (hasBlock) {
1964         shouldShow = shouldShow && blockValue;
1965         hasShownAttr = true;
1966     }
1967 }
1968 
ParseVersionAndUpdateData()1969 void JsCardParser::ParseVersionAndUpdateData()
1970 {
1971     LOGI("parse version info and update data field");
1972     auto versionJson = rootBody_->GetValue("apiVersion");
1973     CHECK_NULL_VOID_NOLOG(versionJson);
1974     if (!versionJson->IsValid()) {
1975         return;
1976     }
1977     auto child = versionJson->GetChild();
1978     VersionData versionData;
1979     while (child && child->IsValid()) {
1980         if (child->IsObject()) {
1981             auto key = child->GetKey();
1982             auto value = child->IsString() ? child->GetString() : child->ToString();
1983             versionData.AddRecord(key, value);
1984         }
1985         child = child->GetNext();
1986     }
1987     auto versionPatch = versionData.GetVersionPatch();
1988     for (const auto& patchInfo : versionPatch) {
1989         auto patchJson = JsonUtil::ParseJsonString(patchInfo);
1990         if (!patchJson || !patchJson->IsValid()) {
1991             LOGW("parse version patch failed, patchInfo = %{public}s", patchInfo.c_str());
1992             continue;
1993         }
1994         auto patchItem = patchJson->GetChild();
1995         while (patchItem && patchItem->IsValid()) {
1996             auto key = patchItem->GetKey();
1997             if (dataJson_->Contains(key)) {
1998                 dataJson_->Replace(key.c_str(), patchItem);
1999             } else {
2000                 dataJson_->Put(key.c_str(), patchItem);
2001             }
2002             patchItem = patchItem->GetNext();
2003         }
2004     }
2005 }
2006 
Initialize()2007 bool JsCardParser::Initialize()
2008 {
2009     rootJson_ = rootBody_->GetValue("template");
2010     styleJson_ = rootBody_->GetValue("styles");
2011     eventJson_ = rootBody_->GetValue("actions");
2012     dataJson_ = rootBody_->GetValue("data");
2013 
2014     CHECK_NULL_RETURN_NOLOG(rootJson_, false);
2015     CHECK_NULL_RETURN_NOLOG(styleJson_, false);
2016     CHECK_NULL_RETURN_NOLOG(eventJson_, false);
2017     CHECK_NULL_RETURN_NOLOG(dataJson_, false);
2018     if (!rootJson_->IsValid() || !styleJson_->IsValid() || !eventJson_->IsValid() || !dataJson_->IsValid()) {
2019         LOGE("the json template is error");
2020         return false;
2021     }
2022 
2023     ParseVersionAndUpdateData();
2024     // repeatJson contains dataJson.
2025     repeatJson_ = JsonUtil::ParseJsonString(dataJson_->ToString());
2026     LoadMediaQueryStyle();
2027     return true;
2028 }
2029 
OnSurfaceChanged(int32_t width,int32_t height)2030 void JsCardParser::OnSurfaceChanged(int32_t width, int32_t height)
2031 {
2032     mediaQueryer_.SetSurfaceSize(width, height);
2033 }
2034 
CreateBlockNode(const OHOS::Ace::RefPtr<OHOS::Ace::Framework::JsAcePage> & page,const std::unique_ptr<JsonValue> & rootJson,int32_t parentId)2035 void JsCardParser::CreateBlockNode(const OHOS::Ace::RefPtr<OHOS::Ace::Framework::JsAcePage>& page,
2036     const std::unique_ptr<JsonValue>& rootJson, int32_t parentId)
2037 {
2038     auto blockChild = rootJson->GetValue("children");
2039     bool shouldShow = true;
2040     bool hasShownAttr = false;
2041     GetBoolValue(rootJson, "shown", shouldShow, hasShownAttr);
2042     const char* value = shouldShow ? "true" : "false";
2043     if (blockChild && blockChild->IsValid()) {
2044         auto child = blockChild->GetChild();
2045         while (child && child->IsValid()) {
2046             if (child->Contains(BLOCK_VALUE)) {
2047                 child->Replace(BLOCK_VALUE, value);
2048             } else {
2049                 child->Put(BLOCK_VALUE, value);
2050             }
2051             parsingStatus_ == ParsingStatus::UPDATE ? UpdateDomNode(page, child, parentId)
2052                                                     : CreateDomNode(page, child, parentId);
2053             child = child->GetNext();
2054         }
2055     }
2056 }
2057 
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)2058 void JsCardParser::GetBoolValue(const std::unique_ptr<JsonValue>& rootJson, const std::unique_ptr<JsonValue>& dataJson,
2059     const std::unique_ptr<JsonValue>& propsJson, const std::string& key, bool& value, bool& hasAttr)
2060 {
2061     auto result = rootJson->GetValue(key);
2062     if (result && result->IsValid()) {
2063         if (result->IsString()) {
2064             auto strValue = result->GetString();
2065             GetShownValue(strValue, dataJson, propsJson);
2066             value = strValue == "true";
2067             hasAttr = true;
2068             return;
2069         } else if (result->IsBool()) {
2070             value = result->GetBool();
2071             hasAttr = true;
2072             return;
2073         }
2074     }
2075     hasAttr = false;
2076 }
2077 
SetColorMode(ColorMode colorMode)2078 void JsCardParser::SetColorMode(ColorMode colorMode)
2079 {
2080     LOGI("current color mode is %{public}d", colorMode);
2081     colorMode_ = colorMode;
2082     mediaQueryer_.SetColorMode(colorMode);
2083 }
2084 
2085 } // namespace OHOS::Ace::Framework
2086