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;
public class LessMinify : IBundleTransform
{
public void Process(BundleContext context, BundleResponse bundle)
{
if (bundle == null)
{
throw new ArgumentNullException("bundle");
}
context.HttpContext.Response.Cache.SetLastModifiedFromFileDependencies();
var lessParser = new Parser();
ILessEngine lessEngine = CreateLessEngine(lessParser);
var content = new StringBuilder(bundle.Content.Length);
foreach (FileInfo file in bundle.Files)
{
SetCurrentFilePath(lessParser, file.FullName);
string source = File.ReadAllText(file.FullName);
content.Append(lessEngine.TransformToCss(source, file.FullName));
content.AppendLine();
AddFileDependencies(lessParser);
}
bundle.ContentType = "text/css";
bundle.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 (string importedFilePath in lessParser.Importer.Imports)
{
string 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)
{
var fileReader = importer.FileReader as FileReader;
if (fileReader != null)
{
return fileReader.PathResolver;
}
}
return 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)
{
var fileReader = importer.FileReader as FileReader;
if (fileReader == null)
{
importer.FileReader = fileReader = new FileReader();
}
var pathResolver = fileReader.PathResolver as ImportedFilePathResolver;
if (pathResolver != null)
{
pathResolver.CurrentFilePath = currentFilePath;
}
else
{
fileReader.PathResolver = new ImportedFilePathResolver(currentFilePath);
}
}
else
{
throw new InvalidOperationException("Unexpected importer type on dotless parser");
}
}
}