/// <summary>
        /// Produces a code minifiction of CSS assets by using WebGrease Semantic CSS minifier
        /// </summary>
        /// <param name="assets">Set of CSS assets</param>
        /// <returns>Set of CSS assets with minified text content</returns>
        public IList <IAsset> Minify(IList <IAsset> assets)
        {
            if (assets == null)
            {
                throw new ArgumentNullException(
                          nameof(assets),
                          string.Format(CoreStrings.Common_ArgumentIsNull, nameof(assets))
                          );
            }

            if (assets.Count == 0)
            {
                return(assets);
            }

            var assetsToProcessing = assets.Where(a => a.IsStylesheet && !a.Minified).ToList();

            if (assetsToProcessing.Count == 0)
            {
                return(assets);
            }

            var wgCssMinifier = new CssMinifier(new WebGreaseContext(_wgConfiguration))
            {
                ShouldMinify = ShouldMinify
            };

            foreach (var asset in assetsToProcessing)
            {
                InnerMinify(asset, wgCssMinifier);
            }

            return(assets);
        }
Beispiel #2
0
        /// <summary>
        /// Minifies the specified resource.
        /// </summary>
        /// <param name="resource">The resource.</param>
        /// <returns>The minified resource.</returns>
        public override string Minify(string resource)
        {
            CssMinifier minifier;

            if (this.Options.Minify)
            {
                minifier = new CssMinifier
                {
                    RemoveWhiteSpace = true
                };
            }
            else
            {
                minifier = new CssMinifier
                {
                    RemoveWhiteSpace = false
                };
            }

            string result = minifier.Minify(resource);

            if (this.Options.CacheFiles)
            {
                this.AddItemToCache(this.Options.MinifyCacheKey, result);
            }

            return(result);
        }
Beispiel #3
0
        /// <summary>
        /// Runs the CSS minifier on the content.
        /// </summary>
        public static IAsset MinifyCss(this IAsset asset, CssSettings settings)
        {
            var minifier = new CssMinifier(settings);

            asset.Processors.Add(minifier);

            return(asset);
        }
Beispiel #4
0
        public void MinifyComplexCaseTest()
        {
            var minifier = new CssMinifier(new WebGreaseContext(new WebGreaseConfiguration()));
            var filePath = Path.Combine(TestDeploymentPaths.TestDirectory, @"css.tests\css30\sites\vsteam\jquery-combined.css");
            var css      = File.ReadAllText(filePath);
            var actual   = minifier.Minify(css);

            Assert.IsTrue(actual.Length < css.Length);
        }
Beispiel #5
0
        public void MinifierErrorsTest()
        {
            var badCss   = "p {color:red;}\r\np {margin: 10px}\r\np {width: }\r\nbody margin: 1em;}";
            var minifier = new CssMinifier(new WebGreaseContext(new WebGreaseConfiguration()));
            var output   = minifier.Minify(badCss);

            Assert.IsTrue(minifier.Errors.Count > 0);
            Assert.IsTrue(minifier.Errors[0].StartsWith("(3"), "first error should be on line 3");
        }
Beispiel #6
0
        /// <summary>
        /// Minifies CSS from a stream input
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public static string MinifyCss(Stream stream)
        {
            var cssMinify = new CssMinifier();

            if (!stream.CanRead)
            {
                throw new InvalidOperationException("Cannot read input stream");
            }
            if (stream.CanSeek)
            {
                stream.Position = 0;
            }
            return(cssMinify.Minify(new StreamReader(stream)));
        }
Beispiel #7
0
        public async Task MinifyCss_NullSettings_Success()
        {
            var minifier = new CssMinifier(null);
            var context  = new Mock <IAssetContext>().SetupAllProperties();

            context.Object.Content = new Dictionary <string, byte[]> {
                { "", "body { color: yellow; }".AsByteArray() }
            };
            var options = new Mock <WebOptimizerOptions>();

            await minifier.ExecuteAsync(context.Object);

            Assert.Equal("body{color:#ff0}", context.Object.Content.First().Value.AsString());
            Assert.Equal("", minifier.CacheKey(new DefaultHttpContext()));
        }
Beispiel #8
0
        public async Task MinifyCss_EmptyContent_Success(string input)
        {
            var minifier = new CssMinifier(new CssSettings());
            var context  = new Mock <IAssetContext>().SetupAllProperties();

            context.Object.Content = new Dictionary <string, byte[]> {
                { "", input.AsByteArray() }
            };
            var options = new Mock <WebOptimizerOptions>();

            await minifier.ExecuteAsync(context.Object);

            Assert.Equal("", context.Object.Content.First().Value.AsString());
            Assert.Equal("", minifier.CacheKey(new DefaultHttpContext()));
        }
        private string minifyCss(string templateContent)
        {
            var outputPath = Path.Combine(_siteDirectory, @"_site\css\minified.css");

            //todo extract all internal css/less links from template
            var cssFiles = new List <FileInfo>();

            var cssMinifier = new CssMinifier(_fileSystem, cssFiles, outputPath);

            cssMinifier.Minify();

            //todo replace extracted links with single link to minified css (possibly with a hash appended)

            throw new NotImplementedException();
        }
Beispiel #10
0
        public void MinifiesGoodCssTest()
        {
            var goodCssContent = "p {color:red;}\r\np {margin: 10px}\r\np {width: 10px}\r\nbody {margin: 1em;}";
            var expected       = "p{color:red;margin:10px;width:10px}body{margin:1em}";

            var minifier = new CssMinifier(new WebGreaseContext(new WebGreaseConfiguration()));
            var actual   = minifier.Minify(goodCssContent);

            Assert.AreEqual <string>(actual, expected);

            // pretty print is the only other option right now; should add indents, new lines etc.
            minifier.ShouldMinify = false;
            expected = "p\r\n{\r\n  color:red;\r\n  margin:10px;\r\n  width:10px\r\n}\r\nbody\r\n{\r\n  margin:1em\r\n}\r\n";
            actual   = minifier.Minify(goodCssContent);
            Assert.AreEqual <string>(actual, expected);
        }
        private void InnerMinify(IAsset asset, CssMinifier wgCssMinifier)
        {
            string content             = asset.Content;
            string topCharset          = string.Empty;
            string preprocessedContent = content;

            if (EjectCharset)
            {
                preprocessedContent = EjectCssCharset(preprocessedContent, ref topCharset);
            }
            string newContent;
            string assetUrl = asset.Url;

            try
            {
                newContent = wgCssMinifier.Minify(preprocessedContent);
                if (EjectCharset && !string.IsNullOrWhiteSpace(topCharset))
                {
                    string separator = ShouldMinify ? string.Empty : Environment.NewLine;
                    newContent = topCharset + separator + newContent;
                }

                IList <string> errors = wgCssMinifier.Errors;
                if (errors.Count > 0)
                {
                    throw new WgMinificationException(FormatErrorDetails(errors[0], preprocessedContent, assetUrl));
                }
            }
            catch (WgMinificationException e)
            {
                throw new AssetMinificationException(
                          string.Format(CoreStrings.Minifiers_MinificationSyntaxError,
                                        CODE_TYPE, assetUrl, MINIFIER_NAME, e.Message));
            }
            catch (Exception e)
            {
                throw new AssetMinificationException(
                          string.Format(CoreStrings.Minifiers_MinificationFailed,
                                        CODE_TYPE, assetUrl, MINIFIER_NAME, e.Message), e);
            }

            asset.Content  = newContent;
            asset.Minified = true;
        }
Beispiel #12
0
        /// <summary>
        /// Produces a code minifiction of CSS asset by using WebGrease Semantic CSS minifier
        /// </summary>
        /// <param name="asset">CSS asset</param>
        /// <returns>CSS asset with minified text content</returns>
        public IAsset Minify(IAsset asset)
        {
            if (asset == null)
            {
                throw new ArgumentException(CoreStrings.Common_ValueIsEmpty, "asset");
            }

            if (asset.Minified)
            {
                return(asset);
            }

            var wgCssMinifier = new CssMinifier(new WebGreaseContext(_wgConfiguration))
            {
                ShouldMinify = ShouldMinify
            };

            InnerMinify(asset, wgCssMinifier);

            return(asset);
        }
Beispiel #13
0
        /// <summary>
        /// Minifies the specified resource.
        /// </summary>
        /// <param name="resource">The resource.</param>
        /// <returns>The minified resource.</returns>
        public override string Minify(string resource)
        {
            CssMinifier minifier;

            if (this.Options.Minify)
            {
                minifier = new CssMinifier
                {
                    RemoveWhiteSpace = true
                };
            }
            else
            {
                minifier = new CssMinifier
                {
                    RemoveWhiteSpace = false
                };
            }

            return(minifier.Minify(resource));
        }
        /// <summary>
        /// Produces a code minifiction of CSS asset by using WebGrease Semantic CSS minifier
        /// </summary>
        /// <param name="asset">CSS asset</param>
        /// <returns>CSS asset with minified text content</returns>
        public IAsset Minify(IAsset asset)
        {
            if (asset == null)
            {
                throw new ArgumentNullException(
                          nameof(asset),
                          string.Format(CoreStrings.Common_ArgumentIsNull, nameof(asset))
                          );
            }

            if (asset.Minified)
            {
                return(asset);
            }

            var wgCssMinifier = new CssMinifier(new WebGreaseContext(_wgConfiguration))
            {
                ShouldMinify = ShouldMinify
            };

            InnerMinify(asset, wgCssMinifier);

            return(asset);
        }
        private void InnerMinify(IAsset asset, CssMinifier wgCssMinifier)
        {
            string content = asset.Content;
            string topCharset = string.Empty;
            string preprocessedContent = content;
            if (EjectCharset)
            {
                preprocessedContent = EjectCssCharset(preprocessedContent, ref topCharset);
            }
            string newContent;
            string assetUrl = asset.Url;

            try
            {
                newContent = wgCssMinifier.Minify(preprocessedContent);
                if (EjectCharset && !string.IsNullOrWhiteSpace(topCharset))
                {
                    string separator = ShouldMinify ? string.Empty : Environment.NewLine;
                    newContent = topCharset + separator + newContent;
                }

                IList<string> errors = wgCssMinifier.Errors;
                if (errors.Count > 0)
                {
                    throw new WgMinificationException(FormatErrorDetails(errors[0], preprocessedContent, assetUrl));
                }
            }
            catch (WgMinificationException e)
            {
                throw new AssetMinificationException(
                    string.Format(CoreStrings.Minifiers_MinificationSyntaxError,
                        CODE_TYPE, assetUrl, MINIFIER_NAME, e.Message));
            }
            catch (Exception e)
            {
                throw new AssetMinificationException(
                    string.Format(CoreStrings.Minifiers_MinificationFailed,
                        CODE_TYPE, assetUrl, MINIFIER_NAME, e.Message), e);
            }

            asset.Content = newContent;
            asset.Minified = true;
        }
        /// <summary>
        /// Produces a code minifiction of CSS-assets by using WebGrease Semantic CSS-minifier
        /// </summary>
        /// <param name="assets">Set of CSS-assets</param>
        /// <returns>Set of CSS-assets with minified text content</returns>
        public IList<IAsset> Minify(IList<IAsset> assets)
        {
            if (assets == null)
            {
                throw new ArgumentException(CoreStrings.Common_ValueIsEmpty, "assets");
            }

            if (assets.Count == 0)
            {
                return assets;
            }

            var assetsToProcessing = assets.Where(a => a.IsStylesheet && !a.Minified).ToList();
            if (assetsToProcessing.Count == 0)
            {
                return assets;
            }

            var wgCssMinifier = new CssMinifier(new WebGreaseContext(_wgConfiguration))
            {
                ShouldMinify = ShouldMinify
            };

            foreach (var asset in assetsToProcessing)
            {
                InnerMinify(asset, wgCssMinifier);
            }

            return assets;
        }
Beispiel #17
0
        public void ProcessRequest(HttpContext context)
        {
            // set from an earlier in pipeline by CDNInterceptPipeline
            string minifyPath = StringUtil.GetString(context.Items["MinifyPath"]);

            if (string.IsNullOrEmpty(minifyPath))
            {
                context.Response.StatusCode = 404;
                context.Response.End();
            }


            UrlString url       = new UrlString(minifyPath);
            string    localPath = url.Path;

            string filePath = FileUtil.MapPath(localPath);

            // if the request is a .js file
            if (localPath.EndsWith(".js"))
            {
                HashEncryption hasher = new HashEncryption(HashEncryption.EncryptionProvider.MD5);
                if (!string.IsNullOrEmpty(localPath))
                {
                    // generate a unique filename for the cached .js version
                    string cachedFilePath = FileUtil.MapPath(string.Format("/App_Data/MediaCache/{0}.js", hasher.Hash(url.ToString())));

                    // if it doesn't exist create it
                    if (!FileUtil.FileExists(cachedFilePath))
                    {
                        // if the original file exsits minify it
                        if (FileUtil.FileExists(filePath))
                        {
                            JsMinifier minifier = new JsMinifier();
                            string     minified = minifier.Minify(filePath);
                            FileUtil.WriteToFile(cachedFilePath, minified);
                        }
                    }

                    if (FileUtil.FileExists(cachedFilePath))
                    {
                        context.Response.ClearHeaders();
                        context.Response.Cache.SetExpires(DateTime.Now.AddDays(14));
                        context.Response.AddHeader("Content-Type", "application/x-javascript; charset=utf-8");
                        context.Response.WriteFile(cachedFilePath);
                        context.Response.End();
                        _success = true;
                    }
                }
            }
            // if the request is a .css file
            else if (localPath.EndsWith(".css"))
            {
                HashEncryption hasher = new HashEncryption(HashEncryption.EncryptionProvider.MD5);
                if (!string.IsNullOrEmpty(localPath))
                {
                    // generate a unique filename for the cached .css version
                    string cachedFilePath = FileUtil.MapPath(string.Format("/App_Data/MediaCache/{0}.css", hasher.Hash(url.ToString())));

                    // if it doesn't exist create it
                    if (!FileUtil.FileExists(cachedFilePath))
                    {
                        // if the original file exsits minify it
                        if (FileUtil.FileExists(filePath))
                        {
                            CssMinifier minifier = new CssMinifier();
                            string      minified = CssMinifier.Minify(FileUtil.ReadFromFile(filePath));

                            // if Css Processing is enabled, replace any urls inside the css file.
                            if (CDNSettings.ProcessCss)
                            {
                                // find all css occurences of url([url])
                                Regex reReplaceUrl = new Regex("url\\(\\s*['\"]?([^\"')]+)['\"]?\\s*\\)");

                                try
                                {
                                    // replacing  url([url]) with url([cdnUrl]) in css
                                    minified = reReplaceUrl.Replace(minified, (m) =>
                                    {
                                        string oldUrl = "";
                                        if (m.Groups.Count > 1)
                                        {
                                            oldUrl = m.Groups[1].Value;
                                        }

                                        if (WebUtil.IsInternalUrl(oldUrl))
                                        {
                                            if (oldUrl.StartsWith("."))
                                            {
                                                oldUrl = VirtualPathUtility.Combine(url.Path, oldUrl);
                                            }
                                            string newUrl = CDNManager.ReplaceMediaUrl(oldUrl, string.Empty);
                                            if (!string.IsNullOrEmpty(newUrl))
                                            {
                                                return(m.Value.Replace(m.Groups[1].Value, newUrl));
                                            }
                                        }

                                        return(m.Value);
                                    });
                                }
                                catch (Exception ex)
                                {
                                    Log.Error("Minify error", ex, this);
                                }
                            }

                            FileUtil.WriteToFile(cachedFilePath, minified);
                        }
                    }

                    if (FileUtil.FileExists(cachedFilePath))
                    {
                        context.Response.ClearHeaders();
                        context.Response.Cache.SetExpires(DateTime.Now.AddDays(14));
                        context.Response.AddHeader("Content-Type", "text/css; charset=utf-8");
                        context.Response.TransmitFile(cachedFilePath);
                        context.Response.End();
                        _success = true;
                    }
                }
            }
        }
        /// <summary>
        /// Produces a code minifiction of CSS-asset by using WebGrease Semantic CSS-minifier
        /// </summary>
        /// <param name="asset">CSS-asset</param>
        /// <returns>CSS-asset with minified text content</returns>
        public IAsset Minify(IAsset asset)
        {
            if (asset == null)
            {
                throw new ArgumentException(CoreStrings.Common_ValueIsEmpty, "asset");
            }

            if (asset.Minified)
            {
                return asset;
            }

            var wgCssMinifier = new CssMinifier(new WebGreaseContext(_wgConfiguration))
            {
                ShouldMinify = ShouldMinify
            };

            InnerMinify(asset, wgCssMinifier);

            return asset;
        }
Beispiel #19
0
        public virtual async Task <ActionResult> Css(string name, string type)
        {
            var dynamicResourceResourceDefaultBasePath = WebConstants.CssDynamicResourceResourceDefaultBasePath;
            var dynamicResourceDefaultBasePath         = WebConstants.CssDynamicResourceDefaultBasePath;

            if (string.IsNullOrEmpty(dynamicResourceResourceDefaultBasePath))
            {
                dynamicResourceResourceDefaultBasePath = "/css";
            }
            if (string.IsNullOrEmpty(dynamicResourceDefaultBasePath))
            {
                dynamicResourceDefaultBasePath = "/css/app";
            }

            return(await GetContentAsync(name : name,
                                         type : type,
                                         mime : "text/css",
                                         extension : ".css",
                                         dynamicResourceResourceBasePathKey : WebConstants.CSS_DYNAMIC_RESOURCE_RESOURCE_BASEPATH_KEY,
                                         dynamicResourceResourceDefaultBasePath : dynamicResourceResourceDefaultBasePath,
                                         dynamicResourcePathKey : WebConstants.CSS_DYNAMIC_RESOURCE_PATH_KEY,
                                         dynamicResourceDefaultBasePath : dynamicResourceDefaultBasePath,
                                         minify : (content) => ClientSideContentProvider.MinifyCss?CssMinifier.Minify(content) : content));
        }