Permalink
Browse files

Merge remote branch 'origin/master' into preprocessor-pipeline

Conflicts:
	SquishIt.Framework/Bundle.cs
	SquishIt.Tests/SquishIt.Tests.csproj
	SquishIt.Tests/packages.config
	nuspec/squishit.mvc.nuspec
	packages/repositories.config
	releases/squishit.nuspec
  • Loading branch information...
AlexCuse committed May 8, 2012
2 parents feb614c + 10db2f1 commit ba26514ba3b530867e003d502c5cdcef55db7ddb
@@ -17,7 +17,7 @@ public abstract class BundleBase<T> where T : BundleBase<T>
private static readonly Dictionary<string, string> renderPathCache = new Dictionary<string, string>();
private const string DEFAULT_GROUP = "default";
- protected string BaseOutputHref = String.Empty;
+ protected string BaseOutputHref = Configuration.Instance.DefaultOutputBaseHref() ?? String.Empty;
protected IFileWriterFactory fileWriterFactory;
protected IFileReaderFactory fileReaderFactory;
protected IDebugStatusReader debugStatusReader;
@@ -55,6 +55,7 @@ protected IMinifier<T> Minifier
private static Dictionary<string, BundleState> bundleStateCache = new Dictionary<string, BundleState>();
private IBundleCache bundleCache;
+ private IRenderer releaseRenderer;
protected BundleBase(IFileWriterFactory fileWriterFactory, IFileReaderFactory fileReaderFactory, IDebugStatusReader debugStatusReader, ICurrentDirectoryWrapper currentDirectoryWrapper, IHasher hasher, IBundleCache bundleCache)
{
@@ -68,6 +69,11 @@ protected BundleBase(IFileWriterFactory fileWriterFactory, IFileReaderFactory fi
this.bundleCache = bundleCache;
}
+ protected IRenderer GetReleaseFileRenderer()
+ {
+ return releaseRenderer ?? Configuration.Instance.DefaultReleaseRenderer() ?? new FileRenderer(fileWriterFactory);
+ }
+
private List<string> GetFiles(List<Asset> assets)
{
var inputFiles = GetInputFiles(assets);
@@ -318,10 +324,16 @@ public T WithOutputBaseHref(string href)
return (T)this;
}
+ public T WithReleaseRenderer(IRenderer renderer)
+ {
+ this.releaseRenderer = renderer;
+ return (T) this;
+ }
+
public string Render(string renderTo)
{
string key = renderTo;
- return Render(renderTo, key, new FileRenderer(fileWriterFactory));
+ return Render(renderTo, key, GetReleaseFileRenderer());
}
private string Render(string renderTo, string key, IRenderer renderer)
@@ -371,7 +383,7 @@ public string RenderCachedAssetTag(string name)
public void AsNamed(string name, string renderTo)
{
- Render(renderTo, name, new FileRenderer(fileWriterFactory));
+ Render(renderTo, name, GetReleaseFileRenderer());
bundleState.Path = renderTo;
bundleStateCache[CachePrefix + name] = bundleState;
}
@@ -91,7 +91,7 @@ public static CSSBundle Css(Utilities.IDebugStatusReader debugStatusReader)
public static Configuration ConfigureDefaults()
{
- return new Configuration();
+ return Configuration.Instance;
}
}
}
@@ -4,11 +4,23 @@
using SquishIt.Framework.Minifiers;
using SquishIt.Framework.Minifiers.CSS;
using SquishIt.Framework.Minifiers.JavaScript;
+using SquishIt.Framework.Renderers;
namespace SquishIt.Framework
{
public class Configuration
{
+ static Configuration instance;
+ Type _defaultCssMinifier = typeof (MsCompressor);
+ Type _defaultJsMinifier = typeof (MsMinifier);
+ string _defaultOutputBaseHref;
+ IRenderer _defaultReleaseRenderer;
+
+ public static Configuration Instance
+ {
+ get { return (instance = instance ?? new Configuration()); }
+ }
+
public Configuration UseMinifierForCss<TMinifier>()
where TMinifier : IMinifier<CSSBundle>
{
@@ -17,10 +29,10 @@ public Configuration UseMinifierForCss<TMinifier>()
public Configuration UseMinifierForCss(Type minifierType)
{
- if (!typeof(IMinifier<CSSBundle>).IsAssignableFrom(minifierType))
+ if (!typeof (IMinifier<CSSBundle>).IsAssignableFrom(minifierType))
throw new InvalidCastException(
- String.Format("Type '{0}' must implement '{1}' to be used for Css minification.",
- minifierType, typeof (IMinifier<CSSBundle>)));
+ String.Format("Type '{0}' must implement '{1}' to be used for Css minification.",
+ minifierType, typeof (IMinifier<CSSBundle>)));
_defaultCssMinifier = minifierType;
return this;
}
@@ -33,7 +45,7 @@ public Configuration UseMinifierForJs<TMinifier>()
public Configuration UseMinifierForJs(Type minifierType)
{
- if (!typeof(IMinifier<JavaScriptBundle>).IsAssignableFrom(minifierType))
+ if (!typeof (IMinifier<JavaScriptBundle>).IsAssignableFrom(minifierType))
throw new InvalidCastException(
String.Format("Type '{0}' must implement '{1}' to be used for Javascript minification.",
minifierType, typeof (IMinifier<JavaScriptBundle>)));
@@ -105,17 +117,36 @@ public Configuration UseJsMinForJsMinification()
return UseMinifierForJs<JsMinMinifier>();
}
- static Type _defaultCssMinifier = typeof (MsCompressor);
- static Type _defaultJsMinifier = typeof (MsMinifier);
+ internal IMinifier<CSSBundle> DefaultCssMinifier()
+ {
+ return (IMinifier<CSSBundle>) Activator.CreateInstance(_defaultCssMinifier, true);
+ }
+
+ internal IMinifier<JavaScriptBundle> DefaultJsMinifier()
+ {
+ return (IMinifier<JavaScriptBundle>) Activator.CreateInstance(_defaultJsMinifier, true);
+ }
- internal static IMinifier<CSSBundle> DefaultCssMinifier()
+ public Configuration UseReleaseRenderer(IRenderer releaseRenderer)
{
- return (IMinifier<CSSBundle>)Activator.CreateInstance(_defaultCssMinifier);
+ _defaultReleaseRenderer = releaseRenderer;
+ return this;
+ }
+
+ internal IRenderer DefaultReleaseRenderer()
+ {
+ return _defaultReleaseRenderer;
+ }
+
+ public Configuration UseOutputBaseHref(string url)
+ {
+ _defaultOutputBaseHref = url;
+ return this;
}
- public static IMinifier<JavaScriptBundle> DefaultJsMinifier()
+ internal string DefaultOutputBaseHref()
{
- return (IMinifier<JavaScriptBundle>)Activator.CreateInstance(_defaultJsMinifier);
+ return _defaultOutputBaseHref;
}
}
-}
+}
@@ -34,7 +34,7 @@ protected override string CachePrefix
protected override IMinifier<CSSBundle> DefaultMinifier
{
- get { return Configuration.DefaultCssMinifier(); }
+ get { return Configuration.Instance.DefaultCssMinifier(); }
}
protected override IEnumerable<string> allowedExtensions
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Text.RegularExpressions;
using SquishIt.Framework.Utilities;
@@ -64,26 +65,25 @@ private static string ReplaceRelativePathsIn (string css, string oldPath, string
});
}
- private static IEnumerable<string> FindDistinctRelativePathsIn (string css)
+ static readonly Regex pathsRegex = new Regex(@"(?<!.*behavior\s*:\s*)url\([""']?(.*?)[""']?\)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
+ private static IEnumerable<string> FindDistinctRelativePathsIn (string css)
{
- var matches = Regex.Matches (css, @"url\([""']{0,1}(.+?)[""']{0,1}\)", RegexOptions.IgnoreCase);
- var matchesHash = new HashSet<string> ();
- foreach (Match match in matches)
- {
- var path = match.Groups[1].Captures[0].Value;
- if (!path.StartsWith ("/") && !path.StartsWith ("http://") && !path.StartsWith ("https://") && !path.StartsWith ("data:") && !path.StartsWith ("squishit://"))
- {
- if (matchesHash.Add (path))
- {
- yield return path;
- }
- }
- }
+ var matches = pathsRegex.Matches(css);
+ return matches.Cast<Match>()
+ .Select(match => match.Groups[1].Captures[0].Value)
+ .Where(path => !path.StartsWith ("/")
+ && !path.StartsWith ("http://")
+ && !path.StartsWith ("https://")
+ && !path.StartsWith ("data:")
+ && !path.StartsWith ("squishit://")
+ && path != "\"\""
+ && path != "''"
+ && !string.IsNullOrEmpty(path)).Distinct();
}
private static IEnumerable<string> FindDistinctLocalRelativePathsThatExist (string css)
{
- var matches = Regex.Matches (css, @"url\([""']{0,1}(.+?)[""']{0,1}\)", RegexOptions.IgnoreCase);
+ var matches = pathsRegex.Matches(css);
var matchesHash = new HashSet<string> ();
foreach (Match match in matches)
{
@@ -20,7 +20,7 @@ public class JavaScriptBundle : BundleBase<JavaScriptBundle>
protected override IMinifier<JavaScriptBundle> DefaultMinifier
{
- get { return Configuration.DefaultJsMinifier(); }
+ get { return Configuration.Instance.DefaultJsMinifier(); }
}
protected override IEnumerable<string> allowedExtensions
@@ -36,7 +36,7 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.8.6.0")]
-[assembly: AssemblyFileVersion("0.8.6.0")]
+[assembly: AssemblyVersion("0.8.7.0")]
+[assembly: AssemblyFileVersion("0.8.7.0")]
[assembly: InternalsVisibleTo("SquishIt.Tests")]
[assembly: AllowPartiallyTrustedCallers]
@@ -32,5 +32,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.8.6.0")]
-[assembly: AssemblyFileVersion("0.8.6.0")]
+[assembly: AssemblyVersion("0.8.7.0")]
+[assembly: AssemblyFileVersion("0.8.7.0")]
@@ -1,9 +1,11 @@
using System;
using System.IO;
+using Moq;
using NUnit.Framework;
using SquishIt.Framework.Css;
using SquishIt.Framework.Minifiers.CSS;
using SquishIt.Framework.Files;
+using SquishIt.Framework.Renderers;
using SquishIt.Framework.Utilities;
using SquishIt.Tests.Helpers;
using SquishIt.Tests.Stubs;
@@ -1004,7 +1006,7 @@ public void CanBundleArbitraryContentsInRelease()
public void PathRewritingDoesNotAffectClassesNamedUrl()
{
string css =
- @"
+ @"
a.url {
color: #4D926F;
}
@@ -1019,9 +1021,45 @@ public void PathRewritingDoesNotAffectClassesNamedUrl()
.Add("~/css/something/test.css")
.Render("~/css/output_rewriting_url.css");
- string contents = cssBundleFactory.FileWriterFactory.Files[TestUtilities.PrepareRelativePath(@"css\output_rewriting_url.css")];
+ string contents =
+ cssBundleFactory.FileWriterFactory.Files[
+ TestUtilities.PrepareRelativePath(@"css\output_rewriting_url.css")];
Assert.AreEqual("a.url{color:#4d926f}", contents);
}
+
+ [Test]
+ public void CanUseArbitraryReleaseRenderer()
+ {
+ var renderer = new Mock<IRenderer>();
+
+ var content = "content";
+
+ var tag = cssBundleFactory
+ .WithDebuggingEnabled(false)
+ .Create()
+ .WithReleaseRenderer(renderer.Object)
+ .AddString(content)
+ .Render("test.css");
+
+ renderer.Verify(r => r.Render(content, TestUtilities.PrepareRelativePath("test.css")));
+ }
+
+ [Test]
+ public void CanIgnoreArbitraryReleaseRendererInDebug()
+ {
+ var renderer = new Mock<IRenderer>();
+
+ var content = "content";
+
+ var tag = cssBundleFactory
+ .WithDebuggingEnabled(true)
+ .Create()
+ .WithReleaseRenderer(renderer.Object)
+ .AddString(content)
+ .Render("test.css");
+
+ renderer.VerifyAll();
+ }
}
}
@@ -337,6 +337,30 @@ public void DontThrowIfPathContainsRegexMetacharacters()
Assert.DoesNotThrow(() => CSSPathRewriter.RewriteCssPaths(targetFile, sourceFile, css, cssAssetsFileHasher));
}
+ [Test]
+ public void DontThrowIfPathIsEmpty()
+ {
+ ICssAssetsFileHasher cssAssetsFileHasher = null;
+ string css =
+ @"
+ .header {
+ background-image: URL("""");
+ background-image: url();
+ }
+
+ .footer {
+ background-image: uRL("""");
+ background-image: UrL('');
+ }
+ ";
+ string sourceFile = TestUtilities.PreparePath(@"C:\somepath\somesubpath\myfile.css");
+ string targetFile = TestUtilities.PreparePath(@"C:\somepath\output.css");
+
+ //concrete result doesn't matter here (since input isn't valid)
+ //the only important thing is that it shouldn't throw exceptions
+ Assert.DoesNotThrow(() => CSSPathRewriter.RewriteCssPaths(targetFile, sourceFile, css, cssAssetsFileHasher));
+ }
+
[Test]
public void WontRewriteAbsolutePaths()
{
@@ -392,5 +416,28 @@ public void WontRewriteDataUrls()
";
Assert.AreEqual(expected, result);
}
+
+ [Test]
+ public void WontRewriteBehaviorUrls()
+ {
+ ICssAssetsFileHasher cssAssetsFileHasher = null;
+ string css =
+ @"
+ .header {
+ behavior: url('somethingorother') no-repeat 0 0;
+ }
+ ";
+ string sourceFile = TestUtilities.PreparePath(@"C:\somepath\somesubpath\myfile.css");
+ string targetFile = TestUtilities.PreparePath(@"C:\somepath\someothersubpath\evendeeper\output.css");
+ string result = CSSPathRewriter.RewriteCssPaths(targetFile, sourceFile, css, cssAssetsFileHasher);
+
+ string expected =
+ @"
+ .header {
+ behavior: url('somethingorother') no-repeat 0 0;
+ }
+ ";
+ Assert.AreEqual(expected, result);
+ }
}
}
Oops, something went wrong.

0 comments on commit ba26514

Please sign in to comment.