forked from madskristensen/WebEssentials2013
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit for madskristensen#418.
- Loading branch information
Showing
16 changed files
with
292 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Globalization; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Text.RegularExpressions; | ||
using System.Web.Helpers; | ||
using MadsKristensen.EditorExtensions.Helpers; | ||
using Microsoft.CSS.Core; | ||
|
||
namespace MadsKristensen.EditorExtensions | ||
{ | ||
public class SassCompiler : NodeExecutorBase | ||
{ | ||
private static readonly string _compilerPath = Path.Combine(WebEssentialsResourceDirectory, @"nodejs\node_modules\node-sass\bin\node-sass"); | ||
private static readonly Regex _endingCurlyBraces = new Regex(@"}\W*}|}", RegexOptions.Compiled); | ||
private static readonly Regex _linesStartingWithTwoSpaces = new Regex("(\n( *))", RegexOptions.Compiled); | ||
private static readonly Regex _errorParsingPattern = new Regex(@"^(?<message>.+) in (?<fileName>.+) on line (?<line>\d+), column (?<column>\d+):$", RegexOptions.Multiline); | ||
private static readonly Regex _sourceMapInCss = new Regex(@"\/\*#([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/", RegexOptions.Multiline); | ||
|
||
protected override string ServiceName | ||
{ | ||
get { return "SASS"; } | ||
} | ||
protected override string CompilerPath | ||
{ | ||
get { return _compilerPath; } | ||
} | ||
protected override Regex ErrorParsingPattern | ||
{ | ||
get { return _errorParsingPattern; } | ||
} | ||
protected override string GetArguments(string sourceFileName, string targetFileName) | ||
{ | ||
var args = new StringBuilder("--no-color --relative-urls "); | ||
|
||
if (WESettings.GetBoolean(WESettings.Keys.SassSourceMaps) && !InUnitTests) | ||
{ | ||
args.Append("--source-comments=map"); | ||
} | ||
|
||
args.AppendFormat(CultureInfo.CurrentCulture, "\"{0}\" \"{1}\"", sourceFileName, targetFileName); | ||
return args.ToString(); | ||
} | ||
|
||
protected override string PostProcessResult(string resultSource, string sourceFileName, string targetFileName) | ||
{ | ||
// Inserts an empty row between each rule and replace two space indentation with 4 space indentation | ||
resultSource = _endingCurlyBraces.Replace(_linesStartingWithTwoSpaces.Replace(resultSource.Trim(), "$1$2"), "$&\n"); | ||
resultSource = UpdateSourceMapUrls(resultSource, targetFileName); | ||
|
||
var message = "SASS: " + Path.GetFileName(sourceFileName) + " compiled."; | ||
|
||
// If the caller wants us to renormalize URLs to a different filename, do so. | ||
if (targetFileName != null && resultSource.IndexOf("url(", StringComparison.OrdinalIgnoreCase) > 0) | ||
{ | ||
try | ||
{ | ||
resultSource = CssUrlNormalizer.NormalizeUrls( | ||
tree: new CssParser().Parse(resultSource, true), | ||
targetFile: targetFileName, | ||
oldBasePath: sourceFileName | ||
); | ||
} | ||
catch (Exception ex) | ||
{ | ||
message = "SASS: An error occurred while normalizing generated paths in " + sourceFileName + "\r\n" + ex; | ||
} | ||
} | ||
|
||
Logger.Log(message); | ||
|
||
return resultSource; | ||
} | ||
|
||
private static string UpdateSourceMapUrls(string content, string compiledFileName) | ||
{ | ||
if (!WESettings.GetBoolean(WESettings.Keys.SassSourceMaps) || !File.Exists(compiledFileName)) | ||
return content; | ||
|
||
string sourceMapFilename = compiledFileName + ".map"; | ||
|
||
if (!File.Exists(sourceMapFilename)) | ||
return content; | ||
|
||
var updatedFileContent = GetUpdatedSourceMapFileContent(compiledFileName, sourceMapFilename); | ||
|
||
if (updatedFileContent == null) | ||
return content; | ||
|
||
FileHelpers.WriteFile(updatedFileContent, sourceMapFilename); | ||
ProjectHelpers.AddFileToProject(compiledFileName, sourceMapFilename); | ||
|
||
return UpdateSourceLinkInCssComment(content, FileHelpers.RelativePath(compiledFileName, sourceMapFilename)); | ||
} | ||
|
||
private static string GetUpdatedSourceMapFileContent(string cssFileName, string sourceMapFilename) | ||
{ | ||
// Read JSON map file and deserialize. | ||
dynamic jsonSourceMap = Json.Decode(File.ReadAllText(sourceMapFilename)); | ||
|
||
if (jsonSourceMap == null) | ||
return null; | ||
|
||
jsonSourceMap.sources = ((IEnumerable<dynamic>)jsonSourceMap.sources).Select(s => FileHelpers.RelativePath(cssFileName, s)); | ||
jsonSourceMap.names = new List<dynamic>(jsonSourceMap.names); | ||
jsonSourceMap.file = Path.GetFileName(cssFileName); | ||
|
||
return Json.Encode(jsonSourceMap); | ||
} | ||
|
||
private static string UpdateSourceLinkInCssComment(string content, string sourceMapRelativePath) | ||
{ // Fix sourceMappingURL comment in CSS file with network accessible path. | ||
return _sourceMapInCss.Replace(content, | ||
string.Format(CultureInfo.CurrentCulture, "/*# sourceMappingURL={0} */", sourceMapRelativePath)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace MadsKristensen.EditorExtensions | ||
{ | ||
internal class SassProjectCompiler : ProjectCompilerBase | ||
{ | ||
protected override string ServiceName | ||
{ | ||
get { return "SASS"; } | ||
} | ||
|
||
protected override string CompileToExtension | ||
{ | ||
get { return ".css"; } | ||
} | ||
|
||
protected override string CompileToLocation | ||
{ | ||
get { return WESettings.GetString(WESettings.Keys.SassCompileToLocation); } | ||
} | ||
|
||
protected override NodeExecutorBase Compiler | ||
{ | ||
get { return new SassCompiler(); } | ||
} | ||
|
||
protected override IEnumerable<string> Extensions | ||
{ | ||
get | ||
{ | ||
return new string[] { ".scss" }; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
using System; | ||
using System.IO; | ||
using System.Linq; | ||
using EnvDTE; | ||
using Microsoft.VisualStudio.Text; | ||
|
||
namespace MadsKristensen.EditorExtensions | ||
{ | ||
public class SassMargin : MarginBase | ||
{ | ||
public const string MarginName = "SassMargin"; | ||
|
||
public SassMargin(string contentType, string source, bool showMargin, ITextDocument document) | ||
: base(source, MarginName, contentType, showMargin, document) | ||
{ } | ||
|
||
protected override async void StartCompiler(string source) | ||
{ | ||
if (!CompileEnabled) | ||
return; | ||
|
||
string sassFilePath = Document.FilePath; | ||
|
||
string cssFilename = GetCompiledFileName(sassFilePath, ".css", CompileEnabled ? CompileToLocation : null); | ||
|
||
if (IsFirstRun && File.Exists(cssFilename)) | ||
{ | ||
OnCompilationDone(File.ReadAllText(cssFilename), sassFilePath); | ||
return; | ||
} | ||
|
||
Logger.Log("SASS: Compiling " + Path.GetFileName(sassFilePath)); | ||
|
||
var result = await new SassCompiler().Compile(sassFilePath, cssFilename); | ||
|
||
if (result.IsSuccess) | ||
{ | ||
OnCompilationDone(result.Result, result.FileName); | ||
} | ||
else | ||
{ | ||
result.Errors.First().Message = "SASS: " + result.Errors.First().Message; | ||
|
||
CreateTask(result.Errors.First()); | ||
|
||
base.OnCompilationDone("ERROR:" + result.Errors.First().Message, sassFilePath); | ||
} | ||
} | ||
|
||
protected override void MinifyFile(string fileName, string source) | ||
{ | ||
if (!CompileEnabled) | ||
return; | ||
|
||
if (WESettings.GetBoolean(WESettings.Keys.SassMinify) && !Path.GetFileName(fileName).StartsWith("_", StringComparison.Ordinal)) | ||
{ | ||
FileHelpers.MinifyFile(fileName, source, ".css"); | ||
} | ||
} | ||
|
||
public override bool CompileEnabled | ||
{ | ||
get { return WESettings.GetBoolean(WESettings.Keys.SassEnableCompiler); } | ||
} | ||
|
||
public override string CompileToLocation | ||
{ | ||
get { return WESettings.GetString(WESettings.Keys.SassCompileToLocation); } | ||
} | ||
|
||
public override bool IsSaveFileEnabled | ||
{ | ||
get { return WESettings.GetBoolean(WESettings.Keys.GenerateCssFileFromSass) && !Path.GetFileName(Document.FilePath).StartsWith("_", StringComparison.Ordinal); } | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.