Browse Source

Jint changes backported.

release/4.5 4.5.2
Sebastian 6 years ago
parent
commit
68b5b418d9
  1. 43
      backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/ContentDataObject.cs
  2. 2
      backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/ContentDataProperty.cs
  3. 58
      backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/ContentFieldObject.cs
  4. 6
      backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/JsonMapper.cs
  5. 28
      backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Extensions/HttpJintExtension.cs
  6. 16
      backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Internal/Parser.cs
  7. 7
      backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptEngine.cs
  8. 2
      backend/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj

43
backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/ContentDataObject.cs

@ -5,10 +5,13 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using Jint;
using Jint.Native;
using Jint.Native.Object;
using Jint.Runtime;
using Jint.Runtime.Descriptors;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Infrastructure;
@ -24,11 +27,11 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
private Dictionary<string, PropertyDescriptor> fieldProperties;
private bool isChanged;
public override bool Extensible => true;
public ContentDataObject(Engine engine, NamedContentData contentData)
: base(engine)
{
Extensible = true;
this.contentData = contentData;
}
@ -68,23 +71,27 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
return isChanged;
}
public override void RemoveOwnProperty(string propertyName)
public override void RemoveOwnProperty(JsValue property)
{
if (fieldsToDelete == null)
{
fieldsToDelete = new HashSet<string>();
}
var propertyName = property.AsString();
fieldsToDelete.Add(propertyName);
fieldProperties?.Remove(propertyName);
MarkChanged();
}
public override bool DefineOwnProperty(string propertyName, PropertyDescriptor desc, bool throwOnError)
public override bool DefineOwnProperty(JsValue property, PropertyDescriptor desc)
{
EnsurePropertiesInitialized();
var propertyName = property.AsString();
if (!fieldProperties.ContainsKey(propertyName))
{
fieldProperties[propertyName] = new ContentDataProperty(this) { Value = desc.Value };
@ -93,25 +100,43 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
return true;
}
public override void Put(string propertyName, JsValue value, bool throwOnError)
public override bool Set(JsValue property, JsValue value, JsValue receiver)
{
EnsurePropertiesInitialized();
var propertyName = property.AsString();
fieldProperties.GetOrAdd(propertyName, this, (k, c) => new ContentDataProperty(c)).Value = value;
return true;
}
public override PropertyDescriptor GetOwnProperty(string propertyName)
public override PropertyDescriptor GetOwnProperty(JsValue property)
{
EnsurePropertiesInitialized();
var propertyName = property.AsString();
if (propertyName.Equals("toJSON", StringComparison.OrdinalIgnoreCase))
{
return PropertyDescriptor.Undefined;
}
return fieldProperties.GetOrAdd(propertyName, this, (k, c) => new ContentDataProperty(c, new ContentFieldObject(c, new ContentFieldData(), false)));
}
public override IEnumerable<KeyValuePair<string, PropertyDescriptor>> GetOwnProperties()
public override IEnumerable<KeyValuePair<JsValue, PropertyDescriptor>> GetOwnProperties()
{
EnsurePropertiesInitialized();
return fieldProperties.Select(x => new KeyValuePair<JsValue, PropertyDescriptor>(x.Key, x.Value));
}
public override List<JsValue> GetOwnPropertyKeys(Types types = Types.String | Types.Symbol)
{
EnsurePropertiesInitialized();
return fieldProperties;
return fieldProperties.Keys.Select(x => (JsValue)x).ToList();
}
private void EnsurePropertiesInitialized()
@ -127,4 +152,4 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
}
}
}
}
}

2
backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/ContentDataProperty.cs

@ -38,7 +38,7 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
foreach (var (key, propertyDescriptor) in obj.GetOwnProperties())
{
contentField.Put(key, propertyDescriptor.Value, true);
contentField.Set(key, propertyDescriptor.Value);
}
this.value = contentField;

58
backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/ContentFieldObject.cs

@ -5,8 +5,13 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using Jint;
using Jint.Native;
using Jint.Native.Object;
using Jint.Runtime;
using Jint.Runtime.Descriptors;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Infrastructure;
@ -19,7 +24,7 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
{
private readonly ContentDataObject contentData;
private readonly ContentFieldData? fieldData;
private HashSet<string> valuesToDelete;
private HashSet<string>? valuesToDelete;
private Dictionary<string, PropertyDescriptor> valueProperties;
private bool isChanged;
@ -28,12 +33,13 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
get { return fieldData; }
}
public override bool Extensible => true;
public ContentFieldObject(ContentDataObject contentData, ContentFieldData? fieldData, bool isNew)
: base(contentData.Engine)
{
Extensible = true;
this.contentData = contentData;
this.fieldData = fieldData;
if (isNew)
@ -80,23 +86,35 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
return isChanged;
}
public override void RemoveOwnProperty(string propertyName)
public override void RemoveOwnProperty(JsValue property)
{
if (valuesToDelete == null)
{
valuesToDelete = new HashSet<string>();
}
var propertyName = property.AsString();
valuesToDelete ??= new HashSet<string>();
valuesToDelete.Add(propertyName);
valueProperties?.Remove(propertyName);
MarkChanged();
}
public override bool DefineOwnProperty(string propertyName, PropertyDescriptor desc, bool throwOnError)
public override bool Set(JsValue property, JsValue value, JsValue receiver)
{
EnsurePropertiesInitialized();
var propertyName = property.AsString();
valueProperties.GetOrAdd(propertyName, k => new ContentFieldProperty(this)).Value = value;
return true;
}
public override bool DefineOwnProperty(JsValue property, PropertyDescriptor desc)
{
EnsurePropertiesInitialized();
var propertyName = property.AsString();
if (!valueProperties.ContainsKey(propertyName))
{
valueProperties[propertyName] = new ContentFieldProperty(this) { Value = desc.Value };
@ -105,18 +123,32 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
return true;
}
public override PropertyDescriptor GetOwnProperty(string propertyName)
public override PropertyDescriptor GetOwnProperty(JsValue property)
{
EnsurePropertiesInitialized();
var propertyName = property.AsString();
if (propertyName.Equals("toJSON", StringComparison.OrdinalIgnoreCase))
{
return PropertyDescriptor.Undefined;
}
return valueProperties?.GetOrDefault(propertyName) ?? PropertyDescriptor.Undefined;
}
public override IEnumerable<KeyValuePair<string, PropertyDescriptor>> GetOwnProperties()
public override IEnumerable<KeyValuePair<JsValue, PropertyDescriptor>> GetOwnProperties()
{
EnsurePropertiesInitialized();
return valueProperties.Select(x => new KeyValuePair<JsValue, PropertyDescriptor>(x.Key, x.Value));
}
public override List<JsValue> GetOwnPropertyKeys(Types types = Types.String | Types.Symbol)
{
EnsurePropertiesInitialized();
return valueProperties;
return valueProperties.Keys.Select(x => (JsValue)x).ToList();
}
private void EnsurePropertiesInitialized()
@ -135,4 +167,4 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
}
}
}
}
}

6
backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/JsonMapper.cs

@ -62,6 +62,8 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
target.FastAddProperty(key, Map(value, engine), false, true, true);
}
target.PreventExtensions();
return target;
}
@ -103,7 +105,7 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
var result = JsonValue.Array();
for (var i = 0; i < arr.GetLength(); i++)
for (var i = 0; i < arr.Length; i++)
{
result.Add(Map(arr.Get(i.ToString())));
}
@ -119,7 +121,7 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
foreach (var (key, propertyDescriptor) in obj.GetOwnProperties())
{
result[key] = Map(propertyDescriptor.Value);
result[key.AsString()] = Map(propertyDescriptor.Value);
}
return result;

28
backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Extensions/HttpJintExtension.cs

@ -8,6 +8,7 @@
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Jint;
using Jint.Native;
using Jint.Native.Json;
using Jint.Runtime;
@ -51,16 +52,19 @@ namespace Squidex.Domain.Apps.Core.Scripting.Extensions
{
using (var httpClient = httpClientFactory.CreateClient())
{
var request = CreateRequest(url, headers);
var response = await httpClient.SendAsync(request, context.CancellationToken);
response.EnsureSuccessStatusCode();
using (var request = CreateRequest(url, headers))
{
using (var response = await httpClient.SendAsync(request, context.CancellationToken))
{
response.EnsureSuccessStatusCode();
var responseObject = await ParseResponse(context, response);
var responseObject = await ParseResponse(context, response);
context.Engine.ResetTimeoutTicks();
context.Engine.ResetConstraints();
callback(responseObject);
callback(responseObject);
}
}
}
}
catch (Exception ex)
@ -86,9 +90,11 @@ namespace Squidex.Domain.Apps.Core.Scripting.Extensions
{
var value = TypeConverter.ToString(property.Value);
if (!string.IsNullOrWhiteSpace(key))
var keyString = key.AsString();
if (!string.IsNullOrWhiteSpace(keyString))
{
request.Headers.TryAddWithoutValidation(key, value ?? string.Empty);
request.Headers.TryAddWithoutValidation(keyString, value ?? string.Empty);
}
}
}
@ -96,7 +102,7 @@ namespace Squidex.Domain.Apps.Core.Scripting.Extensions
return request;
}
private async Task<JsValue> ParseResponse(ExecutionContext context, HttpResponseMessage response)
private static async Task<JsValue> ParseResponse(ExecutionContext context, HttpResponseMessage response)
{
var responseString = await response.Content.ReadAsStringAsync();
@ -110,4 +116,4 @@ namespace Squidex.Domain.Apps.Core.Scripting.Extensions
return jsonValue;
}
}
}
}

16
backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Internal/Parser.cs

@ -18,7 +18,9 @@ namespace Squidex.Domain.Apps.Core.Scripting.Internal
private static readonly TimeSpan Expiration = TimeSpan.FromMinutes(10);
private static readonly ParserOptions DefaultParserOptions = new ParserOptions
{
AdaptRegexp = true, Tolerant = true, Loc = true
AdaptRegexp = true,
Tolerant = true,
Loc = true
};
private readonly IMemoryCache memoryCache;
@ -30,20 +32,20 @@ namespace Squidex.Domain.Apps.Core.Scripting.Internal
this.memoryCache = memoryCache;
}
public Program Parse(string script)
public Script Parse(string script)
{
var key = Key(script);
if (!memoryCache.TryGetValue<Program>(key, out var program))
if (!memoryCache.TryGetValue<Script>(key, out var compiledScript))
{
var parser = new JavaScriptParser(script, DefaultParserOptions);
program = parser.ParseProgram();
compiledScript = parser.ParseScript();
memoryCache.Set(key, program, Expiration);
memoryCache.Set(key, compiledScript, Expiration);
}
return program;
return compiledScript;
}
private static string Key(string script)
@ -51,4 +53,4 @@ namespace Squidex.Domain.Apps.Core.Scripting.Internal
return $"SCRIPT_{script}";
}
}
}
}

7
backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptEngine.cs

@ -20,6 +20,7 @@ using Squidex.Domain.Apps.Core.Scripting.ContentWrapper;
using Squidex.Domain.Apps.Core.Scripting.Internal;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Json.Objects;
using Squidex.Infrastructure.Translations;
using Squidex.Infrastructure.Validation;
namespace Squidex.Domain.Apps.Core.Scripting
@ -189,6 +190,10 @@ namespace Squidex.Domain.Apps.Core.Scripting
{
throw new ValidationException($"Failed to execute script with javascript error: {ex.Message}", new ValidationError(ex.Message));
}
catch (DomainException)
{
throw;
}
}
}
}
}

2
backend/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj

@ -18,7 +18,7 @@
<ItemGroup>
<PackageReference Include="Fluid.Core.Squidex" Version="1.0.0-beta" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.24" />
<PackageReference Include="Jint" Version="3.0.0-beta-1580" />
<PackageReference Include="Jint" Version="3.0.0-beta-1884" />
<PackageReference Include="Markdig" Version="0.20.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="3.1.4" />
<PackageReference Include="Microsoft.OData.Core" Version="7.6.4" />

Loading…
Cancel
Save