From edf6ca5505e957c26e341e5462157b747a74f1ac Mon Sep 17 00:00:00 2001 From: Cezar Cretu Date: Mon, 5 Jan 2015 10:15:22 +0200 Subject: [PATCH] added the ability to customize entry point resolution (#31) --- .../DefaultEntryPointResolver.cs | 83 +++++++++++++++++++ .../EntryPointResolver/IEntryPointResolver.cs | 13 +++ .../RequireEntryPointResolverCollection.cs | 58 +++++++++++++ RequireJsNet/Helpers/HtmlHelpers.cs | 11 +-- RequireJsNet/RequireJsHtmlHelpers.cs | 66 +-------------- RequireJsNet/RequireJsNet.csproj | 3 + RequireJsNet/RequireJsOptions.cs | 8 ++ 7 files changed, 174 insertions(+), 68 deletions(-) create mode 100644 RequireJsNet/EntryPointResolver/DefaultEntryPointResolver.cs create mode 100644 RequireJsNet/EntryPointResolver/IEntryPointResolver.cs create mode 100644 RequireJsNet/EntryPointResolver/RequireEntryPointResolverCollection.cs diff --git a/RequireJsNet/EntryPointResolver/DefaultEntryPointResolver.cs b/RequireJsNet/EntryPointResolver/DefaultEntryPointResolver.cs new file mode 100644 index 0000000..2058fc7 --- /dev/null +++ b/RequireJsNet/EntryPointResolver/DefaultEntryPointResolver.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Web; +using System.Web.Mvc; +using RequireJsNet.Helpers; + +namespace RequireJsNet.EntryPointResolver +{ + public class DefaultEntryPointResolver : IEntryPointResolver + { + private const string DefaultEntryPointRoot = "~/Scripts/"; + private const string DefaultArea = "Common"; + + public string Resolve(ViewContext viewContext, string entryPointRoot) + { + var routingInfo = viewContext.GetRoutingInfo(); + var rootUrl = string.Empty; + var withBaseUrl = true; + var server = viewContext.HttpContext.Server; + + if (entryPointRoot != DefaultEntryPointRoot) + { + withBaseUrl = false; + rootUrl = UrlHelper.GenerateContentUrl(entryPointRoot, viewContext.HttpContext); + } + + // search for controller/action.js in current area + var entryPointTmpl = "Controllers/{0}/" + routingInfo.Controller + "/" + routingInfo.Action; + var entryPoint = string.Format(entryPointTmpl, routingInfo.Area).ToModuleName(); + var filePath = server.MapPath(entryPointRoot + entryPoint + ".js"); + + if (File.Exists(filePath)) + { + var computedEntry = GetEntryPoint(server, filePath, entryPointRoot); + return withBaseUrl ? computedEntry : rootUrl + computedEntry; + } + + // search for controller/action.js in common area + entryPoint = string.Format(entryPointTmpl, DefaultArea).ToModuleName(); + filePath = server.MapPath(entryPointRoot + entryPoint + ".js"); + + if (File.Exists(filePath)) + { + var computedEntry = GetEntryPoint(server, filePath, entryPointRoot); + return withBaseUrl ? computedEntry : rootUrl + computedEntry; + } + + // search for controller/controller-action.js in current area + entryPointTmpl = "Controllers/{0}/" + routingInfo.Controller + "/" + routingInfo.Controller + "-" + routingInfo.Action; + entryPoint = string.Format(entryPointTmpl, routingInfo.Area).ToModuleName(); + filePath = server.MapPath(entryPointRoot + entryPoint + ".js"); + + if (File.Exists(filePath)) + { + var computedEntry = GetEntryPoint(server, filePath, entryPointRoot); + return withBaseUrl ? computedEntry : rootUrl + computedEntry; + } + + // search for controller/controller-action.js in common area + entryPoint = string.Format(entryPointTmpl, DefaultArea).ToModuleName(); + filePath = server.MapPath(entryPointRoot + entryPoint + ".js"); + + if (File.Exists(filePath)) + { + var computedEntry = GetEntryPoint(server, filePath, entryPointRoot); + return withBaseUrl ? computedEntry : rootUrl + computedEntry; + } + + return null; + } + + private static string GetEntryPoint(HttpServerUtilityBase server, string filePath, string root) + { + + var fileName = PathHelpers.GetExactFilePath(filePath); + var folder = server.MapPath(root); + return PathHelpers.GetRequireRelativePath(folder, fileName); + } + } +} diff --git a/RequireJsNet/EntryPointResolver/IEntryPointResolver.cs b/RequireJsNet/EntryPointResolver/IEntryPointResolver.cs new file mode 100644 index 0000000..a614ad3 --- /dev/null +++ b/RequireJsNet/EntryPointResolver/IEntryPointResolver.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web.Mvc; + +namespace RequireJsNet.EntryPointResolver +{ + public interface IEntryPointResolver + { + string Resolve(ViewContext viewContext, string entryPointRoot); + } +} diff --git a/RequireJsNet/EntryPointResolver/RequireEntryPointResolverCollection.cs b/RequireJsNet/EntryPointResolver/RequireEntryPointResolverCollection.cs new file mode 100644 index 0000000..2e9a622 --- /dev/null +++ b/RequireJsNet/EntryPointResolver/RequireEntryPointResolverCollection.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web.Mvc; +using RequireJsNet.EntryPointResolver; + +namespace RequireJsNet +{ + public class RequireEntryPointResolverCollection + { + private List resolvers = new List(); + + public void Clear() + { + lock (resolvers) + { + resolvers.Clear(); + } + + } + + public void Prepend(IEntryPointResolver resolver) + { + lock (resolvers) + { + resolvers.Insert(0, resolver); + } + } + + public void Add(IEntryPointResolver resolver) + { + lock (resolvers) + { + resolvers.Add(resolver); + } + } + + internal string Resolve(ViewContext viewContext, string entryPointRoot) + { + string result = null; + + lock (resolvers) + { + foreach (var resolver in resolvers) + { + result = resolver.Resolve(viewContext, entryPointRoot); + if (result != null) + { + break; + } + } + } + + return result; + } + } +} diff --git a/RequireJsNet/Helpers/HtmlHelpers.cs b/RequireJsNet/Helpers/HtmlHelpers.cs index a5a0692..aff5845 100644 --- a/RequireJsNet/Helpers/HtmlHelpers.cs +++ b/RequireJsNet/Helpers/HtmlHelpers.cs @@ -5,6 +5,7 @@ // http://www.opensource.org/licenses/mit-license.php // http://www.gnu.org/licenses/gpl.html +using System.Web; using System.Web.Mvc; using RequireJsNet.Models; @@ -13,14 +14,14 @@ namespace RequireJsNet.Helpers { internal static class HtmlHelpers { - public static RoutingInfo GetRoutingInfo(this HtmlHelper html) + public static RoutingInfo GetRoutingInfo(this ViewContext viewContext) { - var area = html.ViewContext.RouteData.DataTokens["area"] != null - ? html.ViewContext.RouteData.DataTokens["area"].ToString() + var area = viewContext.RouteData.DataTokens["area"] != null + ? viewContext.RouteData.DataTokens["area"].ToString() : "Root"; - var controller = html.ViewContext.Controller.ValueProvider.GetValue("controller").RawValue as string; - var action = html.ViewContext.Controller.ValueProvider.GetValue("action").RawValue as string; + var controller = viewContext.Controller.ValueProvider.GetValue("controller").RawValue as string; + var action = viewContext.Controller.ValueProvider.GetValue("action").RawValue as string; return new RoutingInfo { Area = area, diff --git a/RequireJsNet/RequireJsHtmlHelpers.cs b/RequireJsNet/RequireJsHtmlHelpers.cs index c1f0462..3021e0f 100644 --- a/RequireJsNet/RequireJsHtmlHelpers.cs +++ b/RequireJsNet/RequireJsHtmlHelpers.cs @@ -21,9 +21,6 @@ namespace RequireJsNet public static class RequireJsHtmlHelpers { - private const string DefaultEntryPointRoot = "~/Scripts/"; - private const string DefaultArea = "Common"; - /// /// Setup RequireJS to be used in layouts /// @@ -136,60 +133,9 @@ public static MvcHtmlString RenderRequireJsSetup( /// public static MvcHtmlString RequireJsEntryPoint(this HtmlHelper html, string root) { - var routingInfo = html.GetRoutingInfo(); - var rootUrl = string.Empty; - var withBaseUrl = true; - var server = html.ViewContext.HttpContext.Server; - - if (root != DefaultEntryPointRoot) - { - withBaseUrl = false; - rootUrl = UrlHelper.GenerateContentUrl(root, html.ViewContext.HttpContext); - } - - // search for controller/action.js in current area - var entryPointTmpl = "Controllers/{0}/" + routingInfo.Controller + "/" + routingInfo.Action; - var entryPoint = string.Format(entryPointTmpl, routingInfo.Area).ToModuleName(); - var filePath = server.MapPath(root + entryPoint + ".js"); - - if (File.Exists(filePath)) - { - var computedEntry = GetEntryPoint(server, filePath, root); - return new MvcHtmlString(withBaseUrl ? computedEntry : rootUrl + computedEntry + ".js"); - } - - // search for controller/action.js in common area - entryPoint = string.Format(entryPointTmpl, DefaultArea).ToModuleName(); - filePath = server.MapPath(root + entryPoint + ".js"); - - if (File.Exists(filePath)) - { - var computedEntry = GetEntryPoint(server, filePath, root); - return new MvcHtmlString(withBaseUrl ? computedEntry : rootUrl + computedEntry + ".js"); - } + var result = RequireJsOptions.ResolverCollection.Resolve(html.ViewContext, root); - // search for controller/controller-action.js in current area - entryPointTmpl = "Controllers/{0}/" + routingInfo.Controller + "/" + routingInfo.Controller + "-" + routingInfo.Action; - entryPoint = string.Format(entryPointTmpl, routingInfo.Area).ToModuleName(); - filePath = server.MapPath(root + entryPoint + ".js"); - - if (File.Exists(filePath)) - { - var computedEntry = GetEntryPoint(server, filePath, root); - return new MvcHtmlString(withBaseUrl ? computedEntry : rootUrl + computedEntry + ".js"); - } - - // search for controller/controller-action.js in common area - entryPoint = string.Format(entryPointTmpl, DefaultArea).ToModuleName(); - filePath = server.MapPath(root + entryPoint + ".js"); - - if (File.Exists(filePath)) - { - var computedEntry = GetEntryPoint(server, filePath, root); - return new MvcHtmlString(withBaseUrl ? computedEntry : rootUrl + computedEntry + ".js"); - } - - return null; + return result != null ? new MvcHtmlString(result) : null; } public static Dictionary ToJsonDictionary() @@ -199,12 +145,6 @@ public static Dictionary ToJsonDictionary() } - private static string GetEntryPoint(HttpServerUtilityBase server, string filePath, string root) - { - - var fileName = PathHelpers.GetExactFilePath(filePath); - var folder = server.MapPath(root); - return PathHelpers.GetRequireRelativePath(folder, fileName); - } + } } \ No newline at end of file diff --git a/RequireJsNet/RequireJsNet.csproj b/RequireJsNet/RequireJsNet.csproj index 2579cc0..85626e4 100644 --- a/RequireJsNet/RequireJsNet.csproj +++ b/RequireJsNet/RequireJsNet.csproj @@ -86,6 +86,8 @@ + + @@ -107,6 +109,7 @@ + diff --git a/RequireJsNet/RequireJsOptions.cs b/RequireJsNet/RequireJsOptions.cs index 37d659f..d8f10bc 100644 --- a/RequireJsNet/RequireJsOptions.cs +++ b/RequireJsNet/RequireJsOptions.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using System.Linq; using System.Web; +using RequireJsNet.EntryPointResolver; namespace RequireJsNet { @@ -24,6 +25,13 @@ public static class RequireJsOptions private const string PageOptionsKey = "pageOptions"; + public static readonly RequireEntryPointResolverCollection ResolverCollection = new RequireEntryPointResolverCollection(); + + static RequireJsOptions() + { + ResolverCollection.Add(new DefaultEntryPointResolver()); + } + public static Dictionary GetGlobalOptions(HttpContextBase context) { var page = context.Items[GlobalOptionsKey] as Dictionary;