Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Sync with bitbucket repo

  • Loading branch information...
DavidZidar committed Aug 26, 2012
1 parent 515785d commit 1352c58728d42e1d8ede0c866485d8c8af625715
Showing with 264 additions and 150 deletions.
  1. +8 −7 .gitignore
  2. +4 −4 NuGet/CacheTag.nuspec
  3. +55 −60 README.md
  4. +2 −1 Source/CacheTag.Core/CacheTag.Core.csproj
  5. +31 −0 Source/CacheTag.Core/Configuration/CacheTagSettings.cs
  6. +59 −0 Source/CacheTag.Core/Configuration/MimeTypeMap.cs
  7. +1 −1 Source/CacheTag.Core/Extensions/ResourceExtensions.cs
  8. +1 −1 Source/CacheTag.Core/Properties/AssemblyInfo.cs
  9. +5 −3 Source/CacheTag.Core/Resources/BaseFileResource.cs
  10. +1 −1 Source/CacheTag.Core/Resources/BaseSnippet.cs
  11. +1 −1 Source/CacheTag.Core/Resources/Html/ImageHtmlRenderer.cs
  12. +2 −2 Source/CacheTag.Core/Resources/Html/ScriptHtmlRenderer.cs
  13. +2 −2 Source/CacheTag.Core/Resources/Html/StyleHtmlRenderer.cs
  14. +2 −15 Source/CacheTag.Core/Resources/Images/ImageFile.cs
  15. +3 −2 Source/CacheTag.Module.AjaxMin/AjaxMinResourceCompiler.cs
  16. +2 −3 Source/CacheTag.Module.AjaxMin/CacheTag.Module.AjaxMin.csproj
  17. +1 −1 Source/CacheTag.Module.AjaxMin/Properties/AssemblyInfo.cs
  18. +1 −1 Source/CacheTag.Module.AjaxMin/packages.config
  19. +2 −2 Source/CacheTag.Module.DotLess/CacheTag.Module.DotLess.csproj
  20. +1 −1 Source/CacheTag.Module.DotLess/Properties/AssemblyInfo.cs
  21. +1 −1 Source/CacheTag.Module.DotLess/packages.config
  22. +1 −1 Source/CacheTag.Module.SassAndCoffee/Properties/AssemblyInfo.cs
  23. +1 −1 Source/CacheTag.Mvc/CacheTag.Mvc.csproj
  24. +7 −0 Source/CacheTag.Mvc/CacheTagMvcSettings.cs
  25. +8 −1 Source/CacheTag.Mvc/MvcUrlResolver.cs
  26. +1 −1 Source/CacheTag.Mvc/Properties/AssemblyInfo.cs
  27. +20 −9 Source/CacheTag.Mvc/Routing.cs
  28. +2 −2 Source/CacheTag.Tests/CacheTag.Tests.csproj
  29. +1 −1 Source/CacheTag.Tests/Properties/AssemblyInfo.cs
  30. +1 −1 Source/CacheTag.Tests/packages.config
  31. +8 −8 Source/CacheTag.sln
  32. +17 −6 Source/Example.Mvc/Example.Mvc.csproj
  33. +4 −2 Source/Example.Mvc/Global.asax.cs
  34. +1 −1 Source/Example.Mvc/Properties/AssemblyInfo.cs
  35. +6 −6 Source/Example.Mvc/Views/Home/Index.cshtml
  36. +1 −1 Source/Example.Mvc/packages.config
@@ -3,12 +3,13 @@
bin/
obj/

_ReSharper\.[\w\d\.]+/
_ReSharper.*/
packages/

\.user$
\.suo$
\.sln\.cache$
\.dotCover$
\.docstates$
\.Publish\.xml$
*.user
*.suo
*.sln.cache
*.dotCover
*.docstates
*.Publish.xml
*.ncrunchsolution
@@ -2,16 +2,16 @@
<package >
<metadata>
<id>CacheTag</id>
<version>1.0.0-beta3</version>
<version>1.0.0-beta5</version>
<authors>Steamcore</authors>
<owners>Steamcore</owners>
<projectUrl>http://cachetag.net/</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Simple and efficient JavaScript and CSS minification for ASP.NET MVC</description>
<releaseNotes>Fixed concurrency issue, updated AjaxMin to v4.54</releaseNotes>
<releaseNotes>Updated AjaxMin to v4.62, behavioural changes regarding file extensions and hashes in debug mode</releaseNotes>
<dependencies>
<dependency id="AjaxMin" version="4.54.4533.37029" />
<dependency id="dotless" version="1.3.0.3" />
<dependency id="AjaxMin" version="4.62.4618.15628" />
<dependency id="dotless" version="1.3.0.5" />
<dependency id="Microsoft.Web.Infrastructure" version="1.0.0.0" />
<dependency id="WebActivator" version="1.5.1" />
</dependencies>
115 README.md
@@ -27,37 +27,32 @@ CacheTag provides a number of benefits compared to other similar frameworks.
How to get started
------------------

Add project references to `CacheTag.Core` and the modules you need, `CacheTag.Mvc` is a required module for now.
Add project references to **`CacheTag.Core`** and the modules you need, **`CacheTag.Mvc`** is a required module for now.

ASP.NET MVC Razor example
-------------------------

Try something like this in a view:

```csharp
@Html.RenderStyles(new []
{
"~/CSS/Reset.css",
"~/CSS/Site.less"
})
@Html.RenderScripts(new []
{
"~/Scripts/jquery-1.7.1.js",
"~/Scripts/app.coffee"
})
```
:::csharp
@Html.RenderStyles(new []
{
"~/CSS/Reset.css",
"~/CSS/Site.less"
})
@Html.RenderScripts(new []
{
"~/Scripts/jquery-1.7.1.js",
"~/Scripts/app.coffee"
})

You can also reference scripts or styles mid page like this:

```csharp
@Html.ReferenceScript("~/Scripts/flot.js")
```
@Html.ReferenceScript("~/Scripts/flot.js")

And then render all referenced scripts at once at the end of the page:

```csharp
@Html.RenderReferencedScripts()
```
@Html.RenderReferencedScripts()

If you want, you can render scripts or styles inline as well, just add Inline to any render method.

@@ -66,22 +61,20 @@ Advanced examples

Or you can build your scripts and styles manually:

```csharp
var styleTags = new StyleList(new [] { "~/CSS/Reset.css", "~/CSS/Site.less" }).Compile().RenderHtml();
var scriptTags = new ScriptList(new [] { "~/Scripts/jquery-1.7.1.js", "~/Scripts/app.coffee" }).Compile().RenderHtml();
```
:::csharp
var styleTags = new StyleList(new [] { "~/CSS/Reset.css", "~/CSS/Site.less" }).Compile().RenderHtml();
var scriptTags = new ScriptList(new [] { "~/Scripts/jquery-1.8.0.js", "~/Scripts/app.coffee" }).Compile().RenderHtml();

`ScriptList` and `StyleList` are just there for convenience, they only inherit from `List<IScriptList>` and `List<IStyleList>` respectively and do a bit of magic to resolve the type of resources based on the file name.

Since we are working with lists, it's easy to do what you want with it.

```csharp
var scriptUrls =
new [] {
new ScriptFile("~/Scripts/jquery-1.7.1.js"),
new CoffeeScript("~/Scripts/app.coffee")
}.Compile().Select(x => x.Url);
```
:::csharp
var scriptUrls =
new [] {
new ScriptFile("~/Scripts/jquery-1.8.0.js"),
new CoffeeScript("~/Scripts/app.coffee")
}.Compile().Select(x => x.Url);

The code snippet above will load two scripts, compile them if in release mode, and return a list of their resulting URLs. This might be useful for lazy loading scripts via yepnope or something similar.

@@ -90,22 +83,19 @@ Example of resulting HTML in release mode

In release mode resources are combined, and minified if a minification module is referenced, to reduce the number of HTTP requests the client has to make.

```html
<link rel="stylesheet" type="text/css" href="/_cachetag/e4dddf2cdd91d693e023cdc5dc0b56d8664766db" />
<script src="/_cachetag/80e9e6fc43c6644ea9badec99eb5c6cbec87c4b0" type="text/javascript"></script>
```
<link rel="stylesheet" type="text/css" href="/_cachetag/e4dddf2cdd91d693e023cdc5dc0b56d8664766db.css" />
<script src="/_cachetag/80e9e6fc43c6644ea9badec99eb5c6cbec87c4b0.js" type="text/javascript"></script>
Example of resulting HTML in debug mode
---------------------------------------
When Web.config is configured for debug mode, resources ar linked individually with a SHA1-hash to ease debugging and prevent any browser cache issues.
```html
<link rel="stylesheet" type="text/css" href="/CSS/Reset.css?f49b5e57ac2258bd3c980f30271554fa4731f26d" />
<link rel="stylesheet" type="text/css" href="/CSS/Site.less?b8193c8e87d1b1f3cc6b8ad5ef3d9a1ac2b68961" />
<script src="/Scripts/jquery-1.7.1.js?b47730ffaec4272a8a01756af2ef13ecea1c4e92" type="text/javascript"></script>
<script src="/Scripts/app.coffee?57818a7855d3931d2884ff32e0949888a225f0d1" type="text/javascript"></script>
```
:::html
<link rel="stylesheet" type="text/css" href="/CSS/Reset.css" />
<link rel="stylesheet" type="text/css" href="/CSS/Site.less" />
<script src="/Scripts/jquery-1.8.0.js" type="text/javascript"></script>
<script src="/Scripts/app.coffee" type="text/javascript"></script>
**Note**: To serve .less and .coffee-files individually in debug mode, you need to add their respective HTTP handlers manually (or via NuGet) to your web project.
@@ -114,70 +104,75 @@ Available modules
To use a module, simply make a project reference, it will be configured automatically.
`CacheTag.Mvc`
**`CacheTag.Mvc`**
Registers routes and an MVC controller for serving scripts
`CacheTag.Modules.AjaxMin`
**`CacheTag.Modules.AjaxMin`**
Minifies scripts and stylesheets using AjaxMin, depends on `AjaxMin`
`CacheTag.Modules.DotLess`
**`CacheTag.Modules.DotLess`**
Support for .less style sheets files, depends on `dotless.Core`
`CacheTag.Modules.SassAndCoffee`
**`CacheTag.Modules.SassAndCoffee`**
Provides support for .coffee-scripts for now, depends on `SassAndCoffee.Core` and `SassAndCoffee.JavaScript`
Configuration
-------------
The idea is sane defaults and zero configuration, but there are some things you can configure if you want.
`CacheTag.Core.Configuration.Settings.HashAlgorithm`
`CacheTagSettings`.**`HashAlgorithm`**
MD5 is used by default
`CacheTag.Core.Configuration.Settings.RuntimeMode`
`CacheTagSettings`.**`RuntimeMode`**
Default mode is Dynamic, other options are ForceDebug or ForceRelease
`CacheTag.Mvc.MvcSettings.RouteUrl`
`CacheTagSettings`.**`HashFilesInDebugMode`**
If true, then CacheTag will append hash of files includeded in debug mode to force browsers to reload changed resources. Default is off because this confuses debuggers
`CacheTagSettings`.**`HideFileExtensions`**
Set to true if you think file extensions are unnecessary
`CacheTagMvcSettings`.**`RouteUrl`**
Default value is `"_cachetag/{id}"`
Create your own module
----------------------
Implement ICacheTagModule and it will automatically be run on startup.
```csharp
public class ModuleConfiguration : ICacheTagModule
{
public void Initialize()
:::csharp
public class ModuleConfiguration : ICacheTagModule
{
CacheTag.Core.Configuration.Settings.RuntimeMode = RuntimeMode.ForceRelease;
public void Initialize()
{
CacheTag.Core.Configuration.Settings.RuntimeMode = RuntimeMode.ForceRelease;
}
}
}
```
Extension methods
-----------------
Most of CacheTag is based around a couple of extension methods operating on either `IEnumerable<IScriptResource>` or `IEnumerable<IStyleResource>`, these are explained here.
`Compile()`
**`Compile()`**
When operating in debug mode, Compile() does nothing, it just returns the same list it was passed. When in release mode however, it will compile the list of resources using whatever resource compiler is registered for that type of resource. For instance, when using the AjaxMin module, Compile() will minify the list and return a list of one item.
In release mode Compile() also calls Store(), see below.
`RenderHtml()`
**`RenderHtml()`**
Renders HTML script tags with items linked as external resources.
`RenderHtmlInline()`
**`RenderHtmlInline()`**
Renders HTML script tags with the resource content inlined.
`RenderMvcHtml()`
**`RenderMvcHtml()`**
Calls RenderHtml() but wraps the result in a IHtmlString.
`RenderMvcHtmlInline()`
**`RenderMvcHtmlInline()`**
Calls RenderHtmlInline() but wraps the result in a IHtmlString.
`Store()`
**`Store()`**
When serving items as external resources they have to be stored somewhere so they can be retrieved when the browser next requests them. Therefore Store() saves the list of resources in a static Dictionary<> in the class ResourceStorage.
When running a site in production, scripts and styles tend to be static, so storing your compiled resources in a static dictionary should not be a problem.
@@ -57,8 +57,9 @@
<Compile Include="Cache\ICacheProvider.cs" />
<Compile Include="Configuration\Container.cs" />
<Compile Include="Configuration\IUrlResolver.cs" />
<Compile Include="Configuration\MimeTypeMap.cs" />
<Compile Include="Configuration\RuntimeMode.cs" />
<Compile Include="Configuration\Settings.cs" />
<Compile Include="Configuration\CacheTagSettings.cs" />
<Compile Include="Extensions\HashAlgorithmExtensions.cs" />
<Compile Include="Extensions\ResourceExtensions.cs" />
<Compile Include="Extensions\StreamExtensions.cs" />
@@ -0,0 +1,31 @@
// ReSharper disable FieldCanBeMadeReadOnly.Global
// ReSharper disable ConvertToConstant.Global

using System.Web;

namespace CacheTag.Core.Configuration
{
public static class CacheTagSettings
{
public const string AssemblyVersion = "1.0.*";

public static string HashAlgorithm = "System.Security.Cryptography.MD5";
public static RuntimeMode RuntimeMode = RuntimeMode.Dynamic;
public static bool HashFilesInDebugMode = false;
public static bool HideFileExtensions = false;

public static string ImageTagFormat = @"<img src=""{0}"" width=""{1}"" height=""{2}"" alt=""{3}"" />";
public static string ScriptTagFormat = @"<script src=""{0}"" type=""text/javascript""></script>";
public static string StyleTagFormat = @"<link rel=""stylesheet"" type=""text/css"" href=""{0}"" />";
public static string InlineScriptTagFormat = @"<script type=""text/javascript"">{0}</script>";
public static string InlineStyleTagFormat = @"<style type=""text/css"">{0}</style>";

public static bool IsReleaseMode
{
get
{
return RuntimeMode == RuntimeMode.ForceRelease || HttpContext.Current.IsDebuggingEnabled == false;
}
}
}
}
@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace CacheTag.Core.Configuration
{
public static class FileExtensions
{
public static string GetMimeType(string extension)
{
switch (extension.ToLowerInvariant())
{
case ".jpg":
case ".jpeg":
return "image/jpeg";

case ".gif":
return "image/gif";

case ".png":
return "image/png";

default:
throw new ArgumentException("Unknown file extension");
}
}
}

public static class MimeTypes
{
public static string GetFileExtension(string mimeType)
{
switch (mimeType.ToLowerInvariant())
{
case "application/x-javascript":
case "application/javascript":
case "application/ecmascript":
case "text/javascript":
case "text/ecmascript":
return ".js";

case "text/css":
return ".css";

case "image/jpeg":
return ".jpg";

case "image/gif":
return ".gif";

case "image/png":
return ".png";

default:
throw new ArgumentException("Unknown mime type");
}
}
}
}
@@ -13,7 +13,7 @@ public static class ResourceExtensions
public static IEnumerable<T> Compile<T>(this IEnumerable<T> items)
where T : IResource
{
return Settings.IsReleaseMode ? Container.Resolve<IResourceCompiler<T>>().Compile(items).Store() : items;
return CacheTagSettings.IsReleaseMode ? Container.Resolve<IResourceCompiler<T>>().Compile(items).Store() : items;
}

public static T Store<T>(this T item)
@@ -29,4 +29,4 @@
// Build Number
// Revision
//
[assembly: AssemblyVersion(Settings.AssemblyVersion)]
[assembly: AssemblyVersion(CacheTagSettings.AssemblyVersion)]
@@ -61,14 +61,16 @@ protected BaseFileResource(string path, string mimeType, IFileProvider fileProvi

protected virtual void LoadFileProperties(Dictionary<string, object> properties)
{
using (var hashAlgorithm = HashAlgorithm.Create(Settings.HashAlgorithm))
using (var hashAlgorithm = HashAlgorithm.Create(CacheTagSettings.HashAlgorithm))
{
var binaryContent = fileProvider.ReadContent();
properties["BinaryContent"] = binaryContent;
properties["Hash"] = hashAlgorithm.ComputeStringHash(binaryContent);
properties["Url"] = Settings.IsReleaseMode
properties["Url"] = CacheTagSettings.IsReleaseMode
? Container.Resolve<IUrlResolver>().GetResourceUrl(this)
: string.Format("{0}?{1}", fileProvider.AppRelativePath, Hash);
: CacheTagSettings.HashFilesInDebugMode
? string.Format("{0}?{1}", fileProvider.AppRelativePath, Hash)
: fileProvider.AppRelativePath;
}
}
}
@@ -18,7 +18,7 @@ public abstract class BaseSnippet : IPlainTextResource

protected BaseSnippet(string snippet)
{
using (var hashAlgorithm = HashAlgorithm.Create(Settings.HashAlgorithm))
using (var hashAlgorithm = HashAlgorithm.Create(CacheTagSettings.HashAlgorithm))
{
Content = snippet;
Hash = hashAlgorithm.ComputeStringHash(snippet);

0 comments on commit 1352c58

Please sign in to comment.
You can’t perform that action at this time.