Skip to content

Commit b9b3ca5

Browse files
committed
Added the EmbedHostObject method (embeds a instance of simple class, structure or delegate to script code)
1 parent d5d52ca commit b9b3ca5

File tree

26 files changed

+883
-9
lines changed

26 files changed

+883
-9
lines changed

src/JavaScriptEngineSwitcher.Core/Helpers/ValidationHelpers.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,18 @@ public static class ValidationHelpers
1717
typeof(Undefined), typeof(Boolean), typeof(Int32), typeof(Double), typeof(String)
1818
};
1919

20+
/// <summary>
21+
/// List of primitive type codes
22+
/// </summary>
23+
private static readonly TypeCode[] _primitiveTypeCodes = new[]
24+
{
25+
TypeCode.Boolean,
26+
TypeCode.SByte, TypeCode.Byte,
27+
TypeCode.Int16, TypeCode.UInt16, TypeCode.Int32, TypeCode.UInt32, TypeCode.Int64, TypeCode.UInt64,
28+
TypeCode.Single, TypeCode.Double, TypeCode.Decimal,
29+
TypeCode.Char, TypeCode.String
30+
};
31+
2032
/// <summary>
2133
/// Regular expression for working with JS-names
2234
/// </summary>
@@ -35,6 +47,19 @@ public static bool IsSupportedType(Type type)
3547
return result;
3648
}
3749

50+
/// <summary>
51+
/// Checks whether .NET type is primitive
52+
/// </summary>
53+
/// <param name="type">.NET type</param>
54+
/// <returns>Result of check (true - is primitive; false - is not primitive)</returns>
55+
public static bool IsPrimitiveType(Type type)
56+
{
57+
TypeCode typeCode = Type.GetTypeCode(type);
58+
bool result = _primitiveTypeCodes.Contains(typeCode);
59+
60+
return result;
61+
}
62+
3863
/// <summary>
3964
/// Checks a format of the name
4065
/// </summary>

src/JavaScriptEngineSwitcher.Core/IJsEngine.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,5 +119,13 @@ string Version
119119
/// </summary>
120120
/// <param name="variableName">Variable name</param>
121121
void RemoveVariable(string variableName);
122+
123+
/// <summary>
124+
/// Embeds a host object to script code
125+
/// </summary>
126+
/// <param name="itemName">The name for the new global variable or function that will represent the object</param>
127+
/// <param name="value">The object to expose</param>
128+
/// <remarks>Allows to embed instances of simple classes (or structures) and delegates.</remarks>
129+
void EmbedHostObject(string itemName, object value);
122130
}
123131
}

src/JavaScriptEngineSwitcher.Core/JsEngineBase.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ protected void VerifyNotDisposed()
4747

4848
protected abstract void InnerRemoveVariable(string variableName);
4949

50+
protected virtual void InnerEmbedHostObject(string itemName, object value)
51+
{
52+
throw new NotImplementedException();
53+
}
54+
5055
#region IJsEngine implementation
5156

5257
public abstract string Name
@@ -361,6 +366,42 @@ public virtual void RemoveVariable(string variableName)
361366
InnerRemoveVariable(variableName);
362367
}
363368

369+
public virtual void EmbedHostObject(string itemName, object value)
370+
{
371+
VerifyNotDisposed();
372+
373+
if (string.IsNullOrWhiteSpace(itemName))
374+
{
375+
throw new ArgumentException(
376+
string.Format(Strings.Common_ArgumentIsEmpty, "itemName"), "itemName");
377+
}
378+
379+
if (!ValidationHelpers.CheckNameFormat(itemName))
380+
{
381+
throw new FormatException(
382+
string.Format(Strings.Runtime_InvalidScriptItemNameFormat, itemName));
383+
}
384+
385+
if (value != null)
386+
{
387+
Type itemType = value.GetType();
388+
389+
if (ValidationHelpers.IsPrimitiveType(itemType)
390+
|| itemType == typeof(Undefined)
391+
|| itemType == typeof(DateTime))
392+
{
393+
throw new NotSupportedTypeException(
394+
string.Format(Strings.Runtime_EmbeddedHostObjectTypeNotSupported, itemType.FullName));
395+
}
396+
}
397+
else
398+
{
399+
throw new ArgumentNullException("value", string.Format(Strings.Common_ArgumentIsNull, "value"));
400+
}
401+
402+
InnerEmbedHostObject(itemName, value);
403+
}
404+
364405
#endregion
365406

366407
#region IDisposable implementation

src/JavaScriptEngineSwitcher.Core/Resources/Strings.Designer.cs

Lines changed: 19 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/JavaScriptEngineSwitcher.Core/Resources/Strings.resx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,9 @@
183183
<data name="Resources_ResourceIsNull" xml:space="preserve">
184184
<value>Resource with name '{0}' is null.</value>
185185
</data>
186+
<data name="Runtime_EmbeddedHostObjectTypeNotSupported" xml:space="preserve">
187+
<value>The embedded host object '{0}' has a type `{1}`, which is not supported.</value>
188+
</data>
186189
<data name="Runtime_FunctionNameIsForbidden" xml:space="preserve">
187190
<value>The function name '{0}' is forbidden, as is contained in the list of reserved words of JavaScript language.</value>
188191
</data>
@@ -195,6 +198,9 @@
195198
<data name="Runtime_InvalidFunctionNameFormat" xml:space="preserve">
196199
<value>The function name '{0}' has incorrect format.</value>
197200
</data>
201+
<data name="Runtime_InvalidScriptItemNameFormat" xml:space="preserve">
202+
<value>The script item name '{0}' has incorrect format.</value>
203+
</data>
198204
<data name="Runtime_InvalidVariableNameFormat" xml:space="preserve">
199205
<value>The variable name '{0}' has incorrect format.</value>
200206
</data>

src/JavaScriptEngineSwitcher.Core/Resources/Strings.ru-ru.resx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,9 @@
183183
<data name="Resources_ResourceIsNull" xml:space="preserve">
184184
<value>Ресурс с именем "{0}" содержит значение равное null!</value>
185185
</data>
186+
<data name="Runtime_EmbeddedHostObjectTypeNotSupported" xml:space="preserve">
187+
<value>Встраиваемый объекта хоста "{0}" имеет тип `{1}`, который не поддерживается!</value>
188+
</data>
186189
<data name="Runtime_FunctionNameIsForbidden" xml:space="preserve">
187190
<value>Имя функции "{0}" запрещено, т.к. входит в список зарезервированных слов JavaScript!</value>
188191
</data>
@@ -195,6 +198,9 @@
195198
<data name="Runtime_InvalidFunctionNameFormat" xml:space="preserve">
196199
<value>Имя функции "{0}" имеет некорректный формат!</value>
197200
</data>
201+
<data name="Runtime_InvalidScriptItemNameFormat" xml:space="preserve">
202+
<value>Имя скриптового элемента "{0}" имеет некорректный формат!</value>
203+
</data>
198204
<data name="Runtime_InvalidVariableNameFormat" xml:space="preserve">
199205
<value>Имя переменной "{0}" имеет некорректный формат!</value>
200206
</data>

src/JavaScriptEngineSwitcher.Jint/JintJsEngine.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,20 @@ protected override void InnerRemoveVariable(string variableName)
414414
InnerSetVariableValue(variableName, Undefined.Value);
415415
}
416416

417+
protected override void InnerEmbedHostObject(string itemName, object value)
418+
{
419+
OriginalJsValue processedValue = MapToJintType(value);
420+
421+
try
422+
{
423+
_jsEngine.SetValue(itemName, processedValue);
424+
}
425+
catch (OriginalJsException e)
426+
{
427+
throw ConvertJavaScriptExceptionToJsRuntimeException(e);
428+
}
429+
}
430+
417431
#endregion
418432

419433
#region IDisposable implementation

src/JavaScriptEngineSwitcher.Jurassic/JurassicJsEngine.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,28 @@ protected override void InnerRemoveVariable(string variableName)
281281
InnerSetVariableValue(variableName, Undefined.Value);
282282
}
283283

284+
protected override void InnerEmbedHostObject(string itemName, object value)
285+
{
286+
object processedValue = MapToJurassicType(value);
287+
288+
try
289+
{
290+
var delegateValue = processedValue as Delegate;
291+
if (delegateValue != null)
292+
{
293+
_jsEngine.SetGlobalFunction(itemName, delegateValue);
294+
}
295+
else
296+
{
297+
_jsEngine.SetGlobalValue(itemName, processedValue);
298+
}
299+
}
300+
catch (OriginalJsException e)
301+
{
302+
throw ConvertJavascriptExceptionToJsRuntimeException(e);
303+
}
304+
}
305+
284306
public override void ExecuteFile(string path, Encoding encoding = null)
285307
{
286308
VerifyNotDisposed();

src/JavaScriptEngineSwitcher.Msie/JavaScriptEngineSwitcher.Msie.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@
4545
</ProjectReference>
4646
</ItemGroup>
4747
<ItemGroup>
48-
<Reference Include="MsieJavaScriptEngine, Version=1.6.0.0, Culture=neutral, PublicKeyToken=a3a2846a37ac0d3e, processorArchitecture=MSIL">
49-
<HintPath>..\..\packages\MsieJavaScriptEngine.1.6.0\lib\net40\MsieJavaScriptEngine.dll</HintPath>
48+
<Reference Include="MsieJavaScriptEngine, Version=1.7.0.0, Culture=neutral, PublicKeyToken=a3a2846a37ac0d3e, processorArchitecture=MSIL">
49+
<HintPath>..\..\packages\MsieJavaScriptEngine.1.7.0-alpha1\lib\net40\MsieJavaScriptEngine.dll</HintPath>
5050
<Private>True</Private>
5151
</Reference>
5252
<Reference Include="System" />

src/JavaScriptEngineSwitcher.Msie/MsieJsEngine.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,20 @@ protected override void InnerRemoveVariable(string variableName)
283283
}
284284
}
285285

286+
protected override void InnerEmbedHostObject(string itemName, object value)
287+
{
288+
object processedValue = MapToMsieType(value);
289+
290+
try
291+
{
292+
_jsEngine.EmbedHostObject(itemName, processedValue);
293+
}
294+
catch (OriginalJsRuntimeException e)
295+
{
296+
throw ConvertMsieJsRuntimeExceptionToJsRuntimeException(e);
297+
}
298+
}
299+
286300
#endregion
287301

288302
#region IDisposable implementation

0 commit comments

Comments
 (0)