Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/jameschch/Blazor.DynamicJavascriptRuntime.Evaluator
Execute dynamic object expressions as Javascript in Blazor
https://github.com/jameschch/Blazor.DynamicJavascriptRuntime.Evaluator
blazor dynamic javascript jsinterop razor wasm webassembly
Last synced: 10 days ago
JSON representation
Execute dynamic object expressions as Javascript in Blazor
- Host: GitHub
- URL: https://github.com/jameschch/Blazor.DynamicJavascriptRuntime.Evaluator
- Owner: jameschch
- License: apache-2.0
- Created: 2019-07-26T09:41:55.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2023-01-31T16:54:56.000Z (almost 2 years ago)
- Last Synced: 2024-06-28T11:10:17.396Z (4 months ago)
- Topics: blazor, dynamic, javascript, jsinterop, razor, wasm, webassembly
- Language: C#
- Homepage:
- Size: 59.6 KB
- Stars: 19
- Watchers: 2
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-blazor - Blazor.DynamicJavascriptRuntime.Evaluator - ![stars](https://img.shields.io/github/stars/jameschch/Blazor.DynamicJavascriptRuntime.Evaluator?style=flat-square&cacheSeconds=604800) ![last commit](https://img.shields.io/github/last-commit/jameschch/Blazor.DynamicJavascriptRuntime.Evaluator?style=flat-square&cacheSeconds=86400) Execute dynamic object expressions as Javascript in Blazor client-side apps. (Libraries & Extensions / Others)
README
# Blazor.DynamicJavascriptRuntime.Evaluator (A.K.A. Gasmask)
Wouldn't it be really useful if you could run a line or two of Javascript in your Blazor C# app?
Wouldn't it be handy if you could execute arbitrary Javascript at runtime without strings of script?
Wouldn't it be a big plus if the Javascript code was declared as a dynamic object expression and could be exposed to unit tests?
Wouldn't it be nice if you could consume Javascript library API's without creating interop wrappers?Calling Javascript dynamically from C# couldn't be easier:
```csharp
var context = (new EvalContext(JSRuntimeInstance) as dynamic).window.location = "www.github.com";
await (context as EvalContext).InvokeAsync();
//window.location = "www.github.com";
```...or with alternate syntax:
```csharp
using (dynamic context = new EvalContext(JSRuntimeInstance))
{
(context as EvalContext).Expression = () => context.window.location = "www.github.com";
//window.location = "www.github.com";
}
```When it comes to executing code with arguments, the C# parser will support this:
```csharp
using (dynamic context = new EvalContext(JSRuntimeInstance))
{
dynamic arg = new EvalContext(JSRuntimeInstance);
dynamic arg2 = new EvalContext(JSRuntimeInstance);
(context as EvalContext).Expression = () => context.Chart.config.data.datasets[arg.i].data.push(arg2.config.data.datasets[arg.i].data);
//Chart.config.data.datasets[i].data.push(config.data.datasets[i].data);
}
```Need to call some script that returns a value? No problem:
```csharp
dynamic context = new EvalContext(runtime.Object);
(context as EvalContext).Expression = () => context.document.cookie;
var cookie = await (context as EvalContext).InvokeAsync();
//document.cookie
```In order to satisfy the C# parser, an underscore ("_") can stand in for a space character in Javascript. This is disabled by default and you can configure your space placeholder:
```csharp
using (dynamic context = new EvalContext(JSRuntimeInstance))
{
var settings = new EvalContextSettings { EnableSpaceCharacterPlaceholderReplacement = true, SpaceCharacterPlaceholder = "_" };
dynamic arg = new EvalContext(JSRuntimeInstance, settings);
(context as EvalContext).Expression = () => context.var_instance = arg.new_object();
//var instance = new object();
}
```The dynamic expression is eagerly evaluated. This means decimal arithmetic will not be mangled by Javascript:
```csharp
using (dynamic context = new EvalContext(JSRuntimeInstance))
{
(context as EvalContext).Expression = () => context.sum = 0.1M + 0.2M * 0.5M / 0.5M;
//sum = 0.3;
}
```Maybe you feel like a bit of JQuery?
```csharp
using (dynamic context = new EvalContext(JsRuntime))
{
(context as EvalContext).Expression = () => context.jQuery("body").css("overflow-y", "hidden");
//jQuery("body").css("overflow-y", "hidden")
}
```
Sorry, no $ allowed.How about passing complex types as arguments? We've got you covered for anonymous types:
```csharp
using (dynamic context = new EvalContext(JsRuntime))
{
var arg = new { Property = "Value", Field = 123, Child = new { Member = new DateTime(2001, 1, 1) } };
(context as EvalContext).Expression = () => context.myScript.set(arg);
//myScript.set({"property":"Value","field":123,"child":{"member":"2001-01-01T00:00:00"}})
}
```Passing user-defined types takes more effort, but not too much:
```csharp
var settings = new EvalContextSettings();
settings.SerializableTypes.Add(typeof(Specified));
using (dynamic context = new EvalContext(JsRuntime, settings))
{
var arg = new Specified { Member = "abc" };
(context as EvalContext).Expression = () => context.myScript.setSpecified(arg);
//myScript.setSpecified({"member":"abc"})
}
```The execution of Javascript is performed with the eval() function, so it's imperative to sanitize user input that's passed into the Javascript runtime. You have been warned.
## Setup
First, install from nuget:
```
Install-Package DynamicJavascriptRuntime.Blazor.Evaluator
```[https://www.nuget.org/packages/DynamicJavascriptRuntime.Blazor.Evaluator/](https://www.nuget.org/packages/DynamicJavascriptRuntime.Blazor.Evaluator/)
You then need to add a script include to your index.htm:
```html
```## Syntax
The are a few different syntax options for dynamic expressions:
- The ```using``` blocks wrapping the EvalContext are optional but prevent forgotten calls to Invoke.
- Setting the ```Expression``` property is optional. You can chain an expression directly on the EvalContext e.g.:
```csharp
dynamic context = new EvalContext();
context.alert("Gasmask");
await (context as EvalContext).InvokeVoidAsync()
```
- You can chain multiple javascript calls on separate lines with a single EvalContext. This makes sense for some "fluent" libraries like jQuery.