1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2020-2023. All rights reserved.
3cb93a386Sopenharmony_ci * Description: Implementation for Css style parser.
4cb93a386Sopenharmony_ci * Create: 2020/03/31
5cb93a386Sopenharmony_ci */
6cb93a386Sopenharmony_ci
7cb93a386Sopenharmony_ci#include "CssStyleParser.h"
8cb93a386Sopenharmony_ci
9cb93a386Sopenharmony_ciconst std::unordered_map<std::string, std::string>& CssStyleParser::getArributesMap(const std::string& key) const
10cb93a386Sopenharmony_ci{
11cb93a386Sopenharmony_ci    auto styleClassIter = fStyleMap.find(key);
12cb93a386Sopenharmony_ci    if (styleClassIter != fStyleMap.end()) {
13cb93a386Sopenharmony_ci        return styleClassIter->second;
14cb93a386Sopenharmony_ci    } else {
15cb93a386Sopenharmony_ci        static std::unordered_map<std::string, std::string> fEmptyMap;
16cb93a386Sopenharmony_ci        return fEmptyMap;
17cb93a386Sopenharmony_ci    }
18cb93a386Sopenharmony_ci}
19cb93a386Sopenharmony_ci
20cb93a386Sopenharmony_civoid CssStyleParser::parseCssStyle(const std::string& style)
21cb93a386Sopenharmony_ci{
22cb93a386Sopenharmony_ci    // begin from 1 to skip first '.'for example: ".cls-1{fill:#843dd1;}"
23cb93a386Sopenharmony_ci    auto styles = splitString(style.substr(1), "}.");
24cb93a386Sopenharmony_ci    for (auto& style : styles) {
25cb93a386Sopenharmony_ci        auto nameEnd = style.find_first_of('{');
26cb93a386Sopenharmony_ci        if (nameEnd != std::string::npos) {
27cb93a386Sopenharmony_ci            auto names = style.substr(0, nameEnd);
28cb93a386Sopenharmony_ci            if (names.empty()) {
29cb93a386Sopenharmony_ci                return;
30cb93a386Sopenharmony_ci            }
31cb93a386Sopenharmony_ci            auto splitNames = splitString(names, ",.");
32cb93a386Sopenharmony_ci            auto attributesString = style.substr(nameEnd + 1);
33cb93a386Sopenharmony_ci            auto attributesVector = splitString(attributesString, ";");
34cb93a386Sopenharmony_ci            for (auto& splitName : splitNames) {
35cb93a386Sopenharmony_ci                for (auto& attribute : attributesVector) {
36cb93a386Sopenharmony_ci                    auto arrPair = splitString(attribute, ":");
37cb93a386Sopenharmony_ci                    // 2 means stye is a kind of key: value, for example a color stype: "fill:#843dd1"
38cb93a386Sopenharmony_ci                    if (arrPair.size() == 2) {
39cb93a386Sopenharmony_ci                        auto arrMapIter = fStyleMap.find(splitName);
40cb93a386Sopenharmony_ci                        if (arrMapIter == fStyleMap.end()) {
41cb93a386Sopenharmony_ci                            std::unordered_map<std::string, std::string> arrMap;
42cb93a386Sopenharmony_ci                            arrMap.emplace(std::make_pair(arrPair[0], arrPair[1]));
43cb93a386Sopenharmony_ci                            fStyleMap.emplace(std::make_pair(splitName, arrMap));
44cb93a386Sopenharmony_ci                        } else {
45cb93a386Sopenharmony_ci                            arrMapIter->second.emplace(std::make_pair(arrPair[0], arrPair[1]));
46cb93a386Sopenharmony_ci                        }
47cb93a386Sopenharmony_ci                    }
48cb93a386Sopenharmony_ci                }
49cb93a386Sopenharmony_ci            }
50cb93a386Sopenharmony_ci        }
51cb93a386Sopenharmony_ci    }
52cb93a386Sopenharmony_ci}
53cb93a386Sopenharmony_ci
54cb93a386Sopenharmony_cistd::vector<std::string> CssStyleParser::splitString(const std::string& srcString, const std::string& splitString)
55cb93a386Sopenharmony_ci{
56cb93a386Sopenharmony_ci    std::string::size_type pos1;
57cb93a386Sopenharmony_ci    std::string::size_type pos2;
58cb93a386Sopenharmony_ci    std::vector<std::string> res;
59cb93a386Sopenharmony_ci    pos2 = srcString.find(splitString);
60cb93a386Sopenharmony_ci    pos1 = 0;
61cb93a386Sopenharmony_ci    while (std::string::npos != pos2) {
62cb93a386Sopenharmony_ci        res.push_back(srcString.substr(pos1, pos2 - pos1));
63cb93a386Sopenharmony_ci
64cb93a386Sopenharmony_ci        pos1 = pos2 + splitString.size();
65cb93a386Sopenharmony_ci        pos2 = srcString.find(splitString, pos1);
66cb93a386Sopenharmony_ci    }
67cb93a386Sopenharmony_ci    if (pos1 != srcString.length()) {
68cb93a386Sopenharmony_ci        res.push_back(srcString.substr(pos1));
69cb93a386Sopenharmony_ci    }
70cb93a386Sopenharmony_ci    return res;
71cb93a386Sopenharmony_ci}
72