diff --git a/.gitignore b/.gitignore index 33a1f79b..49ea30a4 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,7 @@ x64/ # NCrunch *.ncrunchsolution *.ncrunchproject -_NCrunch_WebCompiler \ No newline at end of file +_NCrunch_WebCompiler#Node + +#Node +src/WebCompiler/Node/node_modules/* \ No newline at end of file diff --git a/build/build.cmd b/build/build.cmd index 28bfd74c..3dd93c03 100644 --- a/build/build.cmd +++ b/build/build.cmd @@ -17,6 +17,7 @@ call npm install --quiet ^ less-plugin-csscomb ^ node-sass ^ stylus ^ + handlebars ^ > nul if not exist "node_modules\node-sass\vendor\win32-ia32-14" ( diff --git a/src/WebCompiler/Compile/CompilerService.cs b/src/WebCompiler/Compile/CompilerService.cs index 8bf0c219..119b7ff0 100644 --- a/src/WebCompiler/Compile/CompilerService.cs +++ b/src/WebCompiler/Compile/CompilerService.cs @@ -10,12 +10,12 @@ namespace WebCompiler /// public static class CompilerService { - internal const string Version = "1.4.166"; + internal const string Version = "1.4.167"; private static readonly string _path = Path.Combine(Path.GetTempPath(), "WebCompiler" + Version); private static object _syncRoot = new object(); // Used to lock on the initialize step /// A list of allowed file extensions. - public static readonly string[] AllowedExtensions = new[] { ".LESS", ".SCSS", ".SASS", ".STYL", ".COFFEE", ".ICED", ".JS", ".JSX", ".ES6" }; + public static readonly string[] AllowedExtensions = new[] { ".LESS", ".SCSS", ".SASS", ".STYL", ".COFFEE", ".ICED", ".JS", ".JSX", ".ES6", ".HBS", ".HANDLEBARS" }; /// /// Test if a file type is supported by the compilers. @@ -42,6 +42,11 @@ internal static ICompiler GetCompiler(Config config) compiler = new LessCompiler(_path); break; + case ".HANDLEBARS": + case ".HBS": + compiler = new HandlebarsCompiler(_path); + break; + case ".SCSS": case ".SASS": compiler = new SassCompiler(_path); diff --git a/src/WebCompiler/Compile/HandlebarsCompiler.cs b/src/WebCompiler/Compile/HandlebarsCompiler.cs new file mode 100644 index 00000000..7a0070ef --- /dev/null +++ b/src/WebCompiler/Compile/HandlebarsCompiler.cs @@ -0,0 +1,200 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; + +namespace WebCompiler +{ + class HandlebarsCompiler : ICompiler + { + private static Regex _errorRx = new Regex("Error: (?.+) on line (?[0-9]+):", RegexOptions.Compiled); + private string _mapPath; + private string _path; + private string _name = string.Empty; + private string _extension = string.Empty; + private string _output = string.Empty; + private string _error = string.Empty; + private bool _partial = false; + + public HandlebarsCompiler(string path) + { + _path = path; + } + + public CompilerResult Compile(Config config) + { + string baseFolder = Path.GetDirectoryName(config.FileName); + string inputFile = Path.Combine(baseFolder, config.InputFile); + + FileInfo info = new FileInfo(inputFile); + string content = File.ReadAllText(info.FullName); + + CompilerResult result = new CompilerResult + { + FileName = info.FullName, + OriginalContent = content, + }; + + var extension = Path.GetExtension(inputFile); + if (!string.IsNullOrWhiteSpace(extension)) + { + _extension = extension.Substring(1); + } + + var name = Path.GetFileNameWithoutExtension(inputFile); + if (!string.IsNullOrWhiteSpace(name) && name.StartsWith("_")) + { + _name = name.Substring(1); + _partial = true; + + // Temporarily Fix + // TODO: Remove after actual fix + var tempFilename = Path.Combine(Path.GetDirectoryName(inputFile), _name + ".handlebarstemp"); + info.CopyTo(tempFilename); + info = new FileInfo(tempFilename); + _extension = "handlebarstemp"; + } + + _mapPath = Path.ChangeExtension(inputFile, ".js.map.tmp"); + + try + { + RunCompilerProcess(config, info); + + result.CompiledContent = _output; + + var options = HandlebarsOptions.FromConfig(config); + if (options.SourceMap || config.SourceMap) + { + if (File.Exists(_mapPath)) + result.SourceMap = File.ReadAllText(_mapPath); + } + + if (_error.Length > 0) + { + CompilerError ce = new CompilerError + { + FileName = inputFile, + Message = _error.Replace(baseFolder, string.Empty), + IsWarning = !string.IsNullOrEmpty(_output) + }; + + var match = _errorRx.Match(_error); + + if (match.Success) + { + ce.Message = match.Groups["message"].Value.Replace(baseFolder, string.Empty); + ce.LineNumber = int.Parse(match.Groups["line"].Value); + ce.ColumnNumber = 0; + } + + result.Errors.Add(ce); + } + } + catch (Exception ex) + { + CompilerError error = new CompilerError + { + FileName = inputFile, + Message = string.IsNullOrEmpty(_error) ? ex.Message : _error, + LineNumber = 0, + ColumnNumber = 0, + }; + + result.Errors.Add(error); + } + finally + { + if (File.Exists(_mapPath)) + { + File.Delete(_mapPath); + } + // Temporarily Fix + // TODO: Remove after actual fix + if (info.Extension == ".handlebarstemp") + { + info.Delete(); + } + } + + return result; + } + + private void RunCompilerProcess(Config config, FileInfo info) + { + string arguments = ConstructArguments(config); + + ProcessStartInfo start = new ProcessStartInfo + { + WorkingDirectory = info.Directory.FullName, + UseShellExecute = false, + WindowStyle = ProcessWindowStyle.Hidden, + CreateNoWindow = true, + FileName = "cmd.exe", + Arguments = $"/c \"\"{Path.Combine(_path, "node_modules\\.bin\\handlebars.cmd")}\" \"{info.FullName}\" {arguments}\"", + StandardOutputEncoding = Encoding.UTF8, + StandardErrorEncoding = Encoding.UTF8, + RedirectStandardOutput = true, + RedirectStandardError = true, + }; + + start.EnvironmentVariables["PATH"] = _path + ";" + start.EnvironmentVariables["PATH"]; + + using (Process p = Process.Start(start)) + { + var stdout = p.StandardOutput.ReadToEndAsync(); + var stderr = p.StandardError.ReadToEndAsync(); + p.WaitForExit(); + + _output = stdout.Result.Trim(); + _error = stderr.Result.Trim(); + } + } + + private string ConstructArguments(Config config) + { + string arguments = ""; + + HandlebarsOptions options = HandlebarsOptions.FromConfig(config); + + if (options.AMD) + arguments += " --amd"; + else if (!string.IsNullOrEmpty(options.CommonJS)) + arguments += $" --commonjs \"{options.CommonJS}\""; + + foreach (var knownHelper in options.KnownHelpers) + { + arguments += $" --known \"{knownHelper}\""; + } + + if (options.KnownHelpersOnly) + arguments += " --knownOnly"; + + if (options.ForcePartial || _partial) + arguments += " --partial"; + + if (options.NoBOM) + arguments += " --bom"; + + if ((options.SourceMap || config.SourceMap) && !string.IsNullOrWhiteSpace(_mapPath)) + arguments += $" --map \"{_mapPath}\""; + + if (!string.IsNullOrEmpty(options.TemplateNameSpace)) + arguments += $" --namespace \"{options.TemplateNameSpace}\""; + + if (!string.IsNullOrEmpty(options.Root)) + arguments += $" --root \"{options.Root}\""; + + if (!string.IsNullOrEmpty(options.Name)) + arguments += $" --name \"{options.Name}\""; + else if (!string.IsNullOrEmpty(_name)) + arguments += $" --name \"{_name}\""; + + if (!string.IsNullOrEmpty(_extension)) + arguments += $" --extension \"{_extension}\""; + + return arguments; + } + } +} diff --git a/src/WebCompiler/Compile/HandlebarsOptions.cs b/src/WebCompiler/Compile/HandlebarsOptions.cs new file mode 100644 index 00000000..e678fe01 --- /dev/null +++ b/src/WebCompiler/Compile/HandlebarsOptions.cs @@ -0,0 +1,124 @@ +using Newtonsoft.Json; +using System.Linq; + +namespace WebCompiler +{ + /// + /// Give all options for the Handlebars compiler + /// + public class HandlebarsOptions : BaseOptions + { + private const string trueStr = "true"; + + /// Creates a new instance of the class. + public HandlebarsOptions() + { } + + /// + /// Load the settings from the config object + /// + protected override void LoadSettings(Config config) + { + base.LoadSettings(config); + + var name = GetValue(config, "name"); + if (name != null) + Name = name; + + var @namespace = GetValue(config, "namespace"); + if (@namespace != null) + TemplateNameSpace = @namespace; + + var root = GetValue(config, "root"); + if (root != null) + Root = root; + + var commonjs = GetValue(config, "commonjs"); + if (commonjs != null) + CommonJS = commonjs; + + var amd = GetValue(config, "amd"); + if (amd != null) + AMD = amd.ToLowerInvariant() == trueStr; + + var forcePartial = GetValue(config, "forcePartial"); + if (forcePartial != null) + ForcePartial = forcePartial.ToLowerInvariant() == trueStr; + + var noBOM = GetValue(config, "noBOM"); + if (noBOM != null) + NoBOM = noBOM.ToLowerInvariant() == trueStr; + + var knownHelpersOnly = GetValue(config, "knownHelpersOnly"); + if (knownHelpersOnly != null) + KnownHelpersOnly = knownHelpersOnly.ToLowerInvariant() == trueStr; + + var knownHelpers = GetValue(config, "knownHelpers"); + if (knownHelpers != null) + KnownHelpers = knownHelpers.Split(',').Where(s => !string.IsNullOrWhiteSpace(s)).Select(s => s.Trim()).ToArray(); + } + + /// + /// The file name should match the compiler name + /// + protected override string CompilerFileName + { + get { return "hbs"; } + } + + /// + /// Template root. Base value that will be stripped from template names. + /// + [JsonProperty("root")] + public string Root { get; set; } = ""; + + /// + /// Removes the BOM (Byte Order Mark) from the beginning of the templates. + /// + [JsonProperty("noBOM")] + public bool NoBOM { get; set; } = false; + + /// + /// Name of passed string templates. + /// + [JsonProperty("name")] + public string Name { get; set; } = ""; + + /// + /// Template namespace + /// + [JsonProperty("namespace")] + public string TemplateNameSpace { get; set; } = ""; + + /// + /// Compile with known helpers only + /// + [JsonProperty("knownHelpersOnly")] + public bool KnownHelpersOnly { get; set; } = false; + + + /// + /// Forcing a partial template compilation + /// + [JsonProperty("forcePartial")] + public bool ForcePartial { get; set; } = false; + + /// + /// List of known helpers for a more optimized output + /// + [JsonProperty("knownHelpers")] + public string[] KnownHelpers { get; set; } = new string[0]; + + /// + /// Path to the Handlebars module to export CommonJS style + /// + [JsonProperty("commonjs")] + public string CommonJS { get; set; } = ""; + + /// + /// Exports amd style (require.js), this option has priority to commonjs. + /// + [JsonProperty("amd")] + public bool AMD { get; set; } = false; + } +} diff --git a/src/WebCompiler/Config/ConfigHandler.cs b/src/WebCompiler/Config/ConfigHandler.cs index 260f06af..5b827bde 100644 --- a/src/WebCompiler/Config/ConfigHandler.cs +++ b/src/WebCompiler/Config/ConfigHandler.cs @@ -67,6 +67,7 @@ public void CreateDefaultsFile(string fileName) stylus = new StylusOptions(), babel = new BabelOptions(), coffeescript = new IcedCoffeeScriptOptions(), + handlebars = new HandlebarsOptions(), }, minifiers = new { diff --git a/src/WebCompiler/Dependencies/DependencyService.cs b/src/WebCompiler/Dependencies/DependencyService.cs index 8dbd2061..6b3e9813 100644 --- a/src/WebCompiler/Dependencies/DependencyService.cs +++ b/src/WebCompiler/Dependencies/DependencyService.cs @@ -79,6 +79,10 @@ private static DependencyType GetDependencyType(string sourceFile) case ".ICED": return DependencyType.None; + case ".HBS": + case ".HANDLEBARS": + return DependencyType.None; + case ".JS": case ".JSX": case ".ES6": diff --git a/src/WebCompiler/WebCompiler.csproj b/src/WebCompiler/WebCompiler.csproj index 859bdf69..1b8ef9fa 100644 --- a/src/WebCompiler/WebCompiler.csproj +++ b/src/WebCompiler/WebCompiler.csproj @@ -67,6 +67,8 @@ + + diff --git a/src/WebCompilerTest/Compile/CompileServiceTest.cs b/src/WebCompilerTest/Compile/CompileServiceTest.cs index f597e815..47514b98 100644 --- a/src/WebCompilerTest/Compile/CompileServiceTest.cs +++ b/src/WebCompilerTest/Compile/CompileServiceTest.cs @@ -27,6 +27,16 @@ public void CoffeeIsSupported() Assert.IsTrue(result); } + [TestMethod, TestCategory("CompileService")] + public void HandleBarsIsSupported() + { + var result = CompilerService.IsSupported(".HANDLEBARS"); + Assert.IsTrue(result); + + result = CompilerService.IsSupported(".hbs"); + Assert.IsTrue(result); + } + [TestMethod, TestCategory("CompileService")] public void LowerCaseSupportedExtensionAlsoWorks() { diff --git a/src/WebCompilerTest/Compile/HandleBarsTest.cs b/src/WebCompilerTest/Compile/HandleBarsTest.cs new file mode 100644 index 00000000..6cd19b50 --- /dev/null +++ b/src/WebCompilerTest/Compile/HandleBarsTest.cs @@ -0,0 +1,68 @@ +using System.IO; +using System.Linq; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using WebCompiler; + +namespace WebCompilerTest +{ + [TestClass] + public class HandleBarsTest + { + private ConfigFileProcessor _processor; + + [TestInitialize] + public void Setup() + { + _processor = new ConfigFileProcessor(); + } + + [TestCleanup] + public void Cleanup() + { + File.Delete("../../artifacts/handlebars/test.js"); + File.Delete("../../artifacts/handlebars/test.min.js"); + File.Delete("../../artifacts/handlebars/test.js.map"); + File.Delete("../../artifacts/handlebars/error.js"); + File.Delete("../../artifacts/handlebars/error.min.js"); + File.Delete("../../artifacts/handlebars/error.js.map"); + File.Delete("../../artifacts/handlebars/_partial.js"); + File.Delete("../../artifacts/handlebars/_partial.min.js"); + File.Delete("../../artifacts/handlebars/_partial.js.map"); + } + + [TestMethod, TestCategory("HandleBars")] + public void CompileHandleBars() + { + var result = _processor.Process("../../artifacts/handlebarsconfig.json"); + FileInfo js = new FileInfo("../../artifacts/handlebars/test.js"); + FileInfo min = new FileInfo("../../artifacts/handlebars/test.min.js"); + FileInfo map = new FileInfo("../../artifacts/handlebars/test.js.map"); + Assert.IsTrue(js.Exists, "Output file doesn't exist"); + Assert.IsFalse(min.Exists, "Min file exists"); + Assert.IsTrue(map.Exists, "Map file doesn't exist"); + Assert.IsTrue(js.Length > 5); + Assert.IsTrue(map.Length > 5); + } + + [TestMethod, TestCategory("HandleBars")] + public void CompileHandleBarsPartial() + { + var result = _processor.Process("../../artifacts/handlebarsconfigPartial.json"); + FileInfo js = new FileInfo("../../artifacts/handlebars/_partial.js"); + FileInfo min = new FileInfo("../../artifacts/handlebars/_partial.min.js"); + Assert.IsTrue(js.Exists, "Output file doesn't exist"); + Assert.IsTrue(min.Exists, "Min file doesn't exists"); + Assert.IsTrue(js.Length > 5); + Assert.IsTrue(File.ReadAllText(js.FullName).Contains("Handlebars.partials['partial'] = template("), "Name of partial template is invalid"); + } + + [TestMethod, TestCategory("HandleBars")] + public void CompileHandleBarsWithError() + { + var result = _processor.Process("../../artifacts/handlebarsconfigError.json"); + var error = result.First().Errors[0]; + Assert.AreEqual(2, error.LineNumber); + Assert.AreEqual("Parse error", error.Message); + } + } +} diff --git a/src/WebCompilerTest/WebCompilerTest.csproj b/src/WebCompilerTest/WebCompilerTest.csproj index cc8f2d6c..b363a144 100644 --- a/src/WebCompilerTest/WebCompilerTest.csproj +++ b/src/WebCompilerTest/WebCompilerTest.csproj @@ -55,6 +55,7 @@ + @@ -73,7 +74,13 @@ + + + + + + diff --git a/src/WebCompilerTest/artifacts/handlebars/_partial.hbs b/src/WebCompilerTest/artifacts/handlebars/_partial.hbs new file mode 100644 index 00000000..116ab728 --- /dev/null +++ b/src/WebCompilerTest/artifacts/handlebars/_partial.hbs @@ -0,0 +1 @@ +

{{Header}}

\ No newline at end of file diff --git a/src/WebCompilerTest/artifacts/handlebars/error.hbs b/src/WebCompilerTest/artifacts/handlebars/error.hbs new file mode 100644 index 00000000..86bb460e --- /dev/null +++ b/src/WebCompilerTest/artifacts/handlebars/error.hbs @@ -0,0 +1,2 @@ +

{{Header}}

+
{{{Description}}
\ No newline at end of file diff --git a/src/WebCompilerTest/artifacts/handlebars/test.hbs b/src/WebCompilerTest/artifacts/handlebars/test.hbs new file mode 100644 index 00000000..de1e351b --- /dev/null +++ b/src/WebCompilerTest/artifacts/handlebars/test.hbs @@ -0,0 +1,12 @@ + + + + + {{Title}} + + +
+ {{> partial}} +
+ + diff --git a/src/WebCompilerTest/artifacts/handlebarsconfig.json b/src/WebCompilerTest/artifacts/handlebarsconfig.json new file mode 100644 index 00000000..7ae2fdfe --- /dev/null +++ b/src/WebCompilerTest/artifacts/handlebarsconfig.json @@ -0,0 +1,13 @@ +[ + { + "outputFile": "handlebars/test.js", + "inputFile": "handlebars/test.hbs", + "includeInProject": true, + "options": { + "sourceMap": true + }, + "minify": { + "enabled": false + } + } +] \ No newline at end of file diff --git a/src/WebCompilerTest/artifacts/handlebarsconfigError.json b/src/WebCompilerTest/artifacts/handlebarsconfigError.json new file mode 100644 index 00000000..8fef2de4 --- /dev/null +++ b/src/WebCompilerTest/artifacts/handlebarsconfigError.json @@ -0,0 +1,8 @@ +[ + { + "outputFile": "handlebars/error.js", + "inputFile": "handlebars/error.hbs", + "includeInProject": true, + "minify": { } + } +] \ No newline at end of file diff --git a/src/WebCompilerTest/artifacts/handlebarsconfigPartial.json b/src/WebCompilerTest/artifacts/handlebarsconfigPartial.json new file mode 100644 index 00000000..8131b9fc --- /dev/null +++ b/src/WebCompilerTest/artifacts/handlebarsconfigPartial.json @@ -0,0 +1,13 @@ +[ + { + "outputFile": "handlebars/_partial.js", + "inputFile": "handlebars/_partial.hbs", + "includeInProject": true, + "options": { + "sourceMap": false + }, + "minify": { + "enabled": true + } + } +] \ No newline at end of file diff --git a/src/WebCompilerVsix/Commands/CreateConfig.cs b/src/WebCompilerVsix/Commands/CreateConfig.cs index 157538be..b01b632f 100644 --- a/src/WebCompilerVsix/Commands/CreateConfig.cs +++ b/src/WebCompilerVsix/Commands/CreateConfig.cs @@ -166,7 +166,7 @@ private static string GetOutputFileName(string inputFile) string extension = Path.GetExtension(inputFile).ToLowerInvariant(); string ext = ".css"; - if (extension == ".coffee" || extension == ".iced" || extension == ".litcoffee" || extension == ".jsx" || extension == ".es6") + if (extension == ".coffee" || extension == ".iced" || extension == ".litcoffee" || extension == ".jsx" || extension == ".es6" || extension == ".hbs" || extension == ".handlebars") ext = ".js"; if (extension == ".js") diff --git a/src/WebCompilerVsix/ContentType/HBSContentTypeDefinition.cs b/src/WebCompilerVsix/ContentType/HBSContentTypeDefinition.cs new file mode 100644 index 00000000..7ff1e83c --- /dev/null +++ b/src/WebCompilerVsix/ContentType/HBSContentTypeDefinition.cs @@ -0,0 +1,26 @@ +using System.ComponentModel.Composition; +using Microsoft.VisualStudio.Utilities; + +namespace WebCompilerVsix +{ + /// + /// Exports the HandleBars content type and file extension (.hbs) + /// + public class HBSContentTypeDefinition + { + public const string HBSContentType = "HandleBars"; + + /// + /// Exports the HandleBars content type + /// + [Export(typeof(ContentTypeDefinition))] + [Name(HBSContentType)] + [BaseDefinition("code")] + public ContentTypeDefinition IHandleBarsContentType { get; set; } + + [Export(typeof(FileExtensionToContentTypeDefinition))] + [ContentType(HBSContentType)] + [FileExtension(".hbs")] + public FileExtensionToContentTypeDefinition HandleBarsFileExtension { get; set; } + } +} diff --git a/src/WebCompilerVsix/ContentType/HandlebarsContentTypeDefinition.cs b/src/WebCompilerVsix/ContentType/HandlebarsContentTypeDefinition.cs new file mode 100644 index 00000000..aa76efec --- /dev/null +++ b/src/WebCompilerVsix/ContentType/HandlebarsContentTypeDefinition.cs @@ -0,0 +1,26 @@ +using System.ComponentModel.Composition; +using Microsoft.VisualStudio.Utilities; + +namespace WebCompilerVsix +{ + /// + /// Exports the HandleBars content type and file extension (.handlebars) + /// + public class HandlebarsContentTypeDefinition + { + public const string HandleBarsContentType = "HandleBars"; + + /// + /// Exports the HandleBars content type + /// + [Export(typeof(ContentTypeDefinition))] + [Name(HandleBarsContentType)] + [BaseDefinition("code")] + public ContentTypeDefinition IHandleBarsContentType { get; set; } + + [Export(typeof(FileExtensionToContentTypeDefinition))] + [ContentType(HandleBarsContentType)] + [FileExtension(".handlebars")] + public FileExtensionToContentTypeDefinition HandleBarsFileExtension { get; set; } + } +} diff --git a/src/WebCompilerVsix/FileListeners/SourceFileCreationListener.cs b/src/WebCompilerVsix/FileListeners/SourceFileCreationListener.cs index 8d1be6a5..f4aafb5c 100644 --- a/src/WebCompilerVsix/FileListeners/SourceFileCreationListener.cs +++ b/src/WebCompilerVsix/FileListeners/SourceFileCreationListener.cs @@ -18,6 +18,8 @@ namespace WebCompilerVsix.Listeners [ContentType("jsx")] [ContentType("javascript")] [ContentType(SassContentTypeDefinition.SassContentType)] + [ContentType(HandlebarsContentTypeDefinition.HandleBarsContentType)] + [ContentType(HBSContentTypeDefinition.HBSContentType)] [TextViewRole(PredefinedTextViewRoles.Document)] class SourceFileCreationListener : IVsTextViewCreationListener { diff --git a/src/WebCompilerVsix/JSON/compilerconfig-schema.json b/src/WebCompilerVsix/JSON/compilerconfig-schema.json index 7b42f8e6..fa667291 100644 --- a/src/WebCompilerVsix/JSON/compilerconfig-schema.json +++ b/src/WebCompilerVsix/JSON/compilerconfig-schema.json @@ -19,6 +19,7 @@ } }, + "sassOptions": { "properties": { "inputFile": { @@ -85,6 +86,20 @@ } } }, + + "handlebarsOptions": { + "properties": { + "inputFile": { + "pattern": "\\.(hbs|handlebars)$" + }, + "options": { + "$ref": "compilerdefaults-schema.json#/definitions/handlebars" + }, + "minify": { + "$ref": "compilerdefaults-schema.json#/definitions/javascriptMinify" + } + } + }, "config": { "required": [ "outputFile", "inputFile" ], @@ -123,7 +138,8 @@ { "$ref": "#/definitions/stylusOptions" }, { "$ref": "#/definitions/coffeeScriptOptions" }, { "$ref": "#/definitions/icedCoffeeScriptOptions" }, - { "$ref": "#/definitions/babelOptions" } + { "$ref": "#/definitions/babelOptions" }, + { "$ref": "#/definitions/handlebarsOptions" } ] } }, diff --git a/src/WebCompilerVsix/JSON/compilerdefaults-schema.json b/src/WebCompilerVsix/JSON/compilerdefaults-schema.json index 1972ca40..b9d6bd95 100644 --- a/src/WebCompilerVsix/JSON/compilerdefaults-schema.json +++ b/src/WebCompilerVsix/JSON/compilerdefaults-schema.json @@ -152,6 +152,51 @@ } } }, + + "handlebars": { + "description": "Specify options for the compiler.", + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "noBOM": { + "description": "Removes the BOM (Byte Order Mark) from the beginning of the templates.", + "type": "boolean", + "default": false + }, + "namespace": { + "description": "Template namespace", + "type": "string", + "default": "" + }, + "root": { + "description": "Template root. Base value that will be stripped from template names.", + "type": "string", + "default": "" + }, + "knownHelpers": { + "description": "List of known helpers for a more optimized output (comma separated)", + "type": "string", + "default": "" + }, + "knownHelpersOnly": { + "description": "Compile with known helpers only", + "type": "boolean", + "default": false + }, + "commonjs": { + "description": "Path to the Handlebars module to export CommonJS style", + "type": "string", + "default": "" + }, + "amd": { + "description": "Exports amd style (require.js), this option has priority to commonjs.", + "type": "boolean", + "default": false + } + } + }, "baseMinify": { "type": "object", @@ -233,7 +278,8 @@ "less": { "$ref": "#/definitions/less" }, "sass": { "$ref": "#/definitions/sass" }, "stylus": { "$ref": "#/definitions/stylus" }, - "coffeescript": { "$ref": "#/definitions/coffeeScript" } + "coffeescript": { "$ref": "#/definitions/coffeeScript" }, + "handlebars": { "$ref": "#/definitions/handlebars" } } }, "minifiers": { diff --git a/src/WebCompilerVsix/TaskRunner/WebCompilerTaskRunner.cs b/src/WebCompilerVsix/TaskRunner/WebCompilerTaskRunner.cs index d21850c2..5e86be20 100644 --- a/src/WebCompilerVsix/TaskRunner/WebCompilerTaskRunner.cs +++ b/src/WebCompilerVsix/TaskRunner/WebCompilerTaskRunner.cs @@ -106,6 +106,9 @@ private string GetFriendlyName(string extension) case ".COFFEE": case ".LITCOFFEE": return "CoffeeScript"; + case ".HBS": + case ".HANDLEBARS": + return "HandleBars"; case ".ICED": return "Iced CoffeeScript"; } diff --git a/src/WebCompilerVsix/WebCompilerPackage.cs b/src/WebCompilerVsix/WebCompilerPackage.cs index d5c34804..7f85e86b 100644 --- a/src/WebCompilerVsix/WebCompilerPackage.cs +++ b/src/WebCompilerVsix/WebCompilerPackage.cs @@ -20,7 +20,7 @@ namespace WebCompilerVsix [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "pkgdef, VS and vsixmanifest are valid VS terms")] public sealed class WebCompilerPackage : Package { - public const string Version = "1.4.166"; + public const string Version = "1.4.167"; public static DTE2 _dte; public static Package Package; private SolutionEvents _solutionEvents; diff --git a/src/WebCompilerVsix/WebCompilerVsix.csproj b/src/WebCompilerVsix/WebCompilerVsix.csproj index 6974565e..d0c16701 100644 --- a/src/WebCompilerVsix/WebCompilerVsix.csproj +++ b/src/WebCompilerVsix/WebCompilerVsix.csproj @@ -61,6 +61,8 @@ + + diff --git a/src/WebCompilerVsix/source.extension.vsixmanifest b/src/WebCompilerVsix/source.extension.vsixmanifest index 5f929245..38fddb26 100644 --- a/src/WebCompilerVsix/source.extension.vsixmanifest +++ b/src/WebCompilerVsix/source.extension.vsixmanifest @@ -1,27 +1,27 @@  - - - Web Compiler - The easiest and most powerful way to compile LESS, Scss, Stylus, JSX and CoffeeScript files directly within Visual Studio or through MSBuild. - https://github.com/madskristensen/WebCompiler - Resources\LICENSE - https://github.com/madskristensen/WebCompiler/blob/master/CHANGELOG.md - Resources\icon.png - Resources\preview.png - Compile, LESS, Sass, Scss, CoffeeScript, JavaScript, JSX, ES6, Stylus - - - - - - - - - - - - - - + + + Web Compiler + The easiest and most powerful way to compile LESS, Scss, Stylus, JSX, CoffeeScript and Handlebars files directly within Visual Studio or through MSBuild. + https://github.com/madskristensen/WebCompiler + Resources\LICENSE + https://github.com/madskristensen/WebCompiler/blob/master/CHANGELOG.md + Resources\icon.png + Resources\preview.png + Compile, LESS, Sass, Scss, CoffeeScript, JavaScript, JSX, ES6, Stylus, Handlebars + + + + + + + + + + + + + +