public void Can_Parse_Import_Statements() { var css = @"@import url('/css/typography.css'); @import url('/css/layout.css'); @import url('http://mysite/css/color.css'); @import url(/css/blah.css); body { color: black; } div {display: block;}"; IEnumerable <string> importPaths; var output = CssHelper.ParseImportStatements(css, out importPaths); Assert.AreEqual(@"@import url('http://mysite/css/color.css'); body { color: black; } div {display: block;}", output); Assert.AreEqual(3, importPaths.Count()); Assert.AreEqual("/css/typography.css", importPaths.ElementAt(0)); Assert.AreEqual("/css/layout.css", importPaths.ElementAt(1)); //Assert.AreEqual("http://mysite/css/color.css", importPaths.ElementAt(2)); Assert.AreEqual("/css/blah.css", importPaths.ElementAt(2)); }
public void Ensure_Non_Temp_Search_Strings_Are_Resolved_From_Stream() { var css = @"@font-face{ font-family:'Open Sans'; font-style:normal; font-weight:400; src:url('../fonts/opensans/OpenSans-Regular-webfont.eot'); src:local('Open Sans'), local('OpenSans'), url('../fonts/opensans/OpenSans-Regular-webfont.eot?#iefix') format('embedded-opentype'), url('../fonts/opensans/OpenSans-Regular-webfont.ttf') format('truetype'), url('../fonts/opensans/OpenSans-Regular-webfont.svg#open_sansregular') format('svg')}" ; using (var ms = new MemoryStream()) using (var writer = new StreamWriter(ms)) { writer.Write(css); writer.Flush(); string externalImports; IEnumerable <string> importPaths; CssHelper.ParseImportStatements(ms, out importPaths, out externalImports); Assert.AreEqual("", externalImports); } }
public void Can_Parse_Import_Statements_From_Stream() { var css = @"@import url('/css/typography.css'); @import url('/css/layout.css'); @import url('http://mysite/css/color.css'); @import url(/css/blah.css); body { color: black; } div {display: block;}"; using (var ms = new MemoryStream()) using (var writer = new StreamWriter(ms)) { writer.Write(css); writer.Flush(); IEnumerable <string> importPaths; string externalImports; var position = CssHelper.ParseImportStatements(ms, out importPaths, out externalImports); Assert.AreEqual(@"@import url('http://mysite/css/color.css');", externalImports); Assert.AreEqual(3, importPaths.Count()); Assert.AreEqual("/css/typography.css", importPaths.ElementAt(0)); Assert.AreEqual("/css/layout.css", importPaths.ElementAt(1)); //Assert.AreEqual("http://mysite/css/color.css", importPaths.ElementAt(2)); Assert.AreEqual("/css/blah.css", importPaths.ElementAt(2)); } }
/// <summary> /// Writes the actual contents of a file or request result to the stream and ensures the contents are minified if necessary /// </summary> /// <param name="provider"></param> /// <param name="sw"></param> /// <param name="content"></param> /// <param name="type"></param> /// <param name="context"></param> /// <param name="originalUrl">The original Url that the content is related to</param> internal static void WriteContentToStream(BaseCompositeFileProcessingProvider provider, StreamWriter sw, string content, ClientDependencyType type, HttpContextBase context, string originalUrl) { if (type == ClientDependencyType.Css) { IEnumerable <string> importedPaths; var removedImports = CssHelper.ParseImportStatements(content, out importedPaths); //need to write the imported sheets first since these theoretically should *always* be at the top for browser to support them foreach (var importPath in importedPaths) { var uri = new Uri(originalUrl, UriKind.RelativeOrAbsolute) .MakeAbsoluteUri(context); var absolute = uri.ToAbsolutePath(importPath); provider.WritePathToStream(ClientDependencyType.Css, absolute, context, sw); } //ensure the Urls in the css are changed to absolute var parsedUrls = CssHelper.ReplaceUrlsWithAbsolutePaths(removedImports, originalUrl, context); //then we write the css with the removed import statements sw.WriteLine(provider.MinifyFile(parsedUrls, ClientDependencyType.Css)); } else { sw.WriteLine(provider.MinifyFile(content, type)); } }
private static void WriteContentToStream(BaseCompositeFileProcessingProvider provider, StreamWriter sw, FileInfo inputFile, Stream stream, ClientDependencyType type, HttpContextBase context, string originalUrl) { if (type == ClientDependencyType.Css) { IEnumerable <string> importedPaths; string externalImports; CssHelper.ParseImportStatements(stream, out importedPaths, out externalImports); //we can write the external imports found at the top sw.WriteLine(externalImports); //need to write the imported sheets first since these theoretically should *always* be at the top for browser to support them foreach (var importPath in importedPaths) { var uri = new Uri(originalUrl, UriKind.RelativeOrAbsolute) .MakeAbsoluteUri(context); var absolute = uri.ToAbsolutePath(importPath); provider.WritePathToStream(ClientDependencyType.Css, absolute, context, sw); } var minified = GetMinifiedOutput(provider, type, inputFile, stream); //ensure the Urls in the css are changed to absolute var parsedUrls = CssHelper.ReplaceUrlsWithAbsolutePaths(minified, originalUrl, context); //then we write the css with the removed import statements sw.WriteLine(parsedUrls); } else { sw.WriteLine(GetMinifiedOutput(provider, type, inputFile, stream)); } }
public void Retain_External_Imports() { var cssWithImport = @"@import url(""//fonts.googleapis.com/css?subset=latin,cyrillic-ext,latin-ext,cyrillic&family=Open+Sans+Condensed:300|Open+Sans:400,600,400italic,600italic|Merriweather:400,300,300italic,400italic,700,700italic|Roboto+Slab:400,300""); @import url(""//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css"");"; IEnumerable <string> importPaths; var output = CssHelper.ParseImportStatements(cssWithImport, out importPaths); Assert.AreEqual(cssWithImport, output); }
public void Retain_External_Imports_From_Stream() { var cssWithImport = @"@import url(""//fonts.googleapis.com/css?subset=latin,cyrillic-ext,latin-ext,cyrillic&family=Open+Sans+Condensed:300|Open+Sans:400,600,400italic,600italic|Merriweather:400,300,300italic,400italic,700,700italic|Roboto+Slab:400,300""); @import url(""//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css"");"; using (var ms = new MemoryStream()) using (var writer = new StreamWriter(ms)) { writer.Write(cssWithImport); writer.Flush(); string externalImports; IEnumerable <string> importPaths; var position = CssHelper.ParseImportStatements(ms, out importPaths, out externalImports); Assert.AreEqual(ms.Length, position); Assert.AreEqual(cssWithImport, externalImports); } }
public void Can_Parse_Import_Statements_From_Stream_2() { var css = @"@-ms-viewport { width: device-width; } .visible-xs, tr.visible-xs, th.visible-xs, td.visible-xs { display: none !important; } @media (max-width: 767px) { .visible-xs { display: block !important; } table.visible-xs { display: table; } tr.visible-xs { display: table-row !important; } th.visible-xs, td.visible-xs { display: table-cell !important; } } @media (min-width: 768px) and (max-width: 991px) { .visible-xs.visible-sm { display: block !important; } table.visible-xs.visible-sm { display: table; } tr.visible-xs.visible-sm { display: table-row !important; } th.visible-xs.visible-sm, td.visible-xs.visible-sm { display: table-cell !important; } } "; using (var ms = new MemoryStream()) using (var writer = new StreamWriter(ms)) { writer.Write(css); writer.Flush(); IEnumerable <string> importPaths; string externalImports; var position = CssHelper.ParseImportStatements(ms, out importPaths, out externalImports); Assert.AreEqual(string.Empty, externalImports); //Assert.AreEqual(10, importPaths.Count()); //Assert.AreEqual("/css/typography.css", importPaths.ElementAt(0)); //Assert.AreEqual("/css/layout.css", importPaths.ElementAt(1)); ////Assert.AreEqual("http://mysite/css/color.css", importPaths.ElementAt(2)); //Assert.AreEqual("/css/blah.css", importPaths.ElementAt(2)); } }