|
19 | 19 |
|
20 | 20 | using System; |
21 | 21 | using System.Collections.Generic; |
22 | | -using System.Diagnostics; |
23 | 22 | using System.Linq; |
24 | 23 | using System.Numerics; |
25 | | -using System.Text.Json.Nodes; |
26 | 24 | using System.Text.Json.Serialization; |
27 | | -using System.Text.RegularExpressions; |
28 | 25 |
|
29 | 26 | namespace OpenQA.Selenium.BiDi.Modules.Script; |
30 | 27 |
|
@@ -75,73 +72,67 @@ public static LocalValue ConvertFrom(object? value) |
75 | 72 | case string str: |
76 | 73 | return new StringLocalValue(str); |
77 | 74 |
|
78 | | - case IEnumerable<object?> list: |
79 | | - return new ArrayLocalValue(list.Select(ConvertFrom).ToList()); |
80 | | - |
81 | | - case object: |
| 75 | + case IDictionary<string, string?> dictionary: |
82 | 76 | { |
83 | | - var type = value.GetType(); |
| 77 | + var bidiObject = new List<List<LocalValue>>(dictionary.Count); |
84 | 78 |
|
85 | | - var properties = type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); |
86 | | - |
87 | | - List<List<LocalValue>> values = []; |
88 | | - |
89 | | - foreach (var property in properties) |
| 79 | + foreach (var item in dictionary) |
90 | 80 | { |
91 | | - values.Add([property.Name, ConvertFrom(property.GetValue(value))]); |
| 81 | + bidiObject.Add([new StringLocalValue(item.Key), ConvertFrom(item.Value)]); |
92 | 82 | } |
93 | 83 |
|
94 | | - return new ObjectLocalValue(values); |
| 84 | + return new ObjectLocalValue(bidiObject); |
95 | 85 | } |
96 | | - } |
97 | | - } |
98 | | - |
99 | | - public static LocalValue ConvertFrom(JsonNode? node) |
100 | | - { |
101 | | - if (node is null) |
102 | | - { |
103 | | - return new NullLocalValue(); |
104 | | - } |
105 | | - |
106 | | - switch (node.GetValueKind()) |
107 | | - { |
108 | | - case System.Text.Json.JsonValueKind.Null: |
109 | | - return new NullLocalValue(); |
110 | 86 |
|
111 | | - case System.Text.Json.JsonValueKind.True: |
112 | | - return new BooleanLocalValue(true); |
| 87 | + case IDictionary<string, object?> dictionary: |
| 88 | + { |
| 89 | + var bidiObject = new List<List<LocalValue>>(dictionary.Count); |
113 | 90 |
|
114 | | - case System.Text.Json.JsonValueKind.False: |
115 | | - return new BooleanLocalValue(false); |
| 91 | + foreach (var item in dictionary) |
| 92 | + { |
| 93 | + bidiObject.Add([new StringLocalValue(item.Key), ConvertFrom(item.Value)]); |
| 94 | + } |
116 | 95 |
|
117 | | - case System.Text.Json.JsonValueKind.String: |
118 | | - return new StringLocalValue(node.ToString()); |
| 96 | + return new ObjectLocalValue(bidiObject); |
| 97 | + } |
119 | 98 |
|
120 | | - case System.Text.Json.JsonValueKind.Number: |
| 99 | + case IDictionary<int, object?> dictionary: |
121 | 100 | { |
122 | | - var numberString = node.ToString(); |
123 | | - |
124 | | - var numberAsDouble = double.Parse(numberString); |
| 101 | + var bidiObject = new List<List<LocalValue>>(dictionary.Count); |
125 | 102 |
|
126 | | - if (double.IsInfinity(numberAsDouble)) |
| 103 | + foreach (var item in dictionary) |
127 | 104 | { |
128 | | - // Numbers outside of Int64's range will successfully parse, but become +- Infinity |
129 | | - // We can retain the value using a BigInt |
130 | | - return new BigIntLocalValue(numberString); |
| 105 | + bidiObject.Add([ConvertFrom(item.Key), ConvertFrom(item.Value)]); |
131 | 106 | } |
132 | 107 |
|
133 | | - return new NumberLocalValue(numberAsDouble); |
| 108 | + return new MapLocalValue(bidiObject); |
134 | 109 | } |
135 | 110 |
|
136 | | - case System.Text.Json.JsonValueKind.Array: |
137 | | - return new ArrayLocalValue(node.AsArray().Select(ConvertFrom)); |
| 111 | + case IEnumerable<object?> list: |
| 112 | + return new ArrayLocalValue(list.Select(ConvertFrom).ToList()); |
| 113 | + |
| 114 | + case object: |
| 115 | + { |
| 116 | + const System.Reflection.BindingFlags Flags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance; |
| 117 | + var properties = value.GetType().GetProperties(Flags); |
138 | 118 |
|
139 | | - case System.Text.Json.JsonValueKind.Object: |
140 | | - var convertedToListForm = node.AsObject().Select(property => new LocalValue[] { new StringLocalValue(property.Key), ConvertFrom(property.Value) }).ToList(); |
141 | | - return new ObjectLocalValue(convertedToListForm); |
| 119 | + var values = new List<List<LocalValue>>(properties.Length); |
| 120 | + foreach (var property in properties) |
| 121 | + { |
| 122 | + object? propertyValue; |
| 123 | + try |
| 124 | + { |
| 125 | + propertyValue = property.GetValue(value); |
| 126 | + } |
| 127 | + catch (Exception ex) |
| 128 | + { |
| 129 | + throw new BiDiException($"Could not retrieve property {property.Name} from {property.DeclaringType}", ex); |
| 130 | + } |
| 131 | + values.Add([property.Name, ConvertFrom(propertyValue)]); |
| 132 | + } |
142 | 133 |
|
143 | | - default: |
144 | | - throw new InvalidOperationException("Invalid JSON node"); |
| 134 | + return new ObjectLocalValue(values); |
| 135 | + } |
145 | 136 | } |
146 | 137 | } |
147 | 138 | } |
|
0 commit comments