1 /*
2  * Copyright (c) 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_WEB_RESOURCE_WEB_JAVASCRIPT_VALUE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_WEB_RESOURCE_WEB_JAVASCRIPT_VALUE_H
18 
19 #include <iostream>
20 #include <map>
21 #include <set>
22 #include <sstream>
23 #include <string>
24 #include <vector>
25 
26 namespace OHOS::Ace {
27 enum class WebHitTestType : int { EDIT = 0, EMAIL, HTTP, HTTP_IMG, IMG, MAP, PHONE, UNKNOWN };
28 
29 enum class WebJavaScriptBridgeError : int {
30     NO_ERROR = 0,
31     UNKNOWN_OBJECT_ID,
32     OBJECT_IS_GONE,
33     METHOD_NOT_FOUND,
34     ACCESS_TO_OBJECT_GET_CLASS_IS_BLOCKED,
35     EXCEPTION_RAISED,
36     NON_ASSIGNABLE_TYPES,
37     RENDER_FRAME_DELETED
38 };
39 
40 union WebJSValueUnion {
41     int n;
42     double f;
43     bool b;
WebJSValueUnion()44     WebJSValueUnion() {}
WebJSValueUnion(int value)45     WebJSValueUnion(int value) : n(value) {}
WebJSValueUnion(double value)46     WebJSValueUnion(double value) : f(value) {}
WebJSValueUnion(bool value)47     WebJSValueUnion(bool value) : b(value) {}
48 };
49 
50 class WebJavaScriptValue {
51 public:
52     enum class Type : unsigned char { NONE = 0, BOOLEAN, INTEGER, DOUBLE, STRING, BINARY, DICTIONARY, LIST };
53 
WebJavaScriptValue()54     WebJavaScriptValue() {}
WebJavaScriptValue(Type type)55     explicit WebJavaScriptValue(Type type) : type_(type) {}
WebJavaScriptValue(int value)56     explicit WebJavaScriptValue(int value) : type_(Type::INTEGER), data_(value) {}
WebJavaScriptValue(double value)57     explicit WebJavaScriptValue(double value) : type_(Type::DOUBLE), data_(value) {}
WebJavaScriptValue(bool value)58     explicit WebJavaScriptValue(bool value) : type_(Type::BOOLEAN), data_(value) {}
WebJavaScriptValue(const std::string & value)59     explicit WebJavaScriptValue(const std::string& value) : type_(Type::STRING), str_(value) {}
WebJavaScriptValue(const char * data,size_t len)60     WebJavaScriptValue(const char* data, size_t len) : type_(Type::BINARY), str_(data, len) {}
WebJavaScriptValue(const std::vector<WebJavaScriptValue> & value)61     explicit WebJavaScriptValue(const std::vector<WebJavaScriptValue>& value)
62         : type_(Type::LIST), listValue_(value.begin(), value.end())
63     {}
WebJavaScriptValue(const std::map<std::string,WebJavaScriptValue> & value)64     explicit WebJavaScriptValue(const std::map<std::string, WebJavaScriptValue>& value)
65         : type_(Type::DICTIONARY), dictionaryValue_(value)
66     {}
67 
WebJavaScriptValue(const WebJavaScriptValue & value)68     explicit WebJavaScriptValue(const WebJavaScriptValue& value) : type_(value.type_)
69     {
70         switch (type_) {
71             case Type::NONE:
72                 break;
73             case Type::BOOLEAN:
74                 data_.b = value.data_.b;
75                 break;
76             case Type::INTEGER:
77                 data_.n = value.data_.n;
78                 break;
79             case Type::DOUBLE:
80                 data_.f = value.data_.f;
81                 break;
82             case Type::STRING:
83                 str_ = value.str_;
84                 break;
85             case Type::BINARY:
86                 str_ = value.str_;
87                 break;
88             case Type::LIST:
89                 listValue_ = value.listValue_;
90                 break;
91             case Type::DICTIONARY:
92                 dictionaryValue_ = value.dictionaryValue_;
93                 break;
94             default:
95                 break;
96         }
97     }
98 
WebJavaScriptValue(std::vector<WebJavaScriptValue> && value)99     WebJavaScriptValue(std::vector<WebJavaScriptValue>&& value) : type_(Type::LIST)
100     {
101         std::swap(listValue_, value);
102     }
WebJavaScriptValue(std::map<std::string,WebJavaScriptValue> && value)103     WebJavaScriptValue(std::map<std::string, WebJavaScriptValue>&& value) : type_(Type::DICTIONARY)
104     {
105         std::swap(dictionaryValue_, value);
106     }
WebJavaScriptValue(WebJavaScriptValue && value)107     WebJavaScriptValue(WebJavaScriptValue&& value)
108     {
109         *this = std::move(value);
110     }
111 
112     ~WebJavaScriptValue() = default;
113 
114     WebJavaScriptValue& operator=(const WebJavaScriptValue& value)
115     {
116         SetType(value.type_);
117         switch (type_) {
118             case Type::NONE:
119                 break;
120             case Type::BOOLEAN:
121                 data_.b = value.data_.b;
122                 break;
123             case Type::INTEGER:
124                 data_.n = value.data_.n;
125                 break;
126             case Type::DOUBLE:
127                 data_.f = value.data_.f;
128                 break;
129             case Type::STRING:
130                 str_ = value.str_;
131                 break;
132             case Type::BINARY:
133                 str_ = value.str_;
134                 break;
135             case Type::LIST:
136                 listValue_ = value.listValue_;
137                 break;
138             case Type::DICTIONARY:
139                 dictionaryValue_ = value.dictionaryValue_;
140                 break;
141             default:
142                 break;
143         }
144         return *this;
145     }
146 
147     WebJavaScriptValue& operator=(WebJavaScriptValue&& value)
148     {
149         std::swap(type_, value.type_);
150         switch (type_) {
151             case Type::NONE:
152                 break;
153             case Type::BOOLEAN:
154                 std::swap(data_.b, value.data_.b);
155                 break;
156             case Type::INTEGER:
157                 std::swap(data_.n, value.data_.n);
158                 break;
159             case Type::DOUBLE:
160                 std::swap(data_.f, value.data_.f);
161                 break;
162             case Type::STRING:
163                 std::swap(str_, value.str_);
164                 break;
165             case Type::BINARY:
166                 std::swap(str_, value.str_);
167                 break;
168             case Type::LIST:
169                 std::swap(listValue_, value.listValue_);
170                 break;
171             case Type::DICTIONARY:
172                 std::swap(dictionaryValue_, value.dictionaryValue_);
173                 break;
174             default:
175                 break;
176         }
177         return *this;
178     }
179 
180     bool operator==(WebJavaScriptValue& oVal)
181     {
182         if (type_ != oVal.type_)
183             return false;
184         switch (type_) {
185             case Type::NONE:
186                 return false;
187             case Type::BOOLEAN:
188                 return data_.b == oVal.data_.b;
189             case Type::INTEGER:
190                 return data_.n == oVal.data_.n;
191             case Type::DOUBLE:
192                 return data_.f == oVal.data_.f;
193             case Type::STRING:
194                 return str_ == oVal.str_;
195             case Type::LIST:
196                 if ((*this).listValue_.size() != oVal.listValue_.size())
197                     return false;
198                 for (size_t i = 0; i < listValue_.size(); ++i) {
199                     WebJavaScriptValue& lVal = oVal.listValue_[i];
200                     WebJavaScriptValue& rVal = (*this).listValue_[i];
201                     if (!(lVal == rVal)) {
202                         return false;
203                     }
204                 }
205                 return true;
206             case Type::DICTIONARY:
207                 if ((*this).dictionaryValue_.size() != oVal.dictionaryValue_.size())
208                     return false;
209                 for (auto item : dictionaryValue_) {
210                     WebJavaScriptValue& lVal = oVal.dictionaryValue_[item.first];
211                     WebJavaScriptValue& rVal = (*this).dictionaryValue_[item.first];
212                     if (!(lVal == rVal)) {
213                         return false;
214                     }
215                 }
216                 return true;
217             case Type::BINARY:
218                 return str_ == oVal.str_;
219             default:
220                 return false;
221         }
222         return false;
223     }
224 
IsNone()225     bool IsNone()
226     {
227         return GetType() == Type::NONE;
228     }
229 
IsBoolean()230     bool IsBoolean()
231     {
232         return GetType() == Type::BOOLEAN;
233     }
234 
IsString()235     bool IsString()
236     {
237         return GetType() == Type::STRING;
238     }
239 
IsDouble()240     bool IsDouble()
241     {
242         return GetType() == Type::DOUBLE;
243     }
244 
IsINTEGER()245     bool IsINTEGER()
246     {
247         return GetType() == Type::INTEGER;
248     }
249 
IsList()250     bool IsList()
251     {
252         return GetType() == Type::LIST;
253     }
254 
IsDictionary()255     bool IsDictionary()
256     {
257         return GetType() == Type::DICTIONARY;
258     }
259 
IsBinary()260     bool IsBinary()
261     {
262         return GetType() == Type::BINARY;
263     }
264 
GetBoolean()265     bool GetBoolean()
266     {
267         return data_.b;
268     }
269 
SetBoolean(bool value)270     void SetBoolean(bool value)
271     {
272         data_.b = value;
273     }
274 
SetString(const std::string & value)275     void SetString(const std::string& value)
276     {
277         str_ = value;
278     }
279 
GetString()280     std::string GetString()
281     {
282         return str_;
283     }
284 
SetDouble(double value)285     void SetDouble(double value)
286     {
287         data_.f = value;
288     }
289 
GetDouble()290     double GetDouble()
291     {
292         return data_.f;
293     }
294 
SetInt(int value)295     void SetInt(int value)
296     {
297         data_.n = value;
298     }
299 
GetInt()300     int GetInt()
301     {
302         return data_.n;
303     }
304 
GetListValueSize()305     size_t GetListValueSize()
306     {
307         return listValue_.size();
308     }
309 
GetListValue()310     std::vector<WebJavaScriptValue> GetListValue()
311     {
312         return listValue_;
313     }
314 
GetListValue(unsigned int index)315     WebJavaScriptValue& GetListValue(unsigned int index)
316     {
317         return listValue_[index];
318     }
319 
AddListValue(const WebJavaScriptValue & value)320     void AddListValue(const WebJavaScriptValue& value)
321     {
322         SetType(Type::LIST);
323         listValue_.push_back(value);
324     }
325 
deleteListValue()326     void deleteListValue()
327     {
328         SetType(Type::LIST);
329         listValue_.pop_back();
330     }
331 
GetDictionaryValueSize()332     size_t GetDictionaryValueSize()
333     {
334         return dictionaryValue_.size();
335     }
336 
GetDictionaryValueKeys()337     std::vector<std::string> GetDictionaryValueKeys()
338     {
339         std::vector<std::string> ret;
340         for (auto item : dictionaryValue_) {
341             ret.push_back(item.first);
342         }
343         return ret;
344     }
345 
HasDictionaryValueKey(const std::string & key)346     bool HasDictionaryValueKey(const std::string& key)
347     {
348         return dictionaryValue_.count(key) == 1;
349     }
350 
GetDictionaryValue()351     std::map<std::string, WebJavaScriptValue> GetDictionaryValue()
352     {
353         return dictionaryValue_;
354     }
355 
GetDictionaryValue(const std::string & key)356     WebJavaScriptValue& GetDictionaryValue(const std::string& key)
357     {
358         return dictionaryValue_[key];
359     }
360 
AddDictionaryValue(const std::string & key,WebJavaScriptValue & value)361     void AddDictionaryValue(const std::string& key, WebJavaScriptValue& value)
362     {
363         dictionaryValue_[key] = value;
364     }
365 
DeleteDictionaryValue(const std::string & key)366     void DeleteDictionaryValue(const std::string& key)
367     {
368         dictionaryValue_.erase(key);
369     }
370 
GetBinaryValueSize()371     size_t GetBinaryValueSize()
372     {
373         return str_.size();
374     }
375 
GetBinaryValue()376     const char* GetBinaryValue()
377     {
378         return (const char*)str_.c_str();
379     }
380 
SetJsonString(const std::string & value)381     void SetJsonString(const std::string& value)
382     {
383         json_ = value;
384     }
385 
GetJsonString()386     std::string GetJsonString()
387     {
388         return json_;
389     }
390 
GetType()391     Type GetType()
392     {
393         return type_;
394     }
395 
SetType(Type type)396     void SetType(Type type)
397     {
398         type_ = type;
399     }
400 
401     int error_ = 0;
402 
403 private:
404     Type type_ = Type::NONE;
405     WebJSValueUnion data_;
406     std::string str_;
407     std::string json_;
408     std::map<std::string, WebJavaScriptValue> dictionaryValue_;
409     std::vector<WebJavaScriptValue> listValue_;
410 };
411 using WebJSValue = WebJavaScriptValue;
412 } // namespace OHOS::Ace
413 
414 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_WEB_RESOURCE_WEB_JAVASCRIPT_VALUE_H
415