/// <summary>
		/// Produces a code minifiction of JS-assets by using C# port of
		/// Douglas Crockford's JSMin
		/// </summary>
		/// <param name="assets">Set of JS-assets</param>
		/// <returns>Set of JS-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.IsScript && !a.Minified).ToList();
			if (assetsToProcessing.Count == 0)
			{
				return assets;
			}

			var jsMin = new JsMinifier();

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

			return assets;
		}
		public void JsMinificationIsCorrect()
		{
			// Arrange
			var minifier = new JsMinifier();

			const string input = "// is.js\r\n" +
				"\r\n" +
				"// (c) 2001 Douglas Crockford\r\n" +
				"// 2001 June 3\r\n" +
				"\r\n\r\n" +
				"// is\r\n" +
				"\r\n" +
				"// The -is- object is used to identify the browser.  Every browser edition\r\n" +
				"// identifies itself, but there is no standard way of doing it, and some of\r\n" +
				"// the identification is deceptive. This is because the authors of web\r\n" +
				"// browsers are liars. For example, Microsoft's IE browsers claim to be\r\n" +
				"// Mozilla 4. Netscape 6 claims to be version 5.\r\n" +
				"\r\n" +
				"// Warning: Do not use this awful, awful code or any other thing like it.\r\n" +
				"// Seriously.\r\n" +
				"\r\n" +
				"var is = {\r\n" +
				"\tie: navigator.appName == 'Microsoft Internet Explorer',\r\n" +
				"\tjava: navigator.javaEnabled(),\r\n" +
				"\tns: navigator.appName == 'Netscape',\r\n" +
				"\tua: navigator.userAgent.toLowerCase(),\r\n" +
				"\tversion: parseFloat(navigator.appVersion.substr(21)) ||\r\n" +
				"             parseFloat(navigator.appVersion),\r\n" +
				"\twin: navigator.platform == 'Win32'\r\n" +
				"}\r\n" +
				"is.mac = is.ua.indexOf('mac') >= 0;\r\n" +
				"\r\n" +
				"if (is.ua.indexOf('opera') >= 0) {\r\n" +
				"\tis.ie = is.ns = false;\r\n" +
				"\tis.opera = true;\r\n" +
				"}\r\n" +
				"\r\n" +
				"if (is.ua.indexOf('gecko') >= 0) {\r\n" +
				"\tis.ie = is.ns = false;\r\n" +
				"\tis.gecko = true;\r\n" +
				"}"
				;
			const string targetOutput = "var is={ie:navigator.appName=='Microsoft Internet Explorer',java:navigator.javaEnabled(),ns:navigator.appName=='Netscape',ua:navigator.userAgent.toLowerCase(),version:parseFloat(navigator.appVersion.substr(21))||parseFloat(navigator.appVersion),win:navigator.platform=='Win32'}\n" + 
				"is.mac=is.ua.indexOf('mac')>=0;if(is.ua.indexOf('opera')>=0){is.ie=is.ns=false;is.opera=true;}\n" +
				"if(is.ua.indexOf('gecko')>=0){is.ie=is.ns=false;is.gecko=true;}"
				;

			// Act
			string output = minifier.Minify(input);

			// Assert
			Assert.AreEqual(targetOutput, output);
		}
		/// <summary>
		/// Produces a code minifiction of JS-asset by using C# port of
		/// Douglas Crockford's JSMin
		/// </summary>
		/// <param name="asset">JS-asset</param>
		/// <returns>JS-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 jsMin = new JsMinifier();

			InnerMinify(asset, jsMin);

			return asset;
		}
Example #4
0
        public void Setup()
        {
            var websiteInfo = new Mock <IWebsiteInfo>();

            websiteInfo.Setup(x => x.GetBasePath()).Returns("/");
            websiteInfo.Setup(x => x.GetBaseUrl()).Returns(new Uri("http://test.com"));

            _jsMin   = new JsMinifier();
            _nuglify = new NuglifyJs(
                new NuglifySettings(new NuglifyCodeSettings(null), new CssSettings()),
                Mock.Of <ISourceMapDeclaration>());

            var nodeServices = new SmidgeJavaScriptServices(NodeServicesFactory.CreateNodeServices(
                                                                new NodeServicesOptions(new NullServiceProvider())
            {
                ProjectPath         = AssemblyPath,
                WatchFileExtensions = new string[] {}
            }));

            _jsUglify = new UglifyNodeMinifier(nodeServices);
        }
Example #5
0
        /// <summary>
        /// Produces a code minifiction of JS asset by using C# port of
        /// Douglas Crockford's JSMin
        /// </summary>
        /// <param name="asset">JS asset</param>
        /// <returns>JS 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 jsMin = new JsMinifier();

            InnerMinify(asset, jsMin);

            return(asset);
        }
Example #6
0
        public void Should_Minify_Single_File()
        {
            var filepath = @"c:\css\script.js";
            var script   = "function test() { alert(\"hello\"); }";

            var fileSystem = new MockFileSystem(new Dictionary <string, MockFileData>
            {
                { filepath, new MockFileData(script) }
            });

            var files = new List <FileInfo> {
                new FileInfo(filepath)
            };

            var minifier = new JsMinifier(fileSystem, files, _outputPath);

            minifier.Minify();

            var minifiedFile = fileSystem.File.ReadAllText(_outputPath, Encoding.UTF8);

            Assert.Equal("function test(){alert(\"hello\")}", minifiedFile);
        }
Example #7
0
        public static TargetConfig LoadFromFile(string path)
        {
            JavaScriptSerializer ser = new JavaScriptSerializer(new TargetConfigTypeResolver());

            ser.RegisterConverters(new JavaScriptConverter[] { new ModelConverter() });
            using (StreamReader r = new StreamReader(path))
            {
                string json = r.ReadToEnd();

                // replace Global Variables in the json file
                foreach (string key in GlobalVariables.Keys)
                {
                    json = json.Replace($"${key}", HttpUtility.JavaScriptStringEncode(GlobalVariables[key].ToString()));
                }

                var minifier = new JsMinifier();
                // minify JSON to strip away comments
                // Comments in config files are very useful but JSON parsers
                // do not allow comments. Minification solves the issue.
                string jsonMin = minifier.Minify(json);
                return(ser.Deserialize <TargetConfig>(jsonMin));
            }
        }
        /// <summary>
        /// Produces code minifiction of JS content by using C# port of
        /// Douglas Crockford's JSMin (version of May 22 2007)
        /// </summary>
        /// <param name="content">JS content</param>
        /// <param name="isInlineCode">Flag whether the content is inline code</param>
        /// <param name="encoding">Text encoding</param>
        /// <returns>Minification result</returns>
        public CodeMinificationResult Minify(string content, bool isInlineCode, Encoding encoding)
        {
            if (string.IsNullOrWhiteSpace(content))
            {
                return(new CodeMinificationResult(string.Empty));
            }

            string newContent = string.Empty;
            var    errors     = new List <MinificationErrorInfo>();

            try
            {
                var jsMin = new JsMinifier();
                newContent = jsMin.Minify(content);
            }
            catch (JsMinificationException e)
            {
                errors.Add(new MinificationErrorInfo(e.Message));
            }

            var minificationResult = new CodeMinificationResult(newContent, errors);

            return(minificationResult);
        }
		private void InnerMinify(IAsset asset, JsMinifier jsMin)
		{
			string newContent;
			string assetUrl = asset.Url;

			try
			{
				newContent = jsMin.Minify(asset.Content);
			}
			catch (JsMinificationException 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));
			}

			asset.Content = newContent;
			asset.Minified = true;
		}
Example #10
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;
                    }
                }
            }
        }