1 /*
2  * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef OHOS_ACELITE_APP_STYLE_ITEM_H
17 #define OHOS_ACELITE_APP_STYLE_ITEM_H
18 
19 #include <stdlib.h>
20 #include <string.h>
21 
22 #include "js_fwk_common.h"
23 #include "key_parser.h"
24 #include "non_copyable.h"
25 #include "securec.h"
26 
27 namespace OHOS {
28 namespace ACELite {
29 constexpr char PSEUDO_CLASS_TYPE_ACTIVE[] = ":active";
30 constexpr char PSEUDO_CLASS_TYPE_CHECKED[] = ":checked";
31 
32 enum {
33     STYLE_PROP_VALUE_TYPE_UNKNOWN = 0x00,
34     STYLE_PROP_VALUE_TYPE_STRING = 0x01,
35     STYLE_PROP_VALUE_TYPE_NUMBER = 0x02,
36     STYLE_PROP_VALUE_TYPE_BOOL = 0x03,
37     STYLE_PROP_VALUE_TYPE_FLOATING = 0x04,
38     STYLE_PROP_VALUE_TYPE_PERCENT = 0x05,
39 };
40 
41 union StyleValue {
42     double floating;
43     int32_t number;
44     float percent;
45     char *string;
46     bool boolean;
47 };
48 
49 /**
50  * pseudo class support
51  */
52 enum {
53     PSEUDO_CLASS_UNKNOWN = 0x00, // please add new type above
54     PSEUDO_CLASS_ACTIVE = 0x01,  // :active
55     PSEUDO_CLASS_CHECKED = 0x02  // :checked
56 };
57 
58 /**
59  * style flag
60  * former part for odd, latter part for even
61  */
62 typedef struct U8Bits : public MemoryHeap {
63     bool standardOdd_ : 1;
64     bool pseudoActiveOdd_ : 1;
65     bool pseudoCheckedOdd_ : 1;
66     bool pseudoUnknownOdd_ : 1;
67     bool standardEven_ : 1;
68     bool pseudoActiveEven_ : 1;
69     bool pseudoCheckedEven_ : 1;
70     bool pseudoUnknownEven_ : 1;
71 } U8BitsType;
72 
73 typedef union StyleFlag {
74     U8BitsType u8Bits;
75     uint8_t u8Byte;
76 } StyleFlagType;
77 
78 class AppStyleItem final : public MemoryHeap {
79 public:
80     ACE_DISALLOW_COPY_AND_MOVE(AppStyleItem);
AppStyleItem()81     AppStyleItem()
82         : pre_(nullptr),
83           next_(nullptr),
84           styleValue_({ 0.0 }),
85           propNameId_(0),
86           valueType_(STYLE_PROP_VALUE_TYPE_UNKNOWN),
87           pseudoClassType_(PSEUDO_CLASS_UNKNOWN)
88     {
89     }
90 
~AppStyleItem()91     ~AppStyleItem()
92     {
93         if (valueType_ == STYLE_PROP_VALUE_TYPE_STRING) {
94             ACE_FREE(styleValue_.string);
95         }
96     }
97 
GetPropNameId()98     uint16_t GetPropNameId() const
99     {
100         return propNameId_;
101     }
102 
GetValueType()103     uint8_t GetValueType() const
104     {
105         return valueType_;
106     }
107 
GetStrValue()108     const char *GetStrValue() const
109     {
110         return (valueType_ != STYLE_PROP_VALUE_TYPE_STRING || GetStrValueLen() == 0) ? nullptr : styleValue_.string;
111     }
112 
GetStrValueLen()113     size_t GetStrValueLen() const
114     {
115         return (styleValue_.string != nullptr) ? strlen(styleValue_.string) : 0;
116     }
117 
GetNumValue()118     int32_t GetNumValue() const
119     {
120         return (valueType_ != STYLE_PROP_VALUE_TYPE_NUMBER) ? 0 : styleValue_.number;
121     }
122 
GetBoolValue()123     bool GetBoolValue() const
124     {
125         return (valueType_ != STYLE_PROP_VALUE_TYPE_BOOL) ? false : styleValue_.boolean;
126     }
127 
GetFloatingValue()128     double GetFloatingValue() const
129     {
130         return (valueType_ != STYLE_PROP_VALUE_TYPE_FLOATING) ? false : styleValue_.floating;
131     }
132 
GetPercentValue()133     float GetPercentValue() const
134     {
135         return (valueType_ != STYLE_PROP_VALUE_TYPE_PERCENT) ? 0 : styleValue_.percent;
136     }
137 
GetNext()138     const AppStyleItem *GetNext() const
139     {
140         return next_;
141     }
142 
SetNext(AppStyleItem * nextStyle)143     void SetNext(AppStyleItem *nextStyle)
144     {
145         next_ = nextStyle;
146     }
147 
SetPre(AppStyleItem * preStyle)148     void SetPre(AppStyleItem *preStyle)
149     {
150         pre_ = preStyle;
151     }
152 
GetPre()153     const AppStyleItem *GetPre() const
154     {
155         return pre_;
156     }
157 
IsPseudoClassItem()158     bool IsPseudoClassItem() const
159     {
160         return (pseudoClassType_ != PSEUDO_CLASS_UNKNOWN);
161     }
162 
GetPseudoClassType()163     uint8_t GetPseudoClassType() const
164     {
165         return pseudoClassType_;
166     }
167 
168     bool UpdateNumValToStr();
169     void UpdateValueFrom(const AppStyleItem &from);
170     static AppStyleItem *GenerateFromJSValue(jerry_value_t stylePropName, jerry_value_t stylePropValue);
171     static AppStyleItem *CreateStyleItem(uint16_t keyId,
172                                          const jerry_value_t stylePropValue,
173                                          uint8_t pseudoClassType = PSEUDO_CLASS_UNKNOWN);
174     // copy constructor can not return null, so define a static method instead
175     static AppStyleItem *CopyFrom(const AppStyleItem *from);
176     /**
177      * @brief Check if the given style is one pseudo class type, if it is, the corrensponding pseudo class enum
178      *        will be calculated and returned, the style name also will be cutted to the key without the pseudo
179      *        class name, the new key length also will be given out.
180      *
181      * @param[in] styleKey: the target style name to check
182      * @param[in] keyLength: the target style name length
183      * @param[out] keyLength: the new style name length
184      *
185      * @return unknown or the corrensponding pseudo class type
186      */
187     static uint8_t EstimatePseudoClassType(const char * const styleKey, uint16_t *keyLength);
188 
189 private:
SetNumValue(int32_t value)190     void SetNumValue(int32_t value)
191     {
192         valueType_ = STYLE_PROP_VALUE_TYPE_NUMBER;
193         styleValue_.number = value;
194     }
195 
SetBoolValue(bool value)196     void SetBoolValue(bool value)
197     {
198         valueType_ = STYLE_PROP_VALUE_TYPE_BOOL;
199         styleValue_.boolean = value;
200     }
201 
SetFloatingValue(double value)202     void SetFloatingValue(double value)
203     {
204         valueType_ = STYLE_PROP_VALUE_TYPE_FLOATING;
205         styleValue_.floating = value;
206     }
207 
SetPercentValue(float value)208     void SetPercentValue(float value)
209     {
210         valueType_ = STYLE_PROP_VALUE_TYPE_PERCENT;
211         styleValue_.percent = value;
212     }
213 
214     void SetStringValue(const char * const value);
215 
216     AppStyleItem *pre_;
217     AppStyleItem *next_;
218 
219     StyleValue styleValue_;
220     uint16_t propNameId_;
221     uint8_t valueType_;
222     uint8_t pseudoClassType_;
223 };
224 } // namespace ACELite
225 } // namespace OHOS
226 
227 #endif // OHOS_ACELITE_APP_STYLE_ITEM_H
228