Skip to content

Commit

Permalink
We don't need no dynamics (#823)
Browse files Browse the repository at this point in the history
  • Loading branch information
kblok authored Dec 31, 2018
1 parent 82fd27e commit a3f809f
Show file tree
Hide file tree
Showing 25 changed files with 316 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,8 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp2.0;net471</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<LangVersion>7.2</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<LangVersion>7.2</LangVersion>
<TargetFrameworks>netcoreapp2.2;net471</TargetFrameworks>
<LangVersion>7.3</LangVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)'=='net471'">
<RuntimeIdentifier>win7-x64</RuntimeIdentifier>
Expand Down
10 changes: 2 additions & 8 deletions demos/PuppeteerSharpPdfDemo/PuppeteerSharpPdfDemo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,8 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<LangVersion>7.2</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<LangVersion>7.2</LangVersion>
<TargetFramework>netcoreapp2.2</TargetFramework>
<LangVersion>7.3</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PuppeteerSharp" Version="1.0.1" />
Expand Down
14 changes: 7 additions & 7 deletions lib/PuppeteerSharp/CDPSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace PuppeteerSharp
{
/// <summary>
/// The CDPSession instances are used to talk raw Chrome Devtools Protocol:
/// * Protocol methods can be called with <see cref="CDPSession.SendAsync(string, dynamic, bool)"/> method.
/// * Protocol methods can be called with <see cref="CDPSession.SendAsync(string, object, bool)"/> method.
/// * Protocol events, using the <see cref="CDPSession.MessageReceived"/> event.
///
/// Documentation on DevTools Protocol can be found here: <see href="https://chromedevtools.github.io/devtools-protocol/"/>.
Expand Down Expand Up @@ -106,7 +106,7 @@ internal CDPSession(IConnection connection, TargetType targetType, string sessio

#region Public Methods

internal void Send(string method, dynamic args = null)
internal void Send(string method, object args = null)
=> _ = SendAsync(method, args, false);

/// <summary>
Expand All @@ -115,9 +115,9 @@ internal void Send(string method, dynamic args = null)
/// <param name="method">The method name</param>
/// <param name="args">The method args</param>
/// <returns>The task.</returns>
public async Task<T> SendAsync<T>(string method, dynamic args = null)
public async Task<T> SendAsync<T>(string method, object args = null)
{
JObject content = await SendAsync(method, args).ConfigureAwait(false);
var content = await SendAsync(method, args).ConfigureAwait(false);

return content.ToObject<T>(true);
}
Expand All @@ -133,7 +133,7 @@ public async Task<T> SendAsync<T>(string method, dynamic args = null)
/// </param>
/// <returns>The task.</returns>
/// <exception cref="PuppeteerSharp.PuppeteerException"></exception>
public async Task<JObject> SendAsync(string method, dynamic args = null, bool waitForCallback = true)
public async Task<JObject> SendAsync(string method, object args = null, bool waitForCallback = true)
{
if (Connection == null)
{
Expand All @@ -150,7 +150,7 @@ public async Task<JObject> SendAsync(string method, dynamic args = null, bool wa
{ MessageKeys.Params, args }
}, JsonHelper.DefaultJsonSerializerSettings);

_logger.LogTrace("Send ► {Id} Method {Method} Params {@Params}", id, method, (object)args);
_logger.LogTrace("Send ► {Id} Method {Method} Params {@Params}", id, method, args);

MessageTask callback = null;
if (waitForCallback)
Expand Down Expand Up @@ -310,7 +310,7 @@ internal CDPSession CreateSession(TargetType targetType, string sessionId)
#region IConnection
ILoggerFactory IConnection.LoggerFactory => LoggerFactory;
bool IConnection.IsClosed => IsClosed;
Task<JObject> IConnection.SendAsync(string method, dynamic args, bool waitForCallback)
Task<JObject> IConnection.SendAsync(string method, object args, bool waitForCallback)
=> SendAsync(method, args, waitForCallback);
IConnection IConnection.Connection => Connection;
void IConnection.Close(string closeReason) => Close(closeReason);
Expand Down
8 changes: 4 additions & 4 deletions lib/PuppeteerSharp/Connection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ internal Connection(string url, int delay, IConnectionTransport transport, ILogg

#region Public Methods

internal async Task<JObject> SendAsync(string method, dynamic args = null, bool waitForCallback = true)
internal async Task<JObject> SendAsync(string method, object args = null, bool waitForCallback = true)
{
if (IsClosed)
{
Expand Down Expand Up @@ -119,9 +119,9 @@ internal async Task<JObject> SendAsync(string method, dynamic args = null, bool
return waitForCallback ? await callback.TaskWrapper.Task.WithConnectionCheck(this).ConfigureAwait(false) : null;
}

internal async Task<T> SendAsync<T>(string method, dynamic args = null)
internal async Task<T> SendAsync<T>(string method, object args = null)
{
JToken response = await SendAsync(method, args).ConfigureAwait(false);
var response = await SendAsync(method, args).ConfigureAwait(false);
return response.ToObject<T>(true);
}

Expand Down Expand Up @@ -305,7 +305,7 @@ public void Dispose()
#region IConnection
ILoggerFactory IConnection.LoggerFactory => LoggerFactory;
bool IConnection.IsClosed => IsClosed;
Task<JObject> IConnection.SendAsync(string method, dynamic args, bool waitForCallback)
Task<JObject> IConnection.SendAsync(string method, object args, bool waitForCallback)
=> SendAsync(method, args, waitForCallback);
IConnection IConnection.Connection => null;
void IConnection.Close(string closeReason) => Close(closeReason);
Expand Down
10 changes: 5 additions & 5 deletions lib/PuppeteerSharp/ElementHandle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class ElementHandle : JSHandle
internal ElementHandle(
ExecutionContext context,
CDPSession client,
JToken remoteObject,
RemoteObject remoteObject,
Page page,
FrameManager frameManager) :
base(context, client, remoteObject)
Expand Down Expand Up @@ -198,7 +198,7 @@ public async Task ClickAsync(ClickOptions options = null)
public Task UploadFileAsync(params string[] filePaths)
{
var files = filePaths.Select(Path.GetFullPath).ToArray();
var objectId = RemoteObject[MessageKeys.ObjectId].AsString();
var objectId = RemoteObject.ObjectId;
return Client.SendAsync("DOM.setFileInputFiles", new { objectId, files });
}

Expand Down Expand Up @@ -386,7 +386,7 @@ public async Task<Frame> ContentFrameAsync()
{
var nodeInfo = await Client.SendAsync<DomDescribeNodeResponse>("DOM.describeNode", new Dictionary<string, object>
{
{ MessageKeys.ObjectId, RemoteObject[MessageKeys.ObjectId] }
{ MessageKeys.ObjectId, RemoteObject.ObjectId }
}).ConfigureAwait(false);

return string.IsNullOrEmpty(nodeInfo.Node.FrameId) ? null : await _frameManager.GetFrameAsync(nodeInfo.Node.FrameId);
Expand Down Expand Up @@ -419,7 +419,7 @@ public Task<bool> IsIntersectingViewportAsync()
{
result = await Client.SendAsync<GetContentQuadsResponse>("DOM.getContentQuads", new Dictionary<string, object>
{
{ MessageKeys.ObjectId, RemoteObject[MessageKeys.ObjectId] }
{ MessageKeys.ObjectId, RemoteObject.ObjectId }
}).ConfigureAwait(false);
}
catch (Exception ex)
Expand Down Expand Up @@ -491,7 +491,7 @@ private async Task<BoxModelResponse> GetBoxModelAsync()
{
return await Client.SendAsync<BoxModelResponse>("DOM.getBoxModel", new
{
objectId = RemoteObject[MessageKeys.ObjectId].AsString()
objectId = RemoteObject.ObjectId
}).ConfigureAwait(false);
}
catch (PuppeteerException ex)
Expand Down
2 changes: 1 addition & 1 deletion lib/PuppeteerSharp/EvaluationFailedException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace PuppeteerSharp
{
/// <summary>
/// Exception thrown by <see cref="ExecutionContext.EvaluateHandleAsync(string, dynamic)"/>.
/// Exception thrown by <see cref="ExecutionContext.EvaluateHandleAsync(string, object)"/>.
/// </summary>
[Serializable]
public class EvaluationFailedException : PuppeteerException
Expand Down
23 changes: 12 additions & 11 deletions lib/PuppeteerSharp/ExecutionContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Newtonsoft.Json.Linq;
using PuppeteerSharp.Messaging;
using PuppeteerSharp.Helpers;
using static PuppeteerSharp.Messaging.RuntimeQueryObjectsResponse;

namespace PuppeteerSharp
{
Expand Down Expand Up @@ -111,17 +112,17 @@ public async Task<JSHandle> QueryObjectsAsync(JSHandle prototypeHandle)
throw new PuppeteerException("Prototype JSHandle is disposed!");
}

if (!((JObject)prototypeHandle.RemoteObject).TryGetValue(MessageKeys.ObjectId, out var objectId))
if (prototypeHandle.RemoteObject.ObjectId == null)
{
throw new PuppeteerException("Prototype JSHandle must not be referencing primitive value");
}

var response = await _client.SendAsync("Runtime.queryObjects", new Dictionary<string, object>
var response = await _client.SendAsync<RuntimeQueryObjectsResponse>("Runtime.queryObjects", new Dictionary<string, object>
{
{"prototypeObjectId", objectId.ToString()}
{"prototypeObjectId", prototypeHandle.RemoteObject.ObjectId}
}).ConfigureAwait(false);

return CreateJSHandle(response[MessageKeys.Objects]);
return CreateJSHandle(response.Objects);
}

internal async Task<JSHandle> EvaluateExpressionHandleAsync(string script)
Expand Down Expand Up @@ -173,8 +174,8 @@ internal async Task<JSHandle> EvaluateFunctionHandleAsync(string script, params
}
}

internal JSHandle CreateJSHandle(dynamic remoteObject)
=> (remoteObject.subtype == "node" && Frame != null)
internal JSHandle CreateJSHandle(RemoteObject remoteObject)
=> remoteObject.Subtype == RemoteObjectSubtype.Node && Frame != null
? new ElementHandle(this, _client, remoteObject, Frame.FrameManager.Page, Frame.FrameManager)
: new JSHandle(this, _client, remoteObject);

Expand All @@ -201,17 +202,17 @@ private async Task<T> EvaluateAsync<T>(Task<JSHandle> handleEvaluator)
return result is JToken token && token.Type == JTokenType.Null ? default : result;
}

private async Task<JSHandle> EvaluateHandleAsync(string method, dynamic args)
private async Task<JSHandle> EvaluateHandleAsync(string method, object args)
{
var response = await _client.SendAsync(method, args).ConfigureAwait(false);
var response = await _client.SendAsync<EvaluateHandleResponse>(method, args).ConfigureAwait(false);

if (response[MessageKeys.ExceptionDetails] is JToken exceptionDetails)
if (response.ExceptionDetails != null)
{
throw new EvaluationFailedException("Evaluation failed: " +
GetExceptionMessage(exceptionDetails.ToObject<EvaluateExceptionResponseDetails>(true)));
GetExceptionMessage(response.ExceptionDetails));
}

return CreateJSHandle(response.result);
return CreateJSHandle(response.Result);
}

private object FormatArgument(object arg)
Expand Down
7 changes: 2 additions & 5 deletions lib/PuppeteerSharp/Helpers/FlexibleStringEnumConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,9 @@ namespace PuppeteerSharp.Helpers
{
internal class FlexibleStringEnumConverter : StringEnumConverter
{
private Enum _fallbackValue;
private readonly Enum _fallbackValue;

public FlexibleStringEnumConverter(Enum fallbackValue)
{
_fallbackValue = fallbackValue;
}
public FlexibleStringEnumConverter(Enum fallbackValue) => _fallbackValue = fallbackValue;

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
Expand Down
26 changes: 12 additions & 14 deletions lib/PuppeteerSharp/Helpers/RemoteObjectHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ namespace PuppeteerSharp.Helpers
{
internal class RemoteObjectHelper
{
internal static object ValueFromRemoteObject<T>(JToken remoteObject)
internal static object ValueFromRemoteObject<T>(RemoteObject remoteObject)
{
var unserializableValue = remoteObject[MessageKeys.UnserializableValue]?.AsString();
var unserializableValue = remoteObject.UnserializableValue;

if (unserializableValue != null)
{
Expand All @@ -29,45 +29,43 @@ internal static object ValueFromRemoteObject<T>(JToken remoteObject)
}
}

var value = remoteObject[MessageKeys.Value];
var value = remoteObject.Value;

if (value == null)
{
return null;
}

// https://chromedevtools.github.io/devtools-protocol/tot/Runtime#type-RemoteObject
var objectType = remoteObject[MessageKeys.Type].AsString();
var objectType = remoteObject.Type;

switch (objectType)
{
case "object":
case RemoteObjectType.Object:
return value.ToObject<T>(true);
case "undefined":
case RemoteObjectType.Undefined:
return null;
case "number":
case RemoteObjectType.Number:
return value.Value<T>();
case "boolean":
case RemoteObjectType.Boolean:
return value.Value<bool>();
case "bigint":
case RemoteObjectType.Bigint:
return value.Value<double>();
default: // string, symbol, function
return value.ToObject<T>();
}
}

internal static async Task ReleaseObject(CDPSession client, JToken remoteObject, ILogger logger)
internal static async Task ReleaseObjectAsync(CDPSession client, RemoteObject remoteObject, ILogger logger)
{
var objectId = remoteObject[MessageKeys.ObjectId]?.AsString();

if (objectId == null)
if (remoteObject.ObjectId == null)
{
return;
}

try
{
await client.SendAsync("Runtime.releaseObject", new { objectId }).ConfigureAwait(false);
await client.SendAsync("Runtime.releaseObject", new { remoteObject.ObjectId }).ConfigureAwait(false);
}
catch (Exception ex)
{
Expand Down
2 changes: 1 addition & 1 deletion lib/PuppeteerSharp/IConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ internal interface IConnection
/// If <c>true</c> the method will return a task to be completed when the message is confirmed by Chromium.
/// If <c>false</c> the task will be considered complete after sending the message to Chromium.
/// </param>
Task<JObject> SendAsync(string method, dynamic args = null, bool waitForCallback = true);
Task<JObject> SendAsync(string method, object args = null, bool waitForCallback = true);
/// <summary>
/// Gets the parent connection
/// </summary>
Expand Down
Loading

0 comments on commit a3f809f

Please sign in to comment.