Skip to content

Commit e99eabc

Browse files
committed
add urlsearchparams
1 parent ea182f8 commit e99eabc

File tree

4 files changed

+182
-4
lines changed

4 files changed

+182
-4
lines changed

Runtime/Scripting/DomProxies/URL.cs

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,32 @@ public string href
2222
public string origin { get; protected set; }
2323
public string host { get; protected set; }
2424
public string port { get; protected set; }
25-
public string search { get; protected set; }
26-
public string hash { get; protected set; }
2725
public string pathname { get; protected set; }
2826
public string rawPathname { get; protected set; }
2927

3028

29+
30+
public string _search;
31+
public string _hash;
32+
public string search {
33+
get => _search;
34+
set {
35+
_search = NormalizeWithPrefix(value, "?");
36+
RebuildHref();
37+
}
38+
}
39+
public string hash {
40+
get => _hash;
41+
set {
42+
_hash = NormalizeWithPrefix(value, "#");
43+
RebuildHref();
44+
}
45+
}
46+
47+
private URLSearchParams _searchParams;
48+
public URLSearchParams searchParams => _searchParams = _searchParams ?? new URLSearchParams(this);
49+
50+
3151
public URL(string url) : this(url, null)
3252
{
3353
}
@@ -123,12 +143,25 @@ protected void SetHref(string url)
123143
this.origin = origin;
124144
this.host = host;
125145
this.port = port;
126-
this.search = search;
127-
this.hash = hash;
146+
this._search = search;
147+
this._hash = hash;
128148
this.pathname = pathName;
129149
this.rawPathname = rawPathName;
130150
}
131151

152+
protected void RebuildHref()
153+
{
154+
var newHref = (origin ?? "") + pathname + search + hash;
155+
SetHref(newHref);
156+
}
157+
158+
private string NormalizeWithPrefix(string value, string prefix)
159+
{
160+
if (string.IsNullOrEmpty(value)) return "";
161+
if (value.FastStartsWith(prefix)) return value;
162+
return prefix + value;
163+
}
164+
132165
private string[] GetPathSegments() => GetPathSegments(pathname);
133166

134167
private static string[] GetPathSegments(string pathname)
@@ -181,5 +214,7 @@ private static void AddToPath(List<string> path, ICollection<string> segments)
181214

182215
if (addFolderAtEnd) path.Add("");
183216
}
217+
218+
public override String ToString() => _href;
184219
}
185220
}
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using ReactUnity.Helpers;
6+
7+
namespace ReactUnity.Scripting.DomProxies
8+
{
9+
// https://url.spec.whatwg.org/#urlsearchparams
10+
public class URLSearchParams: IEnumerable<string[]>
11+
{
12+
#region Fields
13+
14+
private readonly List<KeyValuePair<String, String>> _values;
15+
private readonly URL _parent;
16+
17+
#endregion
18+
19+
#region Constructors
20+
21+
public URLSearchParams() => _values = new List<KeyValuePair<String, String>>();
22+
23+
internal URLSearchParams(URL parent) : this()
24+
{
25+
_parent = parent;
26+
ChangeTo(parent.search, true);
27+
}
28+
29+
public URLSearchParams(String init) : this() => ChangeTo(init, false);
30+
31+
#endregion
32+
33+
#region Methods
34+
35+
internal void Reset() => _values.Clear();
36+
37+
internal void ChangeTo(String query, Boolean fromParent)
38+
{
39+
Reset();
40+
41+
if (query is "") return;
42+
if (query.StartsWith("?")) query = query.Substring(1);
43+
44+
foreach (var pair in query.Split('&'))
45+
{
46+
var kvp = pair.Split('=');
47+
48+
if (kvp.Length > 1)
49+
{
50+
AppendCore(Decode(kvp[0]), Decode(kvp[1]));
51+
}
52+
else
53+
{
54+
AppendCore(Decode(pair), String.Empty);
55+
}
56+
}
57+
58+
RaiseChanged(fromParent);
59+
}
60+
61+
public void append(String name, String value)
62+
{
63+
AppendCore(name, value);
64+
RaiseChanged(false);
65+
}
66+
67+
private void AppendCore(String name, String value)
68+
{
69+
_values.Add(new KeyValuePair<String, String>(name, value));
70+
}
71+
72+
public void delete(String name)
73+
{
74+
DeleteCore(name);
75+
RaiseChanged(false);
76+
}
77+
78+
private void DeleteCore(String name)
79+
{
80+
_values.RemoveAll(p => p.Key == name);
81+
}
82+
83+
public String get(String name) => _values.Find(p => p.Key == name).Value;
84+
85+
public String[] getAll(String name) => _values.FindAll(p => p.Key == name).Select(m => m.Value).ToArray();
86+
87+
public Boolean has(String name) => _values.Any(p => p.Key == name);
88+
89+
public void set(String name, String value)
90+
{
91+
if (has(name))
92+
{
93+
var index = _values.FindIndex(p => p.Key == name);
94+
DeleteCore(name);
95+
_values.Insert(index, new KeyValuePair<String, String>(name, value));
96+
}
97+
else
98+
{
99+
AppendCore(name, value);
100+
}
101+
102+
RaiseChanged(false);
103+
}
104+
105+
public void sort()
106+
{
107+
_values.Sort((a, b) => a.Key.CompareTo(b.Key));
108+
RaiseChanged(false);
109+
}
110+
111+
public string[] keys() => _values.Select(p => p.Key).Distinct().ToArray();
112+
public string[] values() => _values.Select(p => p.Value).ToArray();
113+
public string[][] entries() => _values.Select(p => new[] { p.Key, p.Value }).ToArray();
114+
public IEnumerator<string[]> GetEnumerator() => ((IEnumerable<string[]>) entries()).GetEnumerator();
115+
IEnumerator IEnumerable.GetEnumerator() => entries().GetEnumerator();
116+
117+
public override String ToString() => String.Join("&", _values.Select(p => $"{Encode(p.Key)}={Encode(p.Value)}"));
118+
119+
#endregion
120+
121+
#region Helpers
122+
123+
private static String Encode(String value)
124+
{
125+
return EncodingHelpers.encodeURIComponent(value);
126+
}
127+
128+
private static String Decode(String value)
129+
{
130+
return EncodingHelpers.decodeURIComponent(value);
131+
}
132+
133+
private void RaiseChanged(Boolean fromParent)
134+
{
135+
if (!fromParent && _parent != null) _parent.search = ToString();
136+
}
137+
138+
#endregion
139+
}
140+
}

Runtime/Scripting/DomProxies/URLSearchParams.cs.meta

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Runtime/Scripting/ScriptContext.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ static void CreateDOMShims(IJavaScriptEngine engine, ReactContext context)
240240
if (!engine.Capabilities.HasFlag(EngineCapabilities.URL))
241241
{
242242
engine.SetGlobal("URL", typeof(URL));
243+
engine.SetGlobal("URLSearchParams", typeof(URLSearchParams));
243244
}
244245

245246
if (!engine.Capabilities.HasFlag(EngineCapabilities.WebSocket))

0 commit comments

Comments
 (0)