Skip to content

Commit

Permalink
Added options for external JS file, and omit script tag
Browse files Browse the repository at this point in the history
  • Loading branch information
brooklynDev committed Dec 26, 2012
1 parent e182aef commit 4cd3bdc
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 9 deletions.
13 changes: 12 additions & 1 deletion NGon.SampleApplication/Global.asax.cs
@@ -1,11 +1,15 @@
using System.Web.Mvc;
using System.Web.DynamicData;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.SessionState;

namespace NGon.SampleApplication
{
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801



public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
Expand All @@ -17,6 +21,13 @@ public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");


//routes.MapRoute(
// "NGon",
// "ngon",
// new { controller = "DynamicNGonJavascriptController", action = "NGon", id = UrlParameter.Optional }, null,
// new[] { typeof(DynamicNGonJavascriptController).Namespace });

routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
Expand Down
4 changes: 3 additions & 1 deletion NGon.SampleApplication/Views/Shared/_Layout.cshtml
Expand Up @@ -5,7 +5,9 @@
<meta charset="utf-8" />
<title>@ViewBag.Title</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
@Html.IncludeNGon()
<script type="text/javascript">
@Html.IncludeNGon(outputScriptTag:false)
</script>
</head>

<body>
Expand Down
2 changes: 1 addition & 1 deletion NGon.SampleApplication/Views/Web.config
Expand Up @@ -28,7 +28,7 @@
<httpHandlers>
<add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/>
</httpHandlers>

<httpRuntime relaxedUrlToFileSystemMapping="true"/>
<!--
Enabling request validation in view pages would cause validation to occur
after the input has already been processed by the controller. By default
Expand Down
32 changes: 32 additions & 0 deletions NGon.Tests/NGonTests.cs
Expand Up @@ -102,5 +102,37 @@ public void MissingNGonInViewBagThrowsException()
//assert
Assert.Throws<InvalidOperationException>(() => _helper.IncludeNGon());
}

[Test]
public void OutputScriptTagFalseOmitsScriptTag()
{
//arrange
_controller.ViewBag.NGon.Foo = 100;

//act
var result = _helper.IncludeNGon(outputScriptTag: false);

//assert
var expected = "window.ngon={};ngon.Foo=100;";
var actual = result.ToString();
Assert.AreEqual(expected, actual);
}

[Test]
public void ExternalJsFileTrueOutputsExternalJSReference()
{
//arrange
_controller.ViewBag.NGon.Foo = 100;

//act
var result = _helper.IncludeNGon(useExternalJSFile: true);

//assert
var expected = @"<script src=""ngon.js"" type=""text/javascript""></script>";
var actual = result.ToString();
Assert.AreEqual(expected, actual);
}


}
}
67 changes: 61 additions & 6 deletions NGon/HtmlHelperExtensions.cs
Expand Up @@ -4,14 +4,61 @@
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.SessionState;
using Newtonsoft.Json;
using System.Linq;

namespace NGon
{
public class DynamicNGonJavascriptController : Controller
{
public DynamicNGonJavascriptController()
{
}

public ActionResult NGon(string data)
{
return JavaScript(data);
}
}


public static class HtmlHelperExtensions
{
public static IHtmlString IncludeNGon(this HtmlHelper helper, string @namespace = "ngon")
private const string ExternalJSRoute = "ngon.js";
private static void AddExternalJsFileRoute(HtmlHelper helper, string javascript)
{
var dynamicNGonRoute = new Route(ExternalJSRoute, new RouteValueDictionary(new { controller = "DynamicNGonJavascript", action = "NGon" }), new MvcRouteHandler());
if (!helper.RouteCollection.Cast<Route>().Any(r => r.Url == ExternalJSRoute))
{
helper.RouteCollection.Insert(0, dynamicNGonRoute);
}
else
{
dynamicNGonRoute = helper.RouteCollection.Cast<Route>().First(r => r.Url == ExternalJSRoute);
dynamicNGonRoute.Defaults.Remove("data");
}

dynamicNGonRoute.Defaults.Add("data", javascript);
}

private static string GetOutputJavascript(HtmlHelper helper, dynamic ngon, string @namespace)
{
var builder = new StringBuilder();
builder.AppendFormat("window.{0}={{}};", @namespace);

foreach (var prop in ngon)
{
builder.AppendFormat("{0}.{1}={2};", @namespace, prop.Key, helper.Raw(JsonConvert.SerializeObject(prop.Value)));
}

return builder.ToString();
}

public static IHtmlString IncludeNGon(this HtmlHelper helper, string @namespace = "ngon", bool useExternalJSFile = false, bool outputScriptTag = true)
{

var viewData = helper.ViewContext.ViewData;
if (viewData == null)
{
Expand All @@ -24,17 +71,25 @@ public static IHtmlString IncludeNGon(this HtmlHelper helper, string @namespace
throw new InvalidOperationException("Cannot find NGon in ViewBag. Did you remember to add the global NGonActionFilterAttribute?");
}

var outputJavascript = GetOutputJavascript(helper, ngon, @namespace);
if (!outputScriptTag)
{
return new HtmlString(outputJavascript);
}

var tag = new TagBuilder("script");
tag.Attributes.Add(new KeyValuePair<string, string>("type", "text/javascript"));
var builder = new StringBuilder();
builder.AppendFormat("window.{0}={{}};", @namespace);

foreach (var prop in ngon)
if (useExternalJSFile)
{
builder.AppendFormat("{0}.{1}={2};", @namespace, prop.Key, helper.Raw(JsonConvert.SerializeObject(prop.Value)));
AddExternalJsFileRoute(helper, outputJavascript);
tag.Attributes.Add("src", ExternalJSRoute);
}
else
{
tag.InnerHtml = outputJavascript;
}

tag.InnerHtml = builder.ToString();
return new HtmlString(tag.ToString());
}
}
Expand Down

0 comments on commit 4cd3bdc

Please sign in to comment.