├── .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 | --------------------------------------------------------------------------------