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. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Jint; using Jint;
using Jint.Native; using Jint.Native;
using Jint.Native.Object; using Jint.Native.Object;
using Jint.Runtime;
using Jint.Runtime.Descriptors; using Jint.Runtime.Descriptors;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Infrastructure; using Squidex.Infrastructure;
@ -24,11 +27,11 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
private Dictionary<string, PropertyDescriptor> fieldProperties; private Dictionary<string, PropertyDescriptor> fieldProperties;
private bool isChanged; private bool isChanged;
public override bool Extensible => true;
public ContentDataObject(Engine engine, NamedContentData contentData) public ContentDataObject(Engine engine, NamedContentData contentData)
: base(engine) : base(engine)
{ {
Extensible = true;
this.contentData = contentData; this.contentData = contentData;
} }
@ -68,23 +71,27 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
return isChanged; return isChanged;
} }
public override void RemoveOwnProperty(string propertyName) public override void RemoveOwnProperty(JsValue property)
{ {
if (fieldsToDelete == null) if (fieldsToDelete == null)
{ {
fieldsToDelete = new HashSet<string>(); fieldsToDelete = new HashSet<string>();
} }
var propertyName = property.AsString();
fieldsToDelete.Add(propertyName); fieldsToDelete.Add(propertyName);
fieldProperties?.Remove(propertyName); fieldProperties?.Remove(propertyName);
MarkChanged(); MarkChanged();
} }
public override bool DefineOwnProperty(string propertyName, PropertyDescriptor desc, bool throwOnError) public override bool DefineOwnProperty(JsValue property, PropertyDescriptor desc)
{ {
EnsurePropertiesInitialized(); EnsurePropertiesInitialized();
var propertyName = property.AsString();
if (!fieldProperties.ContainsKey(propertyName)) if (!fieldProperties.ContainsKey(propertyName))
{ {
fieldProperties[propertyName] = new ContentDataProperty(this) { Value = desc.Value }; fieldProperties[propertyName] = new ContentDataProperty(this) { Value = desc.Value };
@ -93,25 +100,43 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
return true; return true;
} }
public override void Put(string propertyName, JsValue value, bool throwOnError) public override bool Set(JsValue property, JsValue value, JsValue receiver)
{ {
EnsurePropertiesInitialized(); EnsurePropertiesInitialized();
var propertyName = property.AsString();
fieldProperties.GetOrAdd(propertyName, this, (k, c) => new ContentDataProperty(c)).Value = value; 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(); 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))); 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(); EnsurePropertiesInitialized();
return fieldProperties; return fieldProperties.Keys.Select(x => (JsValue)x).ToList();
} }
private void EnsurePropertiesInitialized() 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()) foreach (var (key, propertyDescriptor) in obj.GetOwnProperties())
{ {
contentField.Put(key, propertyDescriptor.Value, true); contentField.Set(key, propertyDescriptor.Value);
} }
this.value = contentField; 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. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Jint;
using Jint.Native;
using Jint.Native.Object; using Jint.Native.Object;
using Jint.Runtime;
using Jint.Runtime.Descriptors; using Jint.Runtime.Descriptors;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Infrastructure; using Squidex.Infrastructure;
@ -19,7 +24,7 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
{ {
private readonly ContentDataObject contentData; private readonly ContentDataObject contentData;
private readonly ContentFieldData? fieldData; private readonly ContentFieldData? fieldData;
private HashSet<string> valuesToDelete; private HashSet<string>? valuesToDelete;
private Dictionary<string, PropertyDescriptor> valueProperties; private Dictionary<string, PropertyDescriptor> valueProperties;
private bool isChanged; private bool isChanged;
@ -28,12 +33,13 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
get { return fieldData; } get { return fieldData; }
} }
public override bool Extensible => true;
public ContentFieldObject(ContentDataObject contentData, ContentFieldData? fieldData, bool isNew) public ContentFieldObject(ContentDataObject contentData, ContentFieldData? fieldData, bool isNew)
: base(contentData.Engine) : base(contentData.Engine)
{ {
Extensible = true;
this.contentData = contentData; this.contentData = contentData;
this.fieldData = fieldData; this.fieldData = fieldData;
if (isNew) if (isNew)
@ -80,23 +86,35 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
return isChanged; return isChanged;
} }
public override void RemoveOwnProperty(string propertyName) public override void RemoveOwnProperty(JsValue property)
{ {
if (valuesToDelete == null) var propertyName = property.AsString();
{
valuesToDelete = new HashSet<string>();
}
valuesToDelete ??= new HashSet<string>();
valuesToDelete.Add(propertyName); valuesToDelete.Add(propertyName);
valueProperties?.Remove(propertyName); valueProperties?.Remove(propertyName);
MarkChanged(); 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(); EnsurePropertiesInitialized();
var propertyName = property.AsString();
if (!valueProperties.ContainsKey(propertyName)) if (!valueProperties.ContainsKey(propertyName))
{ {
valueProperties[propertyName] = new ContentFieldProperty(this) { Value = desc.Value }; valueProperties[propertyName] = new ContentFieldProperty(this) { Value = desc.Value };
@ -105,18 +123,32 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
return true; return true;
} }
public override PropertyDescriptor GetOwnProperty(string propertyName) public override PropertyDescriptor GetOwnProperty(JsValue property)
{ {
EnsurePropertiesInitialized(); EnsurePropertiesInitialized();
var propertyName = property.AsString();
if (propertyName.Equals("toJSON", StringComparison.OrdinalIgnoreCase))
{
return PropertyDescriptor.Undefined;
}
return valueProperties?.GetOrDefault(propertyName) ?? 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(); EnsurePropertiesInitialized();
return valueProperties; return valueProperties.Keys.Select(x => (JsValue)x).ToList();
} }
private void EnsurePropertiesInitialized() 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.FastAddProperty(key, Map(value, engine), false, true, true);
} }
target.PreventExtensions();
return target; return target;
} }
@ -103,7 +105,7 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper
var result = JsonValue.Array(); 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()))); 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()) foreach (var (key, propertyDescriptor) in obj.GetOwnProperties())
{ {
result[key] = Map(propertyDescriptor.Value); result[key.AsString()] = Map(propertyDescriptor.Value);
} }
return result; return result;

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

@ -8,6 +8,7 @@
using System; using System;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Jint;
using Jint.Native; using Jint.Native;
using Jint.Native.Json; using Jint.Native.Json;
using Jint.Runtime; using Jint.Runtime;
@ -51,16 +52,19 @@ namespace Squidex.Domain.Apps.Core.Scripting.Extensions
{ {
using (var httpClient = httpClientFactory.CreateClient()) using (var httpClient = httpClientFactory.CreateClient())
{ {
var request = CreateRequest(url, headers); using (var request = CreateRequest(url, headers))
var response = await httpClient.SendAsync(request, context.CancellationToken); {
using (var response = await httpClient.SendAsync(request, context.CancellationToken))
response.EnsureSuccessStatusCode(); {
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) catch (Exception ex)
@ -86,9 +90,11 @@ namespace Squidex.Domain.Apps.Core.Scripting.Extensions
{ {
var value = TypeConverter.ToString(property.Value); 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; 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(); var responseString = await response.Content.ReadAsStringAsync();
@ -110,4 +116,4 @@ namespace Squidex.Domain.Apps.Core.Scripting.Extensions
return jsonValue; 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 TimeSpan Expiration = TimeSpan.FromMinutes(10);
private static readonly ParserOptions DefaultParserOptions = new ParserOptions private static readonly ParserOptions DefaultParserOptions = new ParserOptions
{ {
AdaptRegexp = true, Tolerant = true, Loc = true AdaptRegexp = true,
Tolerant = true,
Loc = true
}; };
private readonly IMemoryCache memoryCache; private readonly IMemoryCache memoryCache;
@ -30,20 +32,20 @@ namespace Squidex.Domain.Apps.Core.Scripting.Internal
this.memoryCache = memoryCache; this.memoryCache = memoryCache;
} }
public Program Parse(string script) public Script Parse(string script)
{ {
var key = Key(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); 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) private static string Key(string script)
@ -51,4 +53,4 @@ namespace Squidex.Domain.Apps.Core.Scripting.Internal
return $"SCRIPT_{script}"; 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.Domain.Apps.Core.Scripting.Internal;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Json.Objects; using Squidex.Infrastructure.Json.Objects;
using Squidex.Infrastructure.Translations;
using Squidex.Infrastructure.Validation; using Squidex.Infrastructure.Validation;
namespace Squidex.Domain.Apps.Core.Scripting 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)); 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> <ItemGroup>
<PackageReference Include="Fluid.Core.Squidex" Version="1.0.0-beta" /> <PackageReference Include="Fluid.Core.Squidex" Version="1.0.0-beta" />
<PackageReference Include="HtmlAgilityPack" Version="1.11.24" /> <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="Markdig" Version="0.20.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="3.1.4" /> <PackageReference Include="Microsoft.Extensions.Http" Version="3.1.4" />
<PackageReference Include="Microsoft.OData.Core" Version="7.6.4" /> <PackageReference Include="Microsoft.OData.Core" Version="7.6.4" />

Loading…
Cancel
Save