/*
* Copyright (c) 2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
using System;
using JavaScriptEngineSwitcher.Core;
using JavaScriptEngineSwitcher.Core.Helpers;
using Newtonsoft.Json;
using React.Exceptions;
namespace React
{
///
/// Various helper methods for the JavaScript engine environment.
///
public static class JavaScriptEngineUtils
{
///
/// Determines if the current environment supports the VroomJs engine.
///
/// true if VroomJs is supported
public static bool EnvironmentSupportsVroomJs()
{
return Environment.OSVersion.Platform == PlatformID.Unix;
}
///
/// Determines if the current environment supports the ClearScript V8 engine
///
/// true if ClearScript is supported
public static bool EnvironmentSupportsClearScript()
{
return Environment.OSVersion.Platform == PlatformID.Win32NT;
}
///
/// Attempts to use the specified engine and throws an exception if it doesn't work.
///
public static void EnsureEngineFunctional(
Func exceptionFactory
)
where TEngine : IJsEngine, new()
where TException : Exception
{
int result;
try
{
using (var engine = new TEngine())
{
result = engine.Evaluate("1 + 1");
}
}
catch (Exception ex)
{
throw exceptionFactory(ex);
}
if (result != 2)
{
throw new ReactException("Mathematics is broken. 1 + 1 = " + result);
}
}
///
/// Calls a JavaScript function using the specified engine. If is
/// not a scalar type, the function is assumed to return a string of JSON that can be
/// parsed as that type.
///
/// Type returned by function
/// Engine to execute function with
/// Name of the function to execute
/// Arguments to pass to function
/// Value returned by function
public static T CallFunctionReturningJson(this IJsEngine engine, string function, params object[] args)
{
if (ValidationHelpers.IsSupportedType(typeof(T)))
{
// Type is supported directly (ie. a scalar type like string/int/bool)
// Just execute the function directly.
return engine.CallFunction(function, args);
}
// The type is not a scalar type. Assume the function will return its result as
// JSON.
var resultJson = engine.CallFunction(function, args);
try
{
return JsonConvert.DeserializeObject(resultJson);
}
catch (JsonReaderException ex)
{
throw new ReactException(string.Format(
"{0} did not return valid JSON: {1}.\n\n{2}",
function, ex.Message, resultJson
));
}
}
}
}