diff --git a/.eslintrc.js b/.eslintrc.js index d240473c..16e187ce 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -22,7 +22,7 @@ module.exports = { "templateStrings": true }, "rules": { - // overrides eslint:recommended defaults + // overrides eslint:recommended defaults "no-sparse-arrays": "off", "no-func-assign": "off", "no-console": "warn", diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 09079851..a0dd4a4a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -96,4 +96,4 @@ After this point the handlebars site needs to be updated to point to the new ver [generator-release]: https://github.com/walmartlabs/generator-release [pull-request]: https://github.com/wycats/handlebars.js/pull/new/master [issue]: https://github.com/wycats/handlebars.js/issues/new -[jsfiddle]: https://jsfiddle.net/9D88g/113/ +[jsfiddle]: https://jsfiddle.net/9D88g/180/ diff --git a/bench/templates/complex.js b/bench/templates/complex.js index feba874d..3e5e26c4 100644 --- a/bench/templates/complex.js +++ b/bench/templates/complex.js @@ -5,7 +5,7 @@ module.exports = { header: function() { return 'Colors'; }, - hasItems: true, // To make things fairer in mustache land due to no `{{if}}` construct on arrays + hasItems: true, // To make things fairer in mustache land due to no `{{if}}` construct on arrays items: [ {name: 'red', current: true, url: '#Red'}, {name: 'green', current: false, url: '#Green'}, diff --git a/components/bower.json b/components/bower.json index 0bf954a4..7a28ba7b 100644 --- a/components/bower.json +++ b/components/bower.json @@ -1,6 +1,6 @@ { "name": "handlebars", - "version": "4.0.10", + "version": "4.0.11", "main": "handlebars.js", "license": "MIT", "dependencies": {} diff --git a/components/handlebars.js.nuspec b/components/handlebars.js.nuspec index 9b735a97..f84690c2 100644 --- a/components/handlebars.js.nuspec +++ b/components/handlebars.js.nuspec @@ -2,7 +2,7 @@ handlebars.js - 4.0.10 + 4.0.11 handlebars.js Authors https://github.com/wycats/handlebars.js/blob/master/LICENSE https://github.com/wycats/handlebars.js/ diff --git a/lib/handlebars/base.js b/lib/handlebars/base.js index d0ad1331..f1a39575 100644 --- a/lib/handlebars/base.js +++ b/lib/handlebars/base.js @@ -4,7 +4,7 @@ import {registerDefaultHelpers} from './helpers'; import {registerDefaultDecorators} from './decorators'; import logger from './logger'; -export const VERSION = '4.0.10'; +export const VERSION = '4.0.11'; export const COMPILER_REVISION = 7; export const REVISION_CHANGES = { diff --git a/lib/handlebars/compiler/code-gen.js b/lib/handlebars/compiler/code-gen.js index 5ec052f7..43c0481b 100644 --- a/lib/handlebars/compiler/code-gen.js +++ b/lib/handlebars/compiler/code-gen.js @@ -118,7 +118,7 @@ CodeGen.prototype = { .replace(/"/g, '\\"') .replace(/\n/g, '\\n') .replace(/\r/g, '\\r') - .replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4 + .replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4 .replace(/\u2029/g, '\\u2029') + '"'; }, diff --git a/lib/handlebars/compiler/helpers.js b/lib/handlebars/compiler/helpers.js index 3c1a38fa..432df877 100644 --- a/lib/handlebars/compiler/helpers.js +++ b/lib/handlebars/compiler/helpers.js @@ -38,7 +38,7 @@ export function stripFlags(open, close) { } export function stripComment(comment) { - return comment.replace(/^\{\{~?\!-?-?/, '') + return comment.replace(/^\{\{~?!-?-?/, '') .replace(/-?-?~?\}\}$/, ''); } diff --git a/lib/handlebars/compiler/javascript-compiler.js b/lib/handlebars/compiler/javascript-compiler.js index 25ddd137..551ddbb2 100644 --- a/lib/handlebars/compiler/javascript-compiler.js +++ b/lib/handlebars/compiler/javascript-compiler.js @@ -131,7 +131,7 @@ JavaScriptCompiler.prototype = { }; if (this.decorators) { - ret.main_d = this.decorators; // eslint-disable-line camelcase + ret.main_d = this.decorators; // eslint-disable-line camelcase ret.useDecorators = true; } @@ -207,7 +207,7 @@ JavaScriptCompiler.prototype = { // aliases will not be used, but this case is already being run on the client and // we aren't concern about minimizing the template size. let aliasCount = 0; - for (let alias in this.aliases) { // eslint-disable-line guard-for-in + for (let alias in this.aliases) { // eslint-disable-line guard-for-in let node = this.aliases[alias]; if (this.aliases.hasOwnProperty(alias) && node.children && node.referenceCount > 1) { @@ -699,12 +699,12 @@ JavaScriptCompiler.prototype = { for (let i = 0, l = children.length; i < l; i++) { child = children[i]; - compiler = new this.compiler(); // eslint-disable-line new-cap + compiler = new this.compiler(); // eslint-disable-line new-cap let existing = this.matchExistingProgram(child); if (existing == null) { - this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children + this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children let index = this.context.programs.length; child.index = index; child.name = 'program' + index; diff --git a/lib/handlebars/logger.js b/lib/handlebars/logger.js index 1ab0051f..1e916a99 100644 --- a/lib/handlebars/logger.js +++ b/lib/handlebars/logger.js @@ -24,10 +24,10 @@ let logger = { if (typeof console !== 'undefined' && logger.lookupLevel(logger.level) <= level) { let method = logger.methodMap[level]; - if (!console[method]) { // eslint-disable-line no-console + if (!console[method]) { // eslint-disable-line no-console method = 'log'; } - console[method](...message); // eslint-disable-line no-console + console[method](...message); // eslint-disable-line no-console } } }; diff --git a/lib/precompiler.js b/lib/precompiler.js index 64608f1e..ab3eb201 100644 --- a/lib/precompiler.js +++ b/lib/precompiler.js @@ -60,7 +60,7 @@ function loadStrings(opts, callback) { function loadFiles(opts, callback) { // Build file extension pattern - let extension = (opts.extension || 'handlebars').replace(/[\\^$*+?.():=!|{}\-\[\]]/g, function(arg) { return '\\' + arg; }); + let extension = (opts.extension || 'handlebars').replace(/[\\^$*+?.():=!|{}\-[\]]/g, function(arg) { return '\\' + arg; }); extension = new RegExp('\\.' + extension + '$'); let ret = [], @@ -290,8 +290,9 @@ function minify(output, sourceMapFile) { return output; } return require('uglify-js').minify(output.code, { - fromString: true, - outSourceMap: sourceMapFile, - inSourceMap: JSON.parse(output.map) + sourceMap: { + content: output.map, + url: sourceMapFile + } }); } diff --git a/package.json b/package.json index b9073bed..e856da46 100644 --- a/package.json +++ b/package.json @@ -21,12 +21,12 @@ "node": ">=0.4.7" }, "dependencies": { - "async": "^1.4.0", - "source-map": "^0.4.4", + "async": "^2.5.0", + "source-map": "^0.6.1", "yargs": "^3.32.0" }, "optionalDependencies": { - "uglify-js": "^2.6" + "uglify-js": "^3.1.4" }, "devDependencies": { "aws-sdk": "^2.1.49", @@ -44,7 +44,7 @@ "grunt-contrib-copy": "0.x", "grunt-contrib-uglify": "0.x", "grunt-contrib-watch": "0.x", - "grunt-eslint": "19.0.x", + "grunt-eslint": "^20.1.0", "grunt-saucelabs": "8.x", "grunt-webpack": "^1.0.8", "istanbul": "kpdecker/istanbul", diff --git a/release-notes.md b/release-notes.md index 139dd5a4..29b896b2 100644 --- a/release-notes.md +++ b/release-notes.md @@ -2,7 +2,17 @@ ## Development -[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.10...master) +[Commits](https://github.com/wycats/handlebars.js/compare/v4.0.11...master) + +## v4.0.11 - October 17th, 2017 +- [#1391](https://github.com/wycats/handlebars.js/issues/1391) - `uglify-js` is unconditionally imported, but only listed as optional dependency ([@Turbo87](https://api.github.com/users/Turbo87)) +- [#1233](https://github.com/wycats/handlebars.js/issues/1233) - Unable to build under windows - error at test:bin task ([@blikblum](https://api.github.com/users/blikblum)) +- Update (C) year in the LICENSE file - 21386b6 + +Compatibility notes: +- This is a bugfix release. There are no breaking change and no new features. + +[Commits](https://github.com/nknapp/handlebars.js/compare/v4.0.10...v4.0.11) ## v4.0.10 - May 21st, 2017 - Fix regression in 4.0.9: Replace "Object.assign" (not support in IE) by "util/extend" - 0e953d1 diff --git a/spec/ast.js b/spec/ast.js index 8f346d88..e43438be 100644 --- a/spec/ast.js +++ b/spec/ast.js @@ -59,6 +59,7 @@ describe('ast', function() { equals(node.loc.end.column, lastColumn); } + /* eslint-disable no-multi-spaces */ ast = Handlebars.parse( 'line 1 {{line1Token}}\n' // 1 + ' line 2 {{line2token}}\n' // 2 @@ -71,6 +72,7 @@ describe('ast', function() { + '{{else inverse}}\n' // 9 + '{{else}}\n' // 10 + '{{/open}}'); // 11 + /* eslint-enable no-multi-spaces */ body = ast.body; it('gets ContentNode line numbers', function() { diff --git a/spec/helpers.js b/spec/helpers.js index 94e503f1..15bc2f12 100644 --- a/spec/helpers.js +++ b/spec/helpers.js @@ -113,7 +113,7 @@ describe('helpers', function() { { 'name': 'Yehuda', 'id': 2 } ]}; - shouldCompileTo(source, [data, {link: link}], ''); + shouldCompileTo(source, [data, {link: link}], ''); }); it('block helper for undefined value', function() { diff --git a/spec/parser.js b/spec/parser.js index 4527d19c..856031c3 100644 --- a/spec/parser.js +++ b/spec/parser.js @@ -51,7 +51,7 @@ describe('parser', function() { }); it('parses mustaches with string parameters', function() { - equals(astFor('{{foo bar \"baz\" }}'), '{{ PATH:foo [PATH:bar, "baz"] }}\n'); + equals(astFor('{{foo bar "baz" }}'), '{{ PATH:foo [PATH:bar, "baz"] }}\n'); }); it('parses mustaches with NUMBER parameters', function() { @@ -87,10 +87,10 @@ describe('parser', function() { equals(astFor("{{foo bat='bam'}}"), '{{ PATH:foo [] HASH{bat="bam"} }}\n'); - equals(astFor('{{foo omg bar=baz bat=\"bam\"}}'), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam"} }}\n'); - equals(astFor('{{foo omg bar=baz bat=\"bam\" baz=1}}'), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=NUMBER{1}} }}\n'); - equals(astFor('{{foo omg bar=baz bat=\"bam\" baz=true}}'), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=BOOLEAN{true}} }}\n'); - equals(astFor('{{foo omg bar=baz bat=\"bam\" baz=false}}'), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=BOOLEAN{false}} }}\n'); + equals(astFor('{{foo omg bar=baz bat="bam"}}'), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam"} }}\n'); + equals(astFor('{{foo omg bar=baz bat="bam" baz=1}}'), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=NUMBER{1}} }}\n'); + equals(astFor('{{foo omg bar=baz bat="bam" baz=true}}'), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=BOOLEAN{true}} }}\n'); + equals(astFor('{{foo omg bar=baz bat="bam" baz=false}}'), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=BOOLEAN{false}} }}\n'); }); it('parses contents followed by a mustache', function() { @@ -136,7 +136,7 @@ describe('parser', function() { }); it('parses a multi-line comment', function() { - equals(astFor('{{!\nthis is a multi-line comment\n}}'), "{{! \'\nthis is a multi-line comment\n\' }}\n"); + equals(astFor('{{!\nthis is a multi-line comment\n}}'), "{{! '\nthis is a multi-line comment\n' }}\n"); }); it('parses an inverse section', function() { diff --git a/spec/spec.js b/spec/spec.js index 221d32ec..805609d0 100644 --- a/spec/spec.js +++ b/spec/spec.js @@ -25,8 +25,8 @@ describe('spec', function() { // We nest the entire response from partials, not just the literals || (name === 'partials.json' && test.name === 'Standalone Indentation') - || (/\{\{\=/).test(test.template) - || _.any(test.partials, function(partial) { return (/\{\{\=/).test(partial); })) { + || (/\{\{=/).test(test.template) + || _.any(test.partials, function(partial) { return (/\{\{=/).test(partial); })) { it.skip(name + ' - ' + test.name); return; } diff --git a/spec/tokenizer.js b/spec/tokenizer.js index 428804e0..1a361b75 100644 --- a/spec/tokenizer.js +++ b/spec/tokenizer.js @@ -282,13 +282,13 @@ describe('Tokenizer', function() { }); it('tokenizes mustaches with String params as "OPEN ID ID STRING CLOSE"', function() { - var result = tokenize('{{ foo bar \"baz\" }}'); + var result = tokenize('{{ foo bar "baz" }}'); shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'STRING', 'CLOSE']); shouldBeToken(result[3], 'STRING', 'baz'); }); it('tokenizes mustaches with String params using single quotes as "OPEN ID ID STRING CLOSE"', function() { - var result = tokenize("{{ foo bar \'baz\' }}"); + var result = tokenize("{{ foo bar 'baz' }}"); shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'STRING', 'CLOSE']); shouldBeToken(result[3], 'STRING', 'baz'); }); @@ -365,13 +365,13 @@ describe('Tokenizer', function() { result = tokenize('{{ foo bar\n baz=bat }}'); shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'ID', 'CLOSE']); - result = tokenize('{{ foo bar baz=\"bat\" }}'); + result = tokenize('{{ foo bar baz="bat" }}'); shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'STRING', 'CLOSE']); - result = tokenize('{{ foo bar baz=\"bat\" bam=wot }}'); + result = tokenize('{{ foo bar baz="bat" bam=wot }}'); shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'STRING', 'ID', 'EQUALS', 'ID', 'CLOSE']); - result = tokenize('{{foo omg bar=baz bat=\"bam\"}}'); + result = tokenize('{{foo omg bar=baz bat="bam"}}'); shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'ID', 'ID', 'EQUALS', 'STRING', 'CLOSE']); shouldBeToken(result[2], 'ID', 'omg'); });