From 446ffadf1a66e122673f627b4e757c2fcde397b2 Mon Sep 17 00:00:00 2001 From: Ilya Verbitskiy Date: Sat, 19 Nov 2011 13:32:09 +0100 Subject: [PATCH 1/6] Fixed issue with uninitialized escapers in Haml.render function. Fixed issue with new line on Windows (use \r\n instead of \n when running on Windows). Fixed unit tests. Added posibility to run only some tests from the test kit. Use util module instead of deprecated sys module. --- lib/haml.js | 27 +++++++++++-------- test/test.js | 74 ++++++++++++++++++++++++++++++++++------------------ 2 files changed, 65 insertions(+), 36 deletions(-) diff --git a/lib/haml.js b/lib/haml.js index a497912..439d472 100755 --- a/lib/haml.js +++ b/lib/haml.js @@ -3,6 +3,9 @@ var Haml; (function () { var matchers, self_close_tags, embedder, forceXML, escaperName, escapeHtmlByDefault; + + var NEW_LINE_STR = process.platform.match(/^win/i) ? "\\r\\n" : "\\n"; + var NEW_LINE = process.platform.match(/^win/i) ? "\r\n" : "\n"; function html_escape(text) { return (text + ""). @@ -334,7 +337,7 @@ var Haml; process: function () { this.contents.unshift(this.matches[2]); - return '""'; + return '""'; } }, @@ -403,7 +406,7 @@ var Haml; line = ""; break; } - return JSON.stringify(line + "\n"); + return JSON.stringify(line + NEW_LINE); } }, @@ -421,10 +424,10 @@ var Haml; name: "script", regexp: /^(\s*):(?:java)?script\s*$/, process: function () { - return parse_interpol('\n\n"); + return parse_interpol(NEW_LINE + '" + NEW_LINE); } }, @@ -433,9 +436,9 @@ var Haml; name: "css", regexp: /^(\s*):css\s*$/, process: function () { - return JSON.stringify('"); + return JSON.stringify('"); } } @@ -447,7 +450,7 @@ var Haml; // If lines is a string, turn it into an array if (typeof lines === 'string') { - lines = lines.trim().replace(/\n\r|\r/g, '\n').split('\n'); + lines = lines.trim().replace(/\r\n|\r/g, '\n').split('\n'); } lines.forEach(function(line) { @@ -557,7 +560,7 @@ var Haml; buffer = []; } } - js.replace(/\n\r|\r/g, '\n').split('\n').forEach(function (line) { + js.replace(/\r\n|\r/g, '\n').split('\n').forEach(function (line) { part = line.match(/^(\".*\")(\s*\+\s*)?$/); if (!part) { flush(); @@ -579,6 +582,8 @@ var Haml; function render(text, options) { options = options || {}; + escaperName = options.customEscape || "html_escape" + text = text || ""; var js = compile(text, options); if (options.optimize) { diff --git a/test/test.js b/test/test.js index adcc36f..55f39ab 100644 --- a/test/test.js +++ b/test/test.js @@ -1,49 +1,59 @@ var fs = require('fs'); var assert = require('assert'); -var sys = require('sys'); +var util = require('util'); var Haml = require("../lib/haml"); - - function compare(haml_file, haml, expected, scope, options){ options || (options = {}); try { - sys.puts(haml_file + " Begun") + util.puts(haml_file + " Begun") var js = Haml.compile(haml); var js_opt = Haml.optimize(js); var jsFn = Haml(haml, options); var actual = jsFn.call(scope.context, scope.locals); assert.equal(actual, expected); - sys.puts(haml_file + " Passed") + util.puts(haml_file + " Passed") actual = Haml.render(haml, {context:scope.context, locals:scope.locals}) assert.equal(actual, expected); - sys.puts(haml_file + " Haml.render Passed") + util.puts(haml_file + " Haml.render Passed") } catch (e) { var message = e.name; if (e.message) { message += ": " + e.message; } - sys.error(haml_file + " FAILED") - sys.error(message); - sys.error("\nJS:\n\n" + js); - sys.error("\nOptimized JS:\n\n" + js_opt); - sys.error("\nJS fn:\n\n"+jsFn.toString()); - sys.error("\nStack:\n\n"+e.stack); + util.error(haml_file + " FAILED") + util.error(message); + util.error("\nJS:\n\n" + js); + util.error("\nOptimized JS:\n\n" + js_opt); + util.error("\nJS fn:\n\n"+jsFn.toString()); + util.error("\nStack:\n\n"+e.stack); try{ - sys.error("\nActual["+actual.length+"]:\n\n" + actual); - sys.error("\nExpected["+expected.length+"]:\n\n" + expected); + util.error("\nActual["+actual.length+"]:\n\n" + actual); + util.error("\nExpected["+expected.length+"]:\n\n" + expected); }catch(e2){} process.exit(); } } +// Load command line arguments to run a specific test +var test_param = []; + +if (process.argv.length > 2) { + for (var i = 2; i < process.argv.length; ++i) { + test_param.push(process.argv[i].toLowerCase()); + } +} fs.readdir('.', function (err, files) { files.forEach(function (haml_file) { + if (test_param.length != 0 && test_param.indexOf(haml_file.toLowerCase()) === -1) { + return; + } + var m = haml_file.match(/^(.*)\.haml/), base; if (!m) { @@ -71,25 +81,35 @@ fs.readdir('.', function (err, files) { }); (function(){ - var hamlSrc = fs.readFileSync("alt_attribs.haml", "utf8"); + var haml_file = "alt_attribs.haml"; + + if (test_param.length != 0 && test_param.indexOf(haml_file) === -1) { + return; + } + + var hamlSrc = fs.readFileSync(haml_file, "utf8"); var includeEscape = Haml(hamlSrc).toString(); var customEscape = Haml(hamlSrc, {customEscape:"$esc"}).toString(); try{ assert.ok(customEscape.length < includeEscape.length); }catch(e){ - sys.error(e.stack); - sys.error(customEscape); + util.error(e.stack); + util.error(customEscape); process.exit(); } })(); (function(){ + if (test_param.length != 0 && test_param.indexOf("custom_escape.haml") === -1) { + return; + } + var hamlSrc = fs.readFileSync("./other/custom_escape.haml", "utf8"); var expected = fs.readFileSync("./other/custom_escape.html", "utf8"); var scope = eval("(" + fs.readFileSync("escaping.js") + ")"); - sys.puts("custom_escape" + " Begun") + util.puts("custom_escape" + " Begun") var jsFn = Haml(hamlSrc, {customEscape:"$esc"}); this.$esc = function(){ @@ -100,21 +120,25 @@ fs.readdir('.', function (err, files) { try{ assert.equal(actual, expected); }catch(e){ - sys.error("\nActual["+actual.length+"]:\n\n" + actual); - sys.error("\nExpected["+expected.length+"]:\n\n" + expected); + util.error("\nActual["+actual.length+"]:\n\n" + actual); + util.error("\nExpected["+expected.length+"]:\n\n" + expected); process.exit(); } - sys.puts("custom_escape" + " Passed") + util.puts("custom_escape" + " Passed") })(); (function(){ + if (test_param.length != 0 && test_param.indexOf("escape_by_default.haml") === -1) { + return; + } + var hamlSrc = fs.readFileSync("./other/escape_by_default.haml", "utf8"); var expected = fs.readFileSync("./other/escape_by_default.html", "utf8"); var scope = {}; - sys.puts("escape_by_default" + " Begun") + util.puts("escape_by_default" + " Begun") var js = Haml.compile(hamlSrc); var jsFn = Haml(hamlSrc, {escapeHtmlByDefault:true}); @@ -127,11 +151,11 @@ fs.readdir('.', function (err, files) { try{ assert.equal(actual, expected); }catch(e){ - sys.error("\nActual["+actual.length+"]:\n\n" + actual); - sys.error("\nExpected["+expected.length+"]:\n\n" + expected); + util.error("\nActual["+actual.length+"]:\n\n" + actual); + util.error("\nExpected["+expected.length+"]:\n\n" + expected); process.exit(); } - sys.puts("escape_by_default" + " Passed") + util.puts("escape_by_default" + " Passed") })(); From 7453889f866447cf03a79237df3504505093c363 Mon Sep 17 00:00:00 2001 From: Ilya Verbitskiy Date: Fri, 9 Dec 2011 16:32:54 +0100 Subject: [PATCH 2/6] Added web-browser support. --- lib/haml.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/haml.js b/lib/haml.js index 439d472..6c17c08 100755 --- a/lib/haml.js +++ b/lib/haml.js @@ -3,9 +3,15 @@ var Haml; (function () { var matchers, self_close_tags, embedder, forceXML, escaperName, escapeHtmlByDefault; - - var NEW_LINE_STR = process.platform.match(/^win/i) ? "\\r\\n" : "\\n"; - var NEW_LINE = process.platform.match(/^win/i) ? "\r\n" : "\n"; + + if (process && process.platform) { + var NEW_LINE_STR = process.platform.match(/^win/i) ? "\\r\\n" : "\\n"; + var NEW_LINE = process.platform.match(/^win/i) ? "\r\n" : "\n"; + } + else { + var NEW_LINE_STR = "\\n"; + var NEW_LINE = "\n"; + } function html_escape(text) { return (text + ""). From 8c502101fdb51df1c9186d4996a06e60e3636deb Mon Sep 17 00:00:00 2001 From: "iverbitskiy@yahoo.com" Date: Sat, 24 Dec 2011 08:43:05 +0100 Subject: [PATCH 3/6] Issue #55. Fixed inline JavaScript under :each break --- test/js_after_each.haml | 4 ++++ test/js_after_each.html | 1 + test/js_after_each.js | 5 +++++ 3 files changed, 10 insertions(+) create mode 100644 test/js_after_each.haml create mode 100644 test/js_after_each.html create mode 100644 test/js_after_each.js diff --git a/test/js_after_each.haml b/test/js_after_each.haml new file mode 100644 index 0000000..2c1d59a --- /dev/null +++ b/test/js_after_each.haml @@ -0,0 +1,4 @@ +:each question in questions + - var temp = 'hello' + %div&= question + %div&= temp \ No newline at end of file diff --git a/test/js_after_each.html b/test/js_after_each.html new file mode 100644 index 0000000..ee9846a --- /dev/null +++ b/test/js_after_each.html @@ -0,0 +1 @@ +
question 1
hello
question 2
hello
question 3
hello
\ No newline at end of file diff --git a/test/js_after_each.js b/test/js_after_each.js new file mode 100644 index 0000000..6de834a --- /dev/null +++ b/test/js_after_each.js @@ -0,0 +1,5 @@ +{ + locals: { + questions: ["question 1", "question 2", "question 3"] + } +} \ No newline at end of file From 349ede189ca0171108a8546ce0b7aa27b0b20529 Mon Sep 17 00:00:00 2001 From: "iverbitskiy@yahoo.com" Date: Sat, 24 Dec 2011 08:44:06 +0100 Subject: [PATCH 4/6] Issue #55. Fixed inline JavaScript under :each break --- lib/haml.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/haml.js b/lib/haml.js index 6c17c08..4720dc3 100755 --- a/lib/haml.js +++ b/lib/haml.js @@ -308,8 +308,8 @@ var Haml; 'var ' + rvar + ' = [], ' + ivar + ', ' + vvar + '; ' + 'for (' + ivar + ' in ' + avar + ') { ' + 'if (' + avar + '.hasOwnProperty(' + ivar + ')) { ' + - vvar + ' = ' + avar + '[' + ivar + ']; ' + - rvar + '.push(\n' + (this.render_contents() || "''") + '\n); ' + + vvar + ' = ' + avar + '[' + ivar + ']; _$output = ' + (this.render_contents() || "''") + ";" + + rvar + '.push(_$output); ' + '} } return ' + rvar + '.join(""); }).call(this)'; } }, From 69f28e5e3fcbcaada0937044c69ea50ee210f1b4 Mon Sep 17 00:00:00 2001 From: Ilya Verbitskiy Date: Fri, 13 Jan 2012 01:34:50 +0100 Subject: [PATCH 5/6] Issue #56 Parse eol-style comments in a raw JavaScript code --- test/js_eol_comment.haml | 31 +++++++++++++++++++++++++++++++ test/js_eol_comment.html | 1 + test/js_eol_comment.js | 5 +++++ 3 files changed, 37 insertions(+) create mode 100644 test/js_eol_comment.haml create mode 100644 test/js_eol_comment.html create mode 100644 test/js_eol_comment.js diff --git a/test/js_eol_comment.haml b/test/js_eol_comment.haml new file mode 100644 index 0000000..e71762b --- /dev/null +++ b/test/js_eol_comment.haml @@ -0,0 +1,31 @@ +:each user in users + - var testComment = "hello " + user // sample eol-comment + %div&= testComment + +:each user in users + - var testComment = 'hello ' + user // sample eol-comment + %div&= testComment + +:each user in users + - var testComment = "hello // ok " + user + %div&= testComment + +:each user in users + - var testComment = "hello // ok " + user // sample eol-comment + %div&= testComment + +:each user in users + - var testComment = 'hello // ok ' + user + %div&= testComment + +:each user in users + - var testComment = 'hello // ok ' + user // sample eol-comment + %div&= testComment + +:each user in users + - var testComment = "hel'lo " + user // sample eol-comment + %div&= testComment + +:each user in users + - var testComment = 'hel"lo ' + user // sample eol-comment + %div&= testComment \ No newline at end of file diff --git a/test/js_eol_comment.html b/test/js_eol_comment.html new file mode 100644 index 0000000..79f9ad2 --- /dev/null +++ b/test/js_eol_comment.html @@ -0,0 +1 @@ +
hello Alex
hello Alex
hello // ok Alex
hello // ok Alex
hello // ok Alex
hello // ok Alex
hel'lo Alex
hel"lo Alex
\ No newline at end of file diff --git a/test/js_eol_comment.js b/test/js_eol_comment.js new file mode 100644 index 0000000..2d3068f --- /dev/null +++ b/test/js_eol_comment.js @@ -0,0 +1,5 @@ +{ + locals: { + users: ["Alex"] + } +} \ No newline at end of file From 75808185e5be986d2dc666eb480d3a7b67f909b0 Mon Sep 17 00:00:00 2001 From: Ilya Verbitskiy Date: Fri, 13 Jan 2012 01:36:39 +0100 Subject: [PATCH 6/6] Issue #56 Parse eol-style comments in a raw JavaScript code --- lib/haml.js | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/lib/haml.js b/lib/haml.js index 4720dc3..d5fa3fd 100755 --- a/lib/haml.js +++ b/lib/haml.js @@ -352,7 +352,54 @@ var Haml; name: "rawjs", regexp: /^(\s*)-\s*(.*)\s*$/i, process: function () { + function removeComments(js) { + var inString = null, + chars = js.length, + i, chr, chrNext, + result = []; + + COMMENT_SEARCH: + for (i = 0; i < chars; i++) { + chr = js.charAt(i); + if (inString) { + // Check if it is the end of a string + if (chr === inString) { + inString = null; + } + } + else { + switch (chr) { + // Check if it is a beginning of a string + case "'": + case '"': + inString = chr; + break; + + // Check a comment + case "/": + if (i < chars - 1) { + chrNext = js.charAt(i + 1); + if (chrNext == "/") { + break COMMENT_SEARCH; + } + } + + break; + } + } + + result.push(chr); + } + + js = result.join(""); + return js; + } + this.contents.unshift(this.matches[2]); + for (var i in this.contents) { + this.contents[i] = removeComments(this.contents[i]); + } + return '"";' + this.contents.join("\n")+"; _$output = _$output "; } },