LSTANCZYK
3/21/2017 - 4:55 PM

[C#][MVC] Minify inline scripts and styles

[C#][MVC] Minify inline scripts and styles

  public class MinifyInlineScriptsAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var originalFilter = filterContext.HttpContext.Response.Filter;
            if(originalFilter != null) filterContext.HttpContext.Response.Filter = new MinifyStream(originalFilter);

            base.OnActionExecuting(filterContext);
        }

        private class MinifyStream : MemoryStream
        {
            private readonly Stream _responseStream;

            public MinifyStream(Stream stream)
            {
                _responseStream = stream;
            }

            public override void Write(byte[] buffer, int offset, int count)
            {
                string html = Encoding.UTF8.GetString(buffer);

                var sb = new StringBuilder(html);
                MinifyScripts(sb);
                MinifyStyles(sb);


                buffer = Encoding.UTF8.GetBytes(sb.ToString());
                _responseStream.Write(buffer, offset, buffer.Length);
            }

            private void MinifyScripts(StringBuilder html)
            {
                var regex = new Regex("<script[^/>]*>(?<content>.*?)</script>", RegexOptions.IgnoreCase | RegexOptions.Singleline);
                var matches = regex.Matches(html.ToString());

                foreach (Match match in matches)
                {
                    var content = match.Groups["content"];
                    if (content != null && content.Success && !String.IsNullOrWhiteSpace(content.Value))
                    {
                        var minifier = new Minifier();
                        var minifiedJs = minifier.MinifyJavaScript(content.Value);
                        html.Replace(content.Value, minifiedJs);
                    }

                }
            }

            private void MinifyStyles(StringBuilder html)
            {
                var regex = new Regex("<style[^/>]*>(?<content>.*?)</style>", RegexOptions.IgnoreCase | RegexOptions.Singleline);
                var matches = regex.Matches(html.ToString());

                foreach (Match match in matches)
                {
                    var content = match.Groups["content"];
                    if (content != null && content.Success && !String.IsNullOrWhiteSpace(content.Value))
                    {
                        var minifier = new Minifier();
                        var minifiedCss = minifier.MinifyStyleSheet(content.Value);
                        html.Replace(content.Value, minifiedCss);
                    }

                }
            }
        }
    }