Skip to content

Commit 3325a5b

Browse files
authored
DevicesFetcher - Parse Puppeteer DeviceDescriptors.ts (#1869)
1 parent 739a1d0 commit 3325a5b

File tree

10 files changed

+253
-196
lines changed

10 files changed

+253
-196
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using Newtonsoft.Json;
2+
3+
namespace PuppeteerSharp.DevicesFetcher
4+
{
5+
public class Device
6+
{
7+
[JsonProperty("userAgent")]
8+
public string UserAgent { get; set; }
9+
[JsonProperty("name")]
10+
public string Name { get; set; }
11+
[JsonProperty("viewport")]
12+
public ViewPort Viewport { get; set; }
13+
}
14+
}

lib/PuppeteerSharp.DevicesFetcher/DevicePayload.cs

Lines changed: 0 additions & 19 deletions
This file was deleted.

lib/PuppeteerSharp.DevicesFetcher/Models.cs

Lines changed: 0 additions & 35 deletions
This file was deleted.

lib/PuppeteerSharp.DevicesFetcher/OutputDevice.cs

Lines changed: 0 additions & 24 deletions
This file was deleted.

lib/PuppeteerSharp.DevicesFetcher/Program.cs

Lines changed: 30 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,11 @@
66
using System.Text;
77
using System.Threading.Tasks;
88
using Newtonsoft.Json;
9-
using Newtonsoft.Json.Linq;
10-
using Newtonsoft.Json.Serialization;
11-
129
namespace PuppeteerSharp.DevicesFetcher
1310
{
1411
class Program
1512
{
16-
const string DEVICES_URL = "https://raw.githubusercontent.com/ChromeDevTools/devtools-frontend/master/front_end/emulated_devices/module.json";
13+
const string DEVICES_URL = "https://raw.githubusercontent.com/puppeteer/puppeteer/master/src/common/DeviceDescriptors.ts";
1714

1815
static readonly string deviceDescriptorsOutput = "../../../../PuppeteerSharp/Mobile/DeviceDescriptors.cs";
1916
static readonly string deviceDescriptorNameOutput = "../../../../PuppeteerSharp/Mobile/DeviceDescriptorName.cs";
@@ -26,92 +23,61 @@ static async Task Main(string[] args)
2623
url = args[0];
2724
}
2825

29-
string chromeVersion = null;
30-
using var fetcher = new BrowserFetcher();
31-
32-
await fetcher.DownloadAsync();
33-
await using (var browser = await Puppeteer.LaunchAsync(new LaunchOptions()))
34-
{
35-
chromeVersion = (await browser.GetVersionAsync()).Split('/').Last();
36-
}
37-
3826
Console.WriteLine($"GET {url}");
3927
var text = await HttpGET(url);
40-
RootObject json = null;
28+
29+
const string DeviceArray = "Device[] = [";
30+
var startIndex = text.IndexOf(DeviceArray) + DeviceArray.Length;
31+
var endIndex = text.IndexOf("];", startIndex);
32+
var length = endIndex - startIndex;
33+
text = "[" + text.Substring(startIndex, length) + "]";
34+
35+
Device[] devices;
4136
try
4237
{
43-
json = JsonConvert.DeserializeObject<RootObject>(text);
38+
devices = JsonConvert.DeserializeObject<Device[]>(text);
4439
}
4540
catch (Exception ex)
4641
{
4742
Console.WriteLine($"FAILED: error parsing response - {ex.Message}");
4843
return;
4944
}
50-
var devicePayloads = json.Extensions
51-
.Where(extension => extension.Type == "emulated-device")
52-
.Select(extension => extension.Device)
53-
.ToArray();
54-
var devices = new List<OutputDevice>();
55-
foreach (var payload in devicePayloads)
56-
{
57-
string[] names;
58-
if (payload.Title == "iPhone 6/7/8")
59-
{
60-
names = new[] { "iPhone 6", "iPhone 7", "iPhone 8" };
61-
}
62-
else if (payload.Title == "iPhone 6/7/8 Plus")
63-
{
64-
names = new[] { "iPhone 6 Plus", "iPhone 7 Plus", "iPhone 8 Plus" };
65-
}
66-
else if (payload.Title == "iPhone 5/SE")
67-
{
68-
names = new[] { "iPhone 5", "iPhone SE" };
69-
}
70-
else
71-
{
72-
names = new[] { payload.Title };
73-
}
74-
foreach (var name in names)
75-
{
76-
var device = CreateDevice(chromeVersion, name, payload, false);
77-
var landscape = CreateDevice(chromeVersion, name, payload, true);
78-
devices.Add(device);
79-
if (landscape.Viewport.Width != device.Viewport.Width || landscape.Viewport.Height != device.Viewport.Height)
80-
{
81-
devices.Add(landscape);
82-
}
83-
}
84-
}
85-
devices.RemoveAll(device => !device.Viewport.IsMobile);
86-
devices.Sort((a, b) => a.Name.CompareTo(b.Name));
8745

8846
WriteDeviceDescriptors(devices);
8947
WriteDeviceDescriptorName(devices);
9048
}
9149

92-
static void WriteDeviceDescriptors(IEnumerable<OutputDevice> devices)
50+
static void WriteDeviceDescriptors(IEnumerable<Device> devices)
9351
{
9452
var builder = new StringBuilder();
95-
var begin = @"using System.Collections.Generic;
53+
var begin = @"using System;
54+
using System.Collections.Generic;
55+
using System.Collections.ObjectModel;
9656
9757
namespace PuppeteerSharp.Mobile
9858
{
9959
/// <summary>
10060
/// Device descriptors.
10161
/// </summary>
102-
public class DeviceDescriptors
62+
public static class DeviceDescriptors
10363
{
10464
private static readonly Dictionary<DeviceDescriptorName, DeviceDescriptor> Devices = new Dictionary<DeviceDescriptorName, DeviceDescriptor>
10565
{
10666
";
10767
var end = @"
10868
};
10969
70+
private static Lazy<IReadOnlyDictionary<DeviceDescriptorName, DeviceDescriptor>> _readOnlyDevices =
71+
new Lazy<IReadOnlyDictionary<DeviceDescriptorName, DeviceDescriptor>>(() => new ReadOnlyDictionary<DeviceDescriptorName, DeviceDescriptor>(Devices));
72+
73+
internal static IReadOnlyDictionary<DeviceDescriptorName, DeviceDescriptor> ToReadOnly() => _readOnlyDevices.Value;
74+
11075
/// <summary>
11176
/// Get the specified device description.
11277
/// </summary>
11378
/// <returns>The device descriptor.</returns>
11479
/// <param name=""name"">Device Name.</param>
80+
[Obsolete(""Use Puppeteer.Devices instead"")]
11581
public static DeviceDescriptor Get(DeviceDescriptorName name) => Devices[name];
11682
}
11783
}";
@@ -123,7 +89,7 @@ public class DeviceDescriptors
12389
File.WriteAllText(deviceDescriptorsOutput, builder.ToString());
12490
}
12591

126-
static void WriteDeviceDescriptorName(IEnumerable<OutputDevice> devices)
92+
static void WriteDeviceDescriptorName(IEnumerable<Device> devices)
12793
{
12894
var builder = new StringBuilder();
12995
var begin = @"namespace PuppeteerSharp.Mobile
@@ -151,7 +117,7 @@ public enum DeviceDescriptorName
151117
File.WriteAllText(deviceDescriptorNameOutput, builder.ToString());
152118
}
153119

154-
static string GenerateCsharpFromDevice(OutputDevice device)
120+
static string GenerateCsharpFromDevice(Device device)
155121
{
156122
return $@" [DeviceDescriptorName.{DeviceNameToEnumValue(device)}] = new DeviceDescriptor
157123
{{
@@ -169,64 +135,27 @@ static string GenerateCsharpFromDevice(OutputDevice device)
169135
}}";
170136
}
171137

172-
static string DeviceNameToEnumValue(OutputDevice device)
138+
static string DeviceNameToEnumValue(Device device)
173139
{
140+
var dotNetName = device.Name.Replace("+", "Plus");
174141
var output = new StringBuilder();
175-
output.Append(char.ToUpper(device.Name[0]));
176-
for (var i = 1; i < device.Name.Length; i++)
142+
output.Append(char.ToUpper(dotNetName[0]));
143+
for (var i = 1; i < dotNetName.Length; i++)
177144
{
178-
if (char.IsWhiteSpace(device.Name[i]))
145+
if (char.IsWhiteSpace(dotNetName[i]))
179146
{
180-
output.Append(char.ToUpper(device.Name[i + 1]));
147+
output.Append(char.ToUpper(dotNetName[i + 1]));
181148
i++;
182149
}
183150
else
184151
{
185-
output.Append(device.Name[i]);
152+
output.Append(dotNetName[i]);
186153
}
187154
}
188155

189156
return output.ToString();
190157
}
191158

192-
static OutputDevice CreateDevice(string chromeVersion, string deviceName, RootObject.Device descriptor, bool landscape)
193-
{
194-
var devicePayload = LoadFromJSONV1(descriptor);
195-
var viewportPayload = landscape ? devicePayload.Horizontal : devicePayload.Vertical;
196-
return new OutputDevice
197-
{
198-
Name = deviceName + (landscape ? " landscape" : string.Empty),
199-
UserAgent = devicePayload.UserAgent.Replace("%s", chromeVersion),
200-
Viewport = new OutputDevice.OutputDeviceViewport
201-
{
202-
Width = viewportPayload.Width,
203-
Height = viewportPayload.Height,
204-
DeviceScaleFactor = devicePayload.DeviceScaleFactor,
205-
IsMobile = devicePayload.Capabilities.Contains("mobile"),
206-
HasTouch = devicePayload.Capabilities.Contains("touch"),
207-
IsLandscape = landscape
208-
}
209-
};
210-
}
211-
212-
static DevicePayload LoadFromJSONV1(RootObject.Device json) => new DevicePayload
213-
{
214-
Type = json.Type,
215-
UserAgent = json.UserAgent,
216-
Capabilities = json.Capabilities.ToHashSet(),
217-
DeviceScaleFactor = json.Screen.DevicePixelRatio,
218-
Horizontal = new ViewportPayload
219-
{
220-
Height = json.Screen.Horizontal.Height,
221-
Width = json.Screen.Horizontal.Width
222-
},
223-
Vertical = new ViewportPayload
224-
{
225-
Height = json.Screen.Vertical.Height,
226-
Width = json.Screen.Vertical.Width
227-
}
228-
};
229-
230159
static Task<string> HttpGET(string url) => new HttpClient().GetStringAsync(url);
231160
}
232161
}

lib/PuppeteerSharp.DevicesFetcher/PuppeteerSharp.DevicesFetcher.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>netcoreapp2.2</TargetFramework>
5+
<TargetFramework>net5.0</TargetFramework>
66
</PropertyGroup>
77
<ItemGroup>
88
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using Newtonsoft.Json;
2+
3+
namespace PuppeteerSharp.DevicesFetcher
4+
{
5+
public class ViewPort
6+
{
7+
[JsonProperty("width")]
8+
public int Width { get; set; }
9+
[JsonProperty("height")]
10+
public int Height { get; set; }
11+
12+
[JsonProperty("deviceScaleFactor")]
13+
public double DeviceScaleFactor { get; set; }
14+
15+
[JsonProperty("isMobile")]
16+
public bool IsMobile { get; set; }
17+
[JsonProperty("hasTouch")]
18+
public bool HasTouch { get; set; }
19+
[JsonProperty("isLandscape")]
20+
public bool IsLandscape { get; set; }
21+
}
22+
}

lib/PuppeteerSharp.DevicesFetcher/ViewportPayload.cs

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)