Skip to content

Instantly share code, notes, and snippets.

@SamSaffron
Created February 15, 2012 23:10
Show Gist options
  • Save SamSaffron/1839917 to your computer and use it in GitHub Desktop.
Save SamSaffron/1839917 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Text;
using System.Web.WebPages;
namespace StackOverflow.Helpers
{
public static class DeferJS
{
const string builderKey = "SCRIPT_BUILDER";
const string builderEnabledKey = "SCRIPT_BUILDER_ENABLED";
class ScriptBuilder
{
List<string> LayoutScripts = new List<string>();
List<string> Scripts = new List<string>();
bool layoutStarted = false;
public void Add(string script)
{
if (layoutStarted)
{
LayoutScripts.Add(script);
}
else
{
Scripts.Add(script);
}
}
public void MarkLayoutStart()
{
// once the template starts we need to add scripts to a second list, templates are rendered after internal views
layoutStarted = true;
}
public void MarkLayoutBodyRendered()
{
layoutStarted = false;
}
public string ToString()
{
return string.Join("", LayoutScripts) + string.Join("", Scripts);
}
}
public static bool Enabled
{
get
{
return (bool?)HttpContext.Current.Items[builderEnabledKey] == true;
}
set
{
HttpContext.Current.Items[builderEnabledKey] = value;
}
}
private static ScriptBuilder GetScriptBuilder()
{
var builder = HttpContext.Current.Items[builderKey] as ScriptBuilder;
if (builder == null)
{
HttpContext.Current.Items[builderKey] = builder = new ScriptBuilder();
}
return builder;
}
public static HelperResult AppendJs(this WebPageBase page, Func<object, HelperResult> stuff)
{
if (Enabled)
{
var builder = GetScriptBuilder();
builder.Add(stuff(null).ToHtmlString());
return new HelperResult(_ => {});
}
else
{
return stuff(null);
}
}
public static IHtmlString AppendJs(this WebPageBase page, IHtmlString stuff)
{
if (Enabled)
{
var builder = GetScriptBuilder();
builder.Add(stuff.ToString());
return "".AsHtml();
}
else
{
return stuff;
}
}
public static void MarkLayoutStart()
{
if (Enabled)
{
GetScriptBuilder().MarkLayoutStart();
}
}
// called when the body is done rendering
public static void MarkLayoutBodyRendered()
{
if (Enabled)
{
GetScriptBuilder().MarkLayoutBodyRendered();
}
}
public static IHtmlString RenderJs(this WebPageBase page)
{
if (Enabled)
{
return new MvcHtmlString(GetScriptBuilder().ToString());
}
else
{
return "".AsHtml();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment