public override string MinifyString(string source) { var settings = new HtmlMinificationSettings { RemoveOptionalEndTags = false, AttributeQuotesRemovalMode = HtmlAttributeQuotesRemovalMode.KeepQuotes, RemoveRedundantAttributes = false, EmptyTagRenderMode = HtmlEmptyTagRenderMode.Slash, }; var minifier = new HtmlMinifier(settings); MarkupMinificationResult result = minifier.Minify(source, generateStatistics: true); if (result.Errors.Count == 0) { EditorExtensionsPackage.DTE.StatusBar.Text = "Web Essentials: HTML minified by " + result.Statistics.SavedInPercent + "%"; return result.MinifiedContent; } else { EditorExtensionsPackage.DTE.StatusBar.Text = "Web Essentials: Cannot minify the current selection. See Output Window for details."; Logger.ShowMessage("Cannot minify the selection:\r\n\r\n" + String.Join(Environment.NewLine, result.Errors.Select(e => e.Message))); return null; } }
/// <summary> /// Creates a instance of HTML minifier based on the settings /// that specified in configuration files (App.config or Web.config) /// </summary> /// <param name="settings">HTML minification settings</param> /// <param name="cssMinifier">CSS minifier</param> /// <param name="jsMinifier">JS minifier</param> /// <param name="logger">logger</param> /// <returns>HTML minifier</returns> public HtmlMinifier CreateHtmlMinifierInstance(HtmlMinificationSettings settings = null, ICssMinifier cssMinifier = null, IJsMinifier jsMinifier = null, ILogger logger = null) { HtmlMinificationSettings innerSettings = settings ?? GetHtmlMinificationSettings(); ICssMinifier innerCssMinifier = cssMinifier ?? _wmmContext.Code.CreateDefaultCssMinifierInstance(); IJsMinifier innerJsMinifier = jsMinifier ?? _wmmContext.Code.CreateDefaultJsMinifierInstance(); ILogger innerLogger = logger ?? _wmmContext.GetDefaultLoggerInstance(); var htmlMinifier = new HtmlMinifier(innerSettings, innerCssMinifier, innerJsMinifier, innerLogger); return(htmlMinifier); }
internal static string Minify(string html) { var htmlMinifier = new HtmlMinifier(); var result = htmlMinifier.Minify(html, false); if (result.Errors.Count == 0) { return result.MinifiedContent; } return html; }
public HtmlMinificationViewModel Minify(HtmlMinificationViewModel model) { string cssMinifierName = model.Settings.CssMinifierName; string jsMinifierName = model.Settings.JsMinifierName; var settings = Mapper.Map<HtmlMinificationSettings>(model.Settings); ICssMinifier cssMinifier = _cssMinifierFactory.CreateMinifier(cssMinifierName); IJsMinifier jsMinifier = _jsMinifierFactory.CreateMinifier(jsMinifierName); var htmlMinifier = new HtmlMinifier(settings, cssMinifier, jsMinifier); var result = htmlMinifier.Minify(model.SourceCode, true); model.Result = Mapper.Map<MarkupMinificationResultViewModel>(result); return model; }
/// <summary> /// Modifies the HTML by adding common meta tags, css and js. /// </summary> /// <param name="path">The path.</param> /// <param name="sourceStream">The source stream.</param> /// <param name="mode">The mode.</param> /// <param name="appVersion">The application version.</param> /// <param name="localizationCulture">The localization culture.</param> /// <param name="enableMinification">if set to <c>true</c> [enable minification].</param> /// <returns>Task{Stream}.</returns> public async Task<Stream> ModifyHtml(string path, Stream sourceStream, string mode, string appVersion, string localizationCulture, bool enableMinification) { using (sourceStream) { string html; using (var memoryStream = new MemoryStream()) { await sourceStream.CopyToAsync(memoryStream).ConfigureAwait(false); html = Encoding.UTF8.GetString(memoryStream.ToArray()); if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase)) { } else if (!string.IsNullOrWhiteSpace(path) && !string.Equals(path, "index.html", StringComparison.OrdinalIgnoreCase)) { var index = html.IndexOf("<body", StringComparison.OrdinalIgnoreCase); if (index != -1) { html = html.Substring(index); index = html.IndexOf("</body>", StringComparison.OrdinalIgnoreCase); if (index != -1) { html = html.Substring(0, index+7); } } var mainFile = File.ReadAllText(GetDashboardResourcePath("index.html")); html = ReplaceFirst(mainFile, "<div class=\"mainAnimatedPages skinBody\"></div>", "<div class=\"mainAnimatedPages skinBody hide\">" + html + "</div>"); } if (!string.IsNullOrWhiteSpace(localizationCulture)) { var lang = localizationCulture.Split('-').FirstOrDefault(); html = html.Replace("<html", "<html data-culture=\"" + localizationCulture + "\" lang=\"" + lang + "\""); } if (enableMinification) { try { var minifier = new HtmlMinifier(new HtmlMinificationSettings { AttributeQuotesRemovalMode = HtmlAttributeQuotesRemovalMode.KeepQuotes, RemoveOptionalEndTags = false, RemoveTagsWithoutContent = false }); var result = minifier.Minify(html, false); if (result.Errors.Count > 0) { _logger.Error("Error minifying html: " + result.Errors[0].Message); } else { html = result.MinifiedContent; } } catch (Exception ex) { _logger.ErrorException("Error minifying html", ex); } } } html = html.Replace("<head>", "<head>" + GetMetaTags(mode) + GetCommonCss(mode, appVersion)); // Disable embedded scripts from plugins. We'll run them later once resources have loaded if (html.IndexOf("<script", StringComparison.OrdinalIgnoreCase) != -1) { html = html.Replace("<script", "<!--<script"); html = html.Replace("</script>", "</script>-->"); } html = html.Replace("</body>", GetCommonJavascript(mode, appVersion) + "</body>"); var bytes = Encoding.UTF8.GetBytes(html); return new MemoryStream(bytes); } }
/// <summary> /// Modifies the HTML by adding common meta tags, css and js. /// </summary> /// <param name="sourceStream">The source stream.</param> /// <param name="mode">The mode.</param> /// <param name="appVersion">The application version.</param> /// <param name="localizationCulture">The localization culture.</param> /// <param name="enableMinification">if set to <c>true</c> [enable minification].</param> /// <returns>Task{Stream}.</returns> public async Task<Stream> ModifyHtml(Stream sourceStream, string mode, string appVersion, string localizationCulture, bool enableMinification) { using (sourceStream) { string html; using (var memoryStream = new MemoryStream()) { await sourceStream.CopyToAsync(memoryStream).ConfigureAwait(false); html = Encoding.UTF8.GetString(memoryStream.ToArray()); if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase)) { html = ModifyForCordova(html); } if (!string.IsNullOrWhiteSpace(localizationCulture)) { var lang = localizationCulture.Split('-').FirstOrDefault(); html = html.Replace("<html>", "<html data-culture=\"" + localizationCulture + "\" lang=\"" + lang + "\">"); } if (enableMinification) { try { var minifier = new HtmlMinifier(new HtmlMinificationSettings { AttributeQuotesRemovalMode = HtmlAttributeQuotesRemovalMode.KeepQuotes, RemoveOptionalEndTags = false, RemoveTagsWithoutContent = false }); var result = minifier.Minify(html, false); if (result.Errors.Count > 0) { _logger.Error("Error minifying html: " + result.Errors[0].Message); } else { html = result.MinifiedContent; } } catch (Exception ex) { _logger.ErrorException("Error minifying html", ex); } } html = html.Replace("<body>", "<body><paper-drawer-panel class=\"mainDrawerPanel mainDrawerPanelPreInit\" forceNarrow><div class=\"mainDrawer\" drawer></div><div class=\"mainDrawerPanelContent\" main><!--<div class=\"pageContainer\">") .Replace("</body>", "</div>--></div></paper-drawer-panel></body>"); } var versionString = !string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase) ? "?v=" + appVersion : string.Empty; var imports = new[] { "vulcanize-out.html" + versionString }; var importsHtml = string.Join("", imports.Select(i => "<link rel=\"import\" href=\"" + i + "\">").ToArray()); // It would be better to make polymer completely dynamic and loaded on demand, but seeing issues with that // In chrome it is causing the body to be hidden while loading, which leads to width-check methods to return 0 for everything //imports = ""; html = html.Replace("<head>", "<head>" + GetMetaTags(mode) + GetCommonCss(mode, appVersion)); html = html.Replace("</body>", GetInitialJavascript(mode, appVersion) + importsHtml + GetCommonJavascript(mode, appVersion) + "</body>"); var bytes = Encoding.UTF8.GetBytes(html); return new MemoryStream(bytes); } }
public static string MinifyString(string extension, string content) { if (extension == ".css") { Minifier minifier = new Minifier(); CssSettings settings = new CssSettings(); settings.CommentMode = CssComment.None; if (WESettings.GetBoolean(WESettings.Keys.KeepImportantComments)) { settings.CommentMode = CssComment.Important; } return minifier.MinifyStyleSheet(content, settings); } else if (extension == ".js") { Minifier minifier = new Minifier(); CodeSettings settings = new CodeSettings() { EvalTreatment = EvalTreatment.MakeImmediateSafe, PreserveImportantComments = WESettings.GetBoolean(WESettings.Keys.KeepImportantComments) }; return minifier.MinifyJavaScript(content, settings); } else if (_htmlExt.Contains(extension.ToLowerInvariant())){ var settings = new HtmlMinificationSettings { RemoveOptionalEndTags = false, AttributeQuotesRemovalMode = HtmlAttributeQuotesRemovalMode.KeepQuotes }; var minifier = new HtmlMinifier(settings); MarkupMinificationResult result = minifier.Minify(content, generateStatistics: true); if (result.Errors.Count == 0) { EditorExtensionsPackage.DTE.StatusBar.Text = "Web Essentials: HTML minified by " + result.Statistics.SavedInPercent + "%"; return result.MinifiedContent; } else { EditorExtensionsPackage.DTE.StatusBar.Text = "Web Essentials: Cannot minify the current selection"; return content; } } return null; }
/// <summary> /// Modifies the HTML by adding common meta tags, css and js. /// </summary> /// <param name="sourceStream">The source stream.</param> /// <param name="mode">The mode.</param> /// <param name="appVersion">The application version.</param> /// <param name="localizationCulture">The localization culture.</param> /// <param name="enableMinification">if set to <c>true</c> [enable minification].</param> /// <returns>Task{Stream}.</returns> public async Task<Stream> ModifyHtml(Stream sourceStream, string mode, string appVersion, string localizationCulture, bool enableMinification) { using (sourceStream) { string html; using (var memoryStream = new MemoryStream()) { await sourceStream.CopyToAsync(memoryStream).ConfigureAwait(false); html = Encoding.UTF8.GetString(memoryStream.ToArray()); if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase)) { html = ModifyForCordova(html); } if (!string.IsNullOrWhiteSpace(localizationCulture)) { var lang = localizationCulture.Split('-').FirstOrDefault(); html = html.Replace("<html>", "<html data-culture=\"" + localizationCulture + "\" lang=\"" + lang + "\">"); } if (enableMinification) { try { var minifier = new HtmlMinifier(new HtmlMinificationSettings { AttributeQuotesRemovalMode = HtmlAttributeQuotesRemovalMode.KeepQuotes, RemoveOptionalEndTags = false, RemoveTagsWithoutContent = false }); var result = minifier.Minify(html, false); if (result.Errors.Count > 0) { _logger.Error("Error minifying html: " + result.Errors[0].Message); } else { html = result.MinifiedContent; } } catch (Exception ex) { _logger.ErrorException("Error minifying html", ex); } } html = html.Replace("<body>", "<body><paper-drawer-panel class=\"mainDrawerPanel mainDrawerPanelPreInit\" forceNarrow><div class=\"mainDrawer\" drawer></div><div class=\"mainDrawerPanelContent\" main><!--<div class=\"pageContainer\">") .Replace("</body>", "</div>--></div></paper-drawer-panel></body>"); } html = html.Replace("<head>", "<head>" + GetMetaTags(mode) + GetCommonCss(mode, appVersion)); html = html.Replace("</body>", GetCommonJavascript(mode, appVersion) + "</body>"); var bytes = Encoding.UTF8.GetBytes(html); return new MemoryStream(bytes); } }
public override void Flush() { if (string.IsNullOrEmpty(html)) { // Nothing in the filter, output served by OutputCache module return; } var htmlMinifier = new WebMarkupMin.Core.HtmlMinifier(new HtmlMinificationSettings { WhitespaceMinificationMode = settings.WhitespaceMinificationMode, RemoveHtmlComments = settings.RemoveHtmlComments, RemoveHtmlCommentsFromScriptsAndStyles = settings.RemoveHtmlCommentsFromScriptsAndStyles, RemoveCdataSectionsFromScriptsAndStyles = settings.RemoveCdataSectionsFromScriptsAndStyles, UseShortDoctype = settings.UseShortDoctype, PreserveCase = settings.PreserveCase, UseMetaCharsetTag = settings.UseMetaCharsetTag, EmptyTagRenderMode = settings.EmptyTagRenderMode, RemoveOptionalEndTags = settings.RemoveOptionalEndTags, PreservableOptionalTagList = settings.PreservableOptionalTagList, RemoveTagsWithoutContent = settings.RemoveTagsWithoutContent, CollapseBooleanAttributes = settings.CollapseBooleanAttributes, RemoveEmptyAttributes = settings.RemoveEmptyAttributes, AttributeQuotesRemovalMode = settings.AttributeQuotesRemovalMode, RemoveRedundantAttributes = settings.RemoveRedundantAttributes, RemoveJsTypeAttributes = settings.RemoveJsTypeAttributes, RemoveCssTypeAttributes = settings.RemoveCssTypeAttributes, RemoveHttpProtocolFromAttributes = settings.RemoveHttpProtocolFromAttributes, RemoveHttpsProtocolFromAttributes = settings.RemoveHttpsProtocolFromAttributes, RemoveJsProtocolFromAttributes = settings.RemoveJsProtocolFromAttributes, MinifyEmbeddedCssCode = settings.MinifyEmbeddedCssCode, MinifyInlineCssCode = settings.MinifyInlineCssCode, MinifyEmbeddedJsCode = settings.MinifyEmbeddedJsCode, MinifyInlineJsCode = settings.MinifyInlineJsCode, ProcessableScriptTypeList = settings.ProcessableScriptTypeList, MinifyKnockoutBindingExpressions = settings.MinifyKnockoutBindingExpressions, MinifyAngularBindingExpressions = settings.MinifyAngularBindingExpressions, CustomAngularDirectiveList = settings.CustomAngularDirectiveList }); var generateStatistics = !string.IsNullOrWhiteSpace(settings.StatisticsInfoWindowPattern) && isOwner; var result = htmlMinifier.Minify(html, string.Empty, encoding, generateStatistics); foreach (var error in result.Errors) { Logger.Error(error.Message); } var shouldHaltOnWarnings = result.Warnings.Count > 0 && settings.HaltOnWarnings; foreach (var warning in result.Warnings) { if (shouldHaltOnWarnings) { Logger.Error(warning.Message); } else { Logger.Warning(warning.Message); } } if (result.Errors.Count == 0 && (result.Warnings.Count == 0 || !shouldHaltOnWarnings)) { html = result.MinifiedContent; if (generateStatistics) { var statistics = settings.StatisticsInfoWindowPattern .Replace("{Gzip-CompressionRatio}", $"{(float)result.Statistics.CompressionGzipRatio / 100:P1}") .Replace("{CompressionRatio}", $"{(float)result.Statistics.CompressionRatio / 100:P1}") .Replace("{MinificationDuration}", $"{result.Statistics.MinificationDuration} ms") .Replace("{Gzip-OriginalSize}", $"{(float)result.Statistics.OriginalGzipSize / 1000:F} KB") .Replace("{OriginalSize}", $"{(float)result.Statistics.OriginalSize / 1000:N} KB") .Replace("{Gzip-MinifiedSize}", $"{(float)result.Statistics.MinifiedGzipSize / 1000:N} KB") .Replace("{MinifiedSize}", $"{(float)result.Statistics.MinifiedSize / 1000:N} KB") .Replace("{Gzip-Saved}", $"{(float)result.Statistics.SavedGzipInBytes / 1000:N} KB") .Replace("{Gzip-SavedInPercent}", $"{(float)result.Statistics.SavedGzipInPercent / 100:P1}") .Replace("{Saved}", $"{(float)result.Statistics.SavedInBytes / 1000:N} KB") .Replace("{SavedInPercent}", $"{(float)result.Statistics.SavedInPercent / 100:P1}"); result = htmlMinifier.Minify(statistics, encoding); var bodyIndex = html.IndexOf("</body>", StringComparison.Ordinal); if (bodyIndex > 0) { html = html.Insert(bodyIndex, result.MinifiedContent); } else { html += result.MinifiedContent; } } } stream.Write(encoding.GetBytes(html), 0, encoding.GetByteCount(html)); }
public override string MinifyString(string source) { var weHtmlSettings = WESettings.Instance.Html; var settings = new HtmlMinificationSettings { PreserveCase = weHtmlSettings.PreserveCase, // Tags RemoveOptionalEndTags = false, //EmptyTagRenderMode = HtmlEmptyTagRenderMode.Slash, // Attributes AttributeQuotesRemovalMode = weHtmlSettings.AttributeQuotesRemovalMode, RemoveRedundantAttributes = false, // JavaScript templating ProcessableScriptTypeList = weHtmlSettings.ProcessableScriptTypeList, MinifyKnockoutBindingExpressions = weHtmlSettings.MinifyKnockoutBindingExpressions, MinifyAngularBindingExpressions = weHtmlSettings.MinifyAngularBindingExpressions, CustomAngularDirectiveList = weHtmlSettings.CustomAngularDirectiveList }; var minifier = new HtmlMinifier(settings); MarkupMinificationResult result = minifier.Minify(source, generateStatistics: true); if (result.Errors.Count == 0) { WebEssentialsPackage.DTE.StatusBar.Text = "Web Essentials: HTML minified by " + result.Statistics.SavedInPercent + "%"; return result.MinifiedContent; } else { WebEssentialsPackage.DTE.StatusBar.Text = "Web Essentials: Cannot minify the current selection. See Output Window for details."; Logger.ShowMessage("Cannot minify the selection:\r\n\r\n" + String.Join(Environment.NewLine, result.Errors.Select(e => e.Message))); return null; } }
/// <summary> /// Modifies the HTML by adding common meta tags, css and js. /// </summary> /// <param name="sourceStream">The source stream.</param> /// <param name="mode">The mode.</param> /// <param name="localizationCulture">The localization culture.</param> /// <param name="enableMinification">if set to <c>true</c> [enable minification].</param> /// <returns>Task{Stream}.</returns> public async Task<Stream> ModifyHtml(Stream sourceStream, string mode, string localizationCulture, bool enableMinification) { using (sourceStream) { string html; using (var memoryStream = new MemoryStream()) { await sourceStream.CopyToAsync(memoryStream).ConfigureAwait(false); html = Encoding.UTF8.GetString(memoryStream.ToArray()); if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase)) { html = ModifyForCordova(html); } if (!string.IsNullOrWhiteSpace(localizationCulture)) { var lang = localizationCulture.Split('-').FirstOrDefault(); html = _localization.LocalizeDocument(html, localizationCulture, GetLocalizationToken); html = html.Replace("<html>", "<html lang=\"" + lang + "\">"); } if (enableMinification) { try { var minifier = new HtmlMinifier(new HtmlMinificationSettings { AttributeQuotesRemovalMode = HtmlAttributeQuotesRemovalMode.KeepQuotes, RemoveOptionalEndTags = false, RemoveTagsWithoutContent = false }); var result = minifier.Minify(html, false); if (result.Errors.Count > 0) { _logger.Error("Error minifying html: " + result.Errors[0].Message); } else { html = result.MinifiedContent; } } catch (Exception ex) { _logger.ErrorException("Error minifying html", ex); } } } var version = GetType().Assembly.GetName().Version; var imports = "<link rel=\"import\" href=\"thirdparty/polymer/polymer.html\">"; imports = ""; html = html.Replace("<head>", "<head>" + GetMetaTags(mode) + GetCommonCss(mode, version) + GetCommonJavascript(mode, version) + imports); var bytes = Encoding.UTF8.GetBytes(html); return new MemoryStream(bytes); } }
public IEnumerable<IDocument> Execute(IReadOnlyList<IDocument> inputs, IExecutionContext context) { HtmlMinifier minifier = new HtmlMinifier(_minificationSettings); return Minify(inputs, context, minifier.Minify, "HTML"); }