├── .gitattributes
├── .gitignore
├── .hgignore
├── Placement.info
├── packages.config
├── Module.txt
├── Views
└── EditorTemplates
│ └── Parts.ScriptJs.cshtml
├── Drivers
└── ScriptPartDriver.cs
├── Services
├── TypeFactory.cs
└── JavaScriptRuntime.cs
├── IJavaScriptRuntimeEventHandler.cs
├── Properties
└── AssemblyInfo.cs
├── Licence.md
├── Readme.md
├── Web.config
└── OrchardHUN.Scripting.JavaScript.csproj
/.gitattributes:
--------------------------------------------------------------------------------
1 | * -crlf
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | obj/
2 | bin/
3 | *.user
4 |
--------------------------------------------------------------------------------
/.hgignore:
--------------------------------------------------------------------------------
1 | syntax: glob
2 | obj/
3 | bin/
4 | *.user
5 |
--------------------------------------------------------------------------------
/Placement.info:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Module.txt:
--------------------------------------------------------------------------------
1 | Name: Orchard Scripting Extensions: JavaScript
2 | AntiForgery: enabled
3 | Author: The Orchard Hungary Team / Lombiq
4 | Website: https://github.com/Lombiq/Orchard-Scripting-Extensions-JavaScript
5 | Version: 1.0
6 | OrchardVersion: 1.10.1
7 | Description: Enables Orchard scripting through JavaScript. Uses Javascript.NET (https://github.com/JavascriptNet/Javascript.Net).
8 | Features:
9 | OrchardHUN.Scripting.JavaScript:
10 | Name: Orchard Scripting Extensions: JavaScript
11 | Description: Enables Orchard scripting through JavaScript. Uses Javascript.NET (https://github.com/JavascriptNet/Javascript.Net/).
12 | Category: Scripting
13 | Dependencies: OrchardHUN.Scripting, JavaScript.NET
--------------------------------------------------------------------------------
/Views/EditorTemplates/Parts.ScriptJs.cshtml:
--------------------------------------------------------------------------------
1 | @model OrchardHUN.Scripting.Models.ScriptPart
2 |
3 | @using (Script.Foot())
4 | {
5 |
18 | }
--------------------------------------------------------------------------------
/Drivers/ScriptPartDriver.cs:
--------------------------------------------------------------------------------
1 | using Orchard.ContentManagement;
2 | using Orchard.ContentManagement.Drivers;
3 | using OrchardHUN.Scripting.Models;
4 |
5 | namespace OrchardHUN.Scripting.JavaScript.Drivers
6 | {
7 | public class ScriptPartDriver : ContentPartDriver
8 | {
9 | protected override string Prefix
10 | {
11 | get { return "OrchardHUN.Scripting.ScriptPart"; }
12 | }
13 |
14 | protected override DriverResult Editor(ScriptPart part, dynamic shapeHelper)
15 | {
16 | return ContentShape("Parts_ScriptJs_Edit",
17 | () => shapeHelper.EditorTemplate(
18 | TemplateName: "Parts.ScriptJs",
19 | Model: part,
20 | Prefix: Prefix));
21 | }
22 |
23 | protected override DriverResult Editor(ScriptPart part, IUpdateModel updater, dynamic shapeHelper)
24 | {
25 | return Editor(part, shapeHelper);
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/Services/TypeFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using OrchardHUN.Scripting.Exceptions;
6 |
7 | namespace OrchardHUN.Scripting.JavaScript.Services
8 | {
9 | public class TypeFactory
10 | {
11 | private readonly Dictionary _types;
12 |
13 |
14 | public TypeFactory(IEnumerable assemblies)
15 | {
16 | _types = new Dictionary();
17 |
18 | // .ToDictionary() doesn't work as there can be duplicate full names (but how?)
19 | var types = assemblies.SelectMany(assembly => assembly.GetTypes());
20 | foreach (var type in types)
21 | {
22 | _types[type.FullName] = type;
23 | }
24 | }
25 |
26 |
27 | public object Create(string typeName, object[] ctorArguments = null)
28 | {
29 | if (String.IsNullOrEmpty(typeName) || !_types.ContainsKey(typeName))
30 | throw new ScriptRuntimeException("The type " + typeName + " was not found in any assembly loaded into the script scope.");
31 |
32 | return Activator.CreateInstance(_types[typeName], ctorArguments);
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/IJavaScriptRuntimeEventHandler.cs:
--------------------------------------------------------------------------------
1 | using Noesis.Javascript;
2 | using Orchard.Events;
3 | using OrchardHUN.Scripting.Services;
4 |
5 | namespace OrchardHUN.Scripting.JavaScript
6 | {
7 | public interface IJavaScriptRuntimeEventHandler : IEventHandler
8 | {
9 | void BeforeExecution(BeforeJavaScriptExecutionContext context);
10 | void AfterExecution(AfterJavaScriptExecutionContext context);
11 | }
12 |
13 | public abstract class JavaScriptScriptingEventContext
14 | {
15 | public ScriptScope Scope { get; set; }
16 | public JavascriptContext Context { get; private set; }
17 |
18 | protected JavaScriptScriptingEventContext(ScriptScope scope, JavascriptContext context)
19 | {
20 | Scope = scope;
21 | Context = context;
22 | }
23 | }
24 |
25 | public class BeforeJavaScriptExecutionContext : JavaScriptScriptingEventContext
26 | {
27 | public BeforeJavaScriptExecutionContext(ScriptScope scope, JavascriptContext context)
28 | : base(scope, context)
29 | {
30 | }
31 | }
32 |
33 | public class AfterJavaScriptExecutionContext : JavaScriptScriptingEventContext
34 | {
35 | public AfterJavaScriptExecutionContext(ScriptScope scope, JavascriptContext context)
36 | : base(scope, context)
37 | {
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 | using System.Security;
5 |
6 | // General Information about an assembly is controlled through the following
7 | // set of attributes. Change these attribute values to modify the information
8 | // associated with an assembly.
9 | [assembly: AssemblyTitle("OrchardHUN.Scripting.JavaScript")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyProduct("Orchard")]
13 | [assembly: AssemblyCopyright("")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("afe4ff1e-2903-4526-b238-f4f66b9c6bc6")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Revision and Build Numbers
33 | // by using the '*' as shown below:
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
37 |
--------------------------------------------------------------------------------
/Licence.md:
--------------------------------------------------------------------------------
1 | Copyright © 2015, [Lombiq Technologies Ltd.](https://lombiq.com)
2 |
3 | All rights reserved.
4 |
5 | For more information and requests about licensing please [contact us through our website](https://lombiq.com/contact-us).
6 |
7 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
10 |
11 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
12 |
13 | * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
14 |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # Orchard Scripting Extensions: JavaScript
2 |
3 |
4 |
5 | ## About
6 |
7 | A child module for Orchard Scripting Extensions for running JavaScript code inside Orchard.
8 |
9 |
10 | ## Documentation
11 |
12 | **This module depends on [JavaScript.Net Orchard](https://github.com/Lombiq/Orchard-JavaScript.Net) and [Orchard Scripting Extensions](https://github.com/Lombiq/Orchard-Scripting-Extensions). It uses many of the latter's features. Please install it first!** (And also read [that module's docs](https://github.com/Lombiq/Orchard-Scripting-Extensions) to see what you can do with it - and through it, with JavaScript).
13 | JavaScript execution goes through the excellent [Javascript .NET library](http://javascriptdotnet.codeplex.com/).
14 | Samples
15 |
16 | var hello = "Hello JavaScript!";
17 | hello; // The last statement will be the output of the script
18 |
19 | // You can instantiate types that were loaded to the script context through the Factory object
20 | var obj = Factory.Create("System.Object", null);
21 | obj.ToString(); // Outputs "System.Object"
22 |
23 | // There is an Orchard global variable that you can add fields to. By default it contains a WorkContext field with the Orchard WorkContext and an OrchardServices field with an IOrchardServices instance
24 | Orchard.WorkContext.CurrentSite.SiteName;
25 |
26 | // This adds the string "Hello!' to the markup of the layout's Body zone (this will just show up in the html source!).
27 | Orchard.Layout.Get("Body").Add("Hello!");
28 |
29 |
30 | ## Contributing and support
31 |
32 | Bug reports, feature requests, comments, questions, code contributions, and love letters are warmly welcome, please do so via GitHub issues and pull requests. Please adhere to our [open-source guidelines](https://lombiq.com/open-source-guidelines) while doing so.
33 |
34 | This project is developed by [Lombiq Technologies](https://lombiq.com/). Commercial-grade support is available through Lombiq.
--------------------------------------------------------------------------------
/Services/JavaScriptRuntime.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using Noesis.Javascript;
5 | using Orchard;
6 | using Orchard.Environment;
7 | using Orchard.Exceptions;
8 | using OrchardHUN.Scripting.Exceptions;
9 | using OrchardHUN.Scripting.Services;
10 |
11 | namespace OrchardHUN.Scripting.JavaScript.Services
12 | {
13 | public class JavaScriptRuntime : IScriptingRuntime
14 | {
15 | private readonly IJavaScriptRuntimeEventHandler _eventHandler;
16 | private readonly Work _wcaWork;
17 |
18 | private readonly IEngineDescriptor _descriptor = new EngineDescriptor("JS", new Orchard.Localization.LocalizedString("JavaScript"));
19 | public IEngineDescriptor Descriptor
20 | {
21 | get { return _descriptor; }
22 | }
23 |
24 |
25 | public JavaScriptRuntime(IJavaScriptRuntimeEventHandler eventHandler, Work wcaWork)
26 | {
27 | _eventHandler = eventHandler;
28 | _wcaWork = wcaWork;
29 | }
30 |
31 |
32 | public dynamic ExecuteExpression(string expression, ScriptScope scope)
33 | {
34 | try
35 | {
36 | using (var context = new JavascriptContext())
37 | {
38 | foreach (var variable in scope.Variables)
39 | {
40 | context.SetParameter(variable.Key, variable.Value);
41 | }
42 |
43 | context.SetParameter("Factory", new TypeFactory(scope.Assemblies));
44 |
45 | var workContext = _wcaWork.Value.GetContext();
46 | var orchardGlobal = new Dictionary();
47 | orchardGlobal["WorkContext"] = workContext;
48 | orchardGlobal["OrchardServices"] = workContext.Resolve();
49 | orchardGlobal["Layout"] = new StaticShape(workContext.Layout);
50 |
51 | var existing = scope.GetVariable("Orchard");
52 | if (existing != null)
53 | {
54 | if (!(existing is IDictionary)) throw new ArgumentException("The Orchard global variable should be an IDictionary.");
55 |
56 | var existingDictionary = existing as IDictionary;
57 | foreach (var existingItem in existingDictionary)
58 | {
59 | orchardGlobal[existingItem.Key] = existingItem.Value;
60 | }
61 | }
62 |
63 | context.SetParameter("Orchard", orchardGlobal);
64 |
65 | _eventHandler.BeforeExecution(new BeforeJavaScriptExecutionContext(scope, context));
66 | var output = context.Run(expression);
67 | _eventHandler.AfterExecution(new AfterJavaScriptExecutionContext(scope, context));
68 |
69 | foreach (var variableName in scope.Variables.Select(kvp => kvp.Key))
70 | {
71 | scope.SetVariable(variableName, context.GetParameter(variableName));
72 | }
73 |
74 | return output;
75 | }
76 | }
77 | catch (Exception ex)
78 | {
79 | if (ex.IsFatal()) throw;
80 |
81 | throw new ScriptRuntimeException("The JavaScript script could not be executed.", ex);
82 | }
83 | }
84 | }
85 | }
--------------------------------------------------------------------------------
/Web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/OrchardHUN.Scripting.JavaScript.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | 9.0.30729
8 | 2.0
9 | {87908286-6B0C-449D-A44F-CA54A9FA93F2}
10 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
11 | Library
12 | Properties
13 | OrchardHUN.Scripting.JavaScript
14 | OrchardHUN.Scripting.JavaScript
15 | v4.5.2
16 | true
17 |
18 | 4.0
19 |
20 |
21 | false
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | true
30 | full
31 | false
32 | bin\
33 | DEBUG;TRACE
34 | prompt
35 | 4
36 | ..\..\..\OrchardBasicCorrectness.ruleset
37 | false
38 |
39 |
40 | pdbonly
41 | true
42 | bin\
43 | TRACE
44 | prompt
45 | 4
46 | AllRules.ruleset
47 | false
48 |
49 |
50 |
51 |
52 | ..\Javascript.NET\Libs\Noesis.Javascript.dll
53 |
54 |
55 |
56 |
57 | 3.5
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | ..\..\..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll
72 | True
73 |
74 |
75 | ..\..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll
76 | True
77 |
78 |
79 | ..\..\..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll
80 | True
81 |
82 |
83 | ..\..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll
84 | True
85 |
86 |
87 | ..\..\..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll
88 | True
89 |
90 |
91 | ..\..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll
92 | True
93 |
94 |
95 | ..\..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll
96 | True
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | {2d1d92bb-4555-4cbe-8d0e-63563d6ce4c6}
108 | Orchard.Framework
109 | false
110 |
111 |
112 | {9916839c-39fc-4ceb-a5af-89ca7e87119f}
113 | Orchard.Core
114 | false
115 |
116 |
117 | {c8715027-a8c5-45dc-8a22-fb713af14468}
118 | OrchardHUN.Scripting
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 | 10.0
135 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
136 |
137 |
138 |
139 |
140 |
144 |
145 |
146 | $(ProjectDir)\..\Manifests
147 |
148 |
151 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 | False
164 | True
165 | 45979
166 | /
167 |
168 | False
169 | True
170 | http://orchard.codeplex.com
171 | False
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
--------------------------------------------------------------------------------