21
21
using System . Collections . Generic ;
22
22
using System . Globalization ;
23
23
using System . IO ;
24
+ using System . Text . Json ;
25
+
26
+ #nullable enable
24
27
25
28
namespace OpenQA . Selenium . Firefox
26
29
{
@@ -29,31 +32,27 @@ namespace OpenQA.Selenium.Firefox
29
32
/// </summary>
30
33
internal class Preferences
31
34
{
32
- private Dictionary < string , string > preferences = new Dictionary < string , string > ( ) ;
33
- private Dictionary < string , string > immutablePreferences = new Dictionary < string , string > ( ) ;
35
+ private readonly Dictionary < string , string > preferences = new Dictionary < string , string > ( ) ;
36
+ private readonly HashSet < string > immutablePreferences = new HashSet < string > ( ) ;
34
37
35
38
/// <summary>
36
39
/// Initializes a new instance of the <see cref="Preferences"/> class.
37
40
/// </summary>
38
41
/// <param name="defaultImmutablePreferences">A set of preferences that cannot be modified once set.</param>
39
42
/// <param name="defaultPreferences">A set of default preferences.</param>
40
- public Preferences ( Dictionary < string , object > defaultImmutablePreferences , Dictionary < string , object > defaultPreferences )
43
+ public Preferences ( JsonElement defaultImmutablePreferences , JsonElement defaultPreferences )
41
44
{
42
- if ( defaultImmutablePreferences != null )
45
+ foreach ( JsonProperty pref in defaultImmutablePreferences . EnumerateObject ( ) )
43
46
{
44
- foreach ( KeyValuePair < string , object > pref in defaultImmutablePreferences )
45
- {
46
- this . SetPreferenceValue ( pref . Key , pref . Value ) ;
47
- this . immutablePreferences . Add ( pref . Key , pref . Value . ToString ( ) ) ;
48
- }
47
+ this . ThrowIfPreferenceIsImmutable ( pref . Name , pref . Value ) ;
48
+ this . preferences [ pref . Name ] = pref . Value . GetRawText ( ) ;
49
+ this . immutablePreferences . Add ( pref . Name ) ;
49
50
}
50
51
51
- if ( defaultPreferences != null )
52
+ foreach ( JsonProperty pref in defaultPreferences . EnumerateObject ( ) )
52
53
{
53
- foreach ( KeyValuePair < string , object > pref in defaultPreferences )
54
- {
55
- this . SetPreferenceValue ( pref . Key , pref . Value ) ;
56
- }
54
+ this . ThrowIfPreferenceIsImmutable ( pref . Name , pref . Value ) ;
55
+ this . preferences [ pref . Name ] = pref . Value . GetRawText ( ) ;
57
56
}
58
57
}
59
58
@@ -64,9 +63,31 @@ public Preferences(Dictionary<string, object> defaultImmutablePreferences, Dicti
64
63
/// <param name="value">A <see cref="string"/> value give the preference.</param>
65
64
/// <remarks>If the preference already exists in the currently-set list of preferences,
66
65
/// the value will be updated.</remarks>
66
+ /// <exception cref="ArgumentNullException">If <paramref name="key"/> or <paramref name="value"/> are <see langword="null"/>.</exception>
67
+ /// <exception cref="ArgumentException">
68
+ /// <para>If <paramref name="value"/> is wrapped with double-quotes.</para>
69
+ /// <para>-or-</para>
70
+ /// <para>If the specified preference is immutable.</para>
71
+ /// </exception>
67
72
internal void SetPreference ( string key , string value )
68
73
{
69
- this . SetPreferenceValue ( key , value ) ;
74
+ if ( key is null )
75
+ {
76
+ throw new ArgumentNullException ( nameof ( key ) ) ;
77
+ }
78
+
79
+ if ( value is null )
80
+ {
81
+ throw new ArgumentNullException ( nameof ( value ) ) ;
82
+ }
83
+
84
+ if ( IsWrappedAsString ( value ) )
85
+ {
86
+ throw new ArgumentException ( string . Format ( CultureInfo . InvariantCulture , "Preference values must be plain strings: {0}: {1}" , key , value ) ) ;
87
+ }
88
+
89
+ this . ThrowIfPreferenceIsImmutable ( key , value ) ;
90
+ this . preferences [ key ] = string . Format ( CultureInfo . InvariantCulture , "\" {0}\" " , value ) ;
70
91
}
71
92
72
93
/// <summary>
@@ -76,9 +97,17 @@ internal void SetPreference(string key, string value)
76
97
/// <param name="value">A <see cref="int"/> value give the preference.</param>
77
98
/// <remarks>If the preference already exists in the currently-set list of preferences,
78
99
/// the value will be updated.</remarks>
100
+ /// <exception cref="ArgumentNullException">If <paramref name="key"/> is <see langword="null"/>.</exception>
101
+ /// <exception cref="ArgumentException">If the specified preference is immutable.</exception>
79
102
internal void SetPreference ( string key , int value )
80
103
{
81
- this . SetPreferenceValue ( key , value ) ;
104
+ if ( key is null )
105
+ {
106
+ throw new ArgumentNullException ( nameof ( key ) ) ;
107
+ }
108
+
109
+ this . ThrowIfPreferenceIsImmutable ( key , value ) ;
110
+ this . preferences [ key ] = value . ToString ( CultureInfo . InvariantCulture ) ;
82
111
}
83
112
84
113
/// <summary>
@@ -88,16 +117,25 @@ internal void SetPreference(string key, int value)
88
117
/// <param name="value">A <see cref="bool"/> value give the preference.</param>
89
118
/// <remarks>If the preference already exists in the currently-set list of preferences,
90
119
/// the value will be updated.</remarks>
120
+ /// <exception cref="ArgumentNullException">If <paramref name="key"/> is <see langword="null"/>.</exception>
121
+ /// <exception cref="ArgumentException">If the specified preference is immutable.</exception>
91
122
internal void SetPreference ( string key , bool value )
92
123
{
93
- this . SetPreferenceValue ( key , value ) ;
124
+ if ( key is null )
125
+ {
126
+ throw new ArgumentNullException ( nameof ( key ) ) ;
127
+ }
128
+
129
+ this . ThrowIfPreferenceIsImmutable ( key , value ) ;
130
+ this . preferences [ key ] = value ? "true" : "false" ;
94
131
}
95
132
96
133
/// <summary>
97
134
/// Gets a preference from the list of preferences.
98
135
/// </summary>
99
136
/// <param name="preferenceName">The name of the preference to retrieve.</param>
100
137
/// <returns>The value of the preference, or an empty string if the preference is not set.</returns>
138
+ /// <exception cref="ArgumentNullException">If <paramref name="preferenceName"/> is <see langword="null"/>.</exception>
101
139
internal string GetPreference ( string preferenceName )
102
140
{
103
141
if ( this . preferences . ContainsKey ( preferenceName ) )
@@ -151,44 +189,18 @@ private static bool IsWrappedAsString(string value)
151
189
return value . StartsWith ( "\" " , StringComparison . OrdinalIgnoreCase ) && value . EndsWith ( "\" " , StringComparison . OrdinalIgnoreCase ) ;
152
190
}
153
191
154
- private bool IsSettablePreference ( string preferenceName )
192
+ private void ThrowIfPreferenceIsImmutable < TValue > ( string preferenceName , TValue value )
155
193
{
156
- return ! this . immutablePreferences . ContainsKey ( preferenceName ) ;
157
- }
158
-
159
- private void SetPreferenceValue ( string key , object value )
160
- {
161
- if ( ! this . IsSettablePreference ( key ) )
194
+ if ( this . immutablePreferences . Contains ( preferenceName ) )
162
195
{
163
- string message = string . Format ( CultureInfo . InvariantCulture , "Preference {0} may not be overridden: frozen value={1}, requested value={2}" , key , this . immutablePreferences [ key ] , value . ToString ( ) ) ;
196
+ string message = string . Format ( CultureInfo . InvariantCulture , "Preference {0} may not be overridden: frozen value={1}, requested value={2}" , preferenceName , this . preferences [ preferenceName ] , value ? . ToString ( ) ) ;
164
197
throw new ArgumentException ( message ) ;
165
198
}
199
+ }
166
200
167
- string stringValue = value as string ;
168
- if ( stringValue != null )
169
- {
170
- if ( IsWrappedAsString ( stringValue ) )
171
- {
172
- throw new ArgumentException ( string . Format ( CultureInfo . InvariantCulture , "Preference values must be plain strings: {0}: {1}" , key , value ) ) ;
173
- }
174
-
175
- this . preferences [ key ] = string . Format ( CultureInfo . InvariantCulture , "\" {0}\" " , value ) ;
176
- return ;
177
- }
178
-
179
- if ( value is bool )
180
- {
181
- this . preferences [ key ] = Convert . ToBoolean ( value , CultureInfo . InvariantCulture ) . ToString ( ) . ToLowerInvariant ( ) ;
182
- return ;
183
- }
184
-
185
- if ( value is int || value is long )
186
- {
187
- this . preferences [ key ] = Convert . ToInt32 ( value , CultureInfo . InvariantCulture ) . ToString ( CultureInfo . InvariantCulture ) ;
188
- return ;
189
- }
190
-
191
- throw new WebDriverException ( "Value must be string, int or boolean" ) ;
201
+ private bool IsSettablePreference ( string preferenceName )
202
+ {
203
+ return ! this . immutablePreferences . Contains ( preferenceName ) ;
192
204
}
193
205
}
194
206
}
0 commit comments