Skip to content

Instantly share code, notes, and snippets.

@linuxbender
Created September 20, 2012 12:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save linuxbender/3755632 to your computer and use it in GitHub Desktop.
Save linuxbender/3755632 to your computer and use it in GitHub Desktop.
LessMinify.cs
using System.IO;
using System.Web;
using System.Web.Hosting;
using dotless.Core.Input;
namespace theForce.App_Start
{
public class LessImportResolver : IPathResolver
{
private string _currentFileDirectory;
private string _currentFilePath;
public LessImportResolver(string currentFilePath)
{
CurrentFilePath = currentFilePath;
}
///Gets or sets the path to the currently processed file.
public string CurrentFilePath
{
get { return _currentFilePath; }
set
{
_currentFilePath = value;
_currentFileDirectory = Path.GetDirectoryName(value);
}
}
///Returns the absolute path for the specified improted file path.
///
///The imported file path.
public string GetFullPath(string filePath)
{
filePath = filePath.Replace('\\', '/').Trim();
return FilePath(filePath);
}
private string FilePath(string filePath)
{
if (filePath.StartsWith("~"))
{
filePath = VirtualPathUtility.ToAbsolute(filePath);
}
if (filePath.StartsWith("/"))
{
filePath = HostingEnvironment.MapPath(filePath);
}
else if (!Path.IsPathRooted(filePath))
{
filePath = Path.Combine(_currentFileDirectory, filePath);
}
return filePath;
}
}
}
using System;
using System.IO;
using System.Text;
using System.Web;
using System.Web.Optimization;
using dotless.Core;
using dotless.Core.Abstractions;
using dotless.Core.Importers;
using dotless.Core.Input;
using dotless.Core.Loggers;
using dotless.Core.Parser;
namespace theForce.App_Start
{
public class LessMinify : IBundleTransform
{
public void Process(BundleContext context, BundleResponse response)
{
if (response == null)
{
throw new ArgumentNullException("bundle");
}
context.HttpContext.Response.Cache.SetLastModifiedFromFileDependencies();
var lessParser = new Parser();
ILessEngine lessEngine = CreateLessEngine(lessParser);
var content = new StringBuilder(response.Content.Length);
foreach (var file in response.Files)
{
SetCurrentFilePath(lessParser, file.FullName);
var source = File.ReadAllText(file.FullName);
content.Append(lessEngine.TransformToCss(source, file.FullName));
content.AppendLine();
AddFileDependencies(lessParser);
}
response.ContentType = "text/css";
response.Content = content.ToString();
}
///Creates an instance of LESS engine.
///
///The LESS parser.
private ILessEngine CreateLessEngine(Parser lessParser)
{
var logger = new AspNetTraceLogger(LogLevel.Debug, new Http());
return new LessEngine(lessParser, logger, true, false);
}
///Adds imported files to the collection of files on which the current response is dependent.
///
///The LESS parser.
private void AddFileDependencies(Parser lessParser)
{
IPathResolver pathResolver = GetPathResolver(lessParser);
foreach (var importedFilePath in lessParser.Importer.Imports)
{
var fullPath = pathResolver.GetFullPath(importedFilePath);
HttpContext.Current.Response.AddFileDependency(fullPath);
}
lessParser.Importer.Imports.Clear();
}
///Returns an instance used by the specified LESS lessParser.
///
///The LESS prser.
private IPathResolver GetPathResolver(Parser lessParser)
{
var importer = lessParser.Importer as Importer;
if (importer == null) return null;
var fileReader = importer.FileReader as FileReader;
return fileReader != null ? fileReader.PathResolver : null;
}
///Informs the LESS parser about the path to the currently processed file.
///This is done by using custom implementation.
///
///The LESS parser.
///The path to the currently processed file.
private void SetCurrentFilePath(Parser lessParser, string currentFilePath)
{
var importer = lessParser.Importer as Importer;
if (importer == null)
{
throw new InvalidOperationException("Unexpected importer type on dotless parser");
}
var fileReader = importer.FileReader as FileReader;
if (fileReader == null)
{
importer.FileReader = fileReader = new FileReader();
}
var pathResolver = fileReader.PathResolver as LessImportResolver;
if (pathResolver == null)
{
fileReader.PathResolver = new LessImportResolver(currentFilePath);
}
else
{
pathResolver.CurrentFilePath = currentFilePath;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment