diff --git a/compiler/CodeGenerator.js b/compiler/CodeGenerator.js index c101eed8d..75f8d6a49 100644 --- a/compiler/CodeGenerator.js +++ b/compiler/CodeGenerator.js @@ -91,6 +91,7 @@ class Generator { throw new Error('Root node is not of type "TemplateRoot". Actual ' + JSON.stringify(templateRoot)); } templateRoot.addStaticVar(name, value); + return name; } generateCode(node, options) { diff --git a/compiler/ast/ArrayContainer.js b/compiler/ast/ArrayContainer.js index 105ef7850..26f9d2134 100644 --- a/compiler/ast/ArrayContainer.js +++ b/compiler/ast/ArrayContainer.js @@ -30,7 +30,7 @@ class ArrayContainer extends Container { // } forEach(callback, thisObj) { - var array = this.array; + var array = this.array.concat([]); for (var i=0; i'); } else { @@ -94,6 +104,14 @@ class HtmlElement extends Node { } } + addDynamicAttributes(expression) { + if (!this._dynamicAttributesExpressionArray) { + this._dynamicAttributesExpressionArray = []; + } + + this._dynamicAttributesExpressionArray.push(expression); + } + removeAttribute(name) { if (this._attributes) { this._attributes.removeAttribute(name); @@ -111,6 +129,14 @@ class HtmlElement extends Node { get attributes() { return this._attributes.all; } + + forEachAttribute(callback, thisObj) { + var attributes = this._attributes.all.concat([]); + + for (let i=0, len=attributes.length; i { + let attrName = attr.name; + var attrTransformerFunc = attributeTransformers[attrName]; + if (attrTransformerFunc) { + el.removeAttribute(attrName); - if (!attributeTransfomer) { - attributeTransfomer = new AttributeTransformer(compiler, el); - } - attributeTransfomer[attrName](attr, el); + if (!attributeTransfomer) { + attributeTransfomer = new AttributeTransformer(compiler, el); } + attributeTransfomer[attrName](attr, el); } - } + }); }; \ No newline at end of file diff --git a/test/autotest.js b/test/autotest.js index 553187ed4..fe126fab0 100644 --- a/test/autotest.js +++ b/test/autotest.js @@ -1,30 +1,47 @@ var fs = require('fs'); var enabledTest = process.env.TEST; var path = require('path'); - +var assert = require('assert'); function autoTest(name, dir, run, options) { var compareExtension = (options && options.compareExtension) || '.js'; + var isJSON = compareExtension === '.json'; + var actualPath = path.join(dir, 'actual' + compareExtension); var expectedPath = path.join(dir, 'expected' + compareExtension); var actual = run(dir); + var actualJSON = isJSON ? JSON.stringify(actual, null, 2) : null; - fs.writeFileSync(actualPath, actual, {encoding: 'utf8'}); + fs.writeFileSync( + actualPath, + isJSON ? actualJSON : actual, + {encoding: 'utf8'}); var expected; try { expected = fs.readFileSync(expectedPath, { encoding: 'utf8' }); } catch(e) { - expected = 'TBD'; + expected = isJSON ? '"TBD"' : 'TBD'; fs.writeFileSync(expectedPath, expected, {encoding: 'utf8'}); } - if (actual !== expected) { - throw new Error('Unexpected output for "' + name + '":\nEXPECTED (' + expectedPath + '):\n---------\n' + expected + - '\n---------\nACTUAL (' + actualPath + '):\n---------\n' + actual + '\n---------'); + var expectedJSON; + + if (isJSON) { + expectedJSON = expected; + expected = JSON.parse(expectedJSON); } + + assert.deepEqual( + (isJSON ? JSON.parse(actualJSON) : actual), + expected, + 'Unexpected output for "' + name + '":\nEXPECTED (' + expectedPath + '):\n---------\n' + + (isJSON ? expectedJSON : expected) + + '\n---------\nACTUAL (' + actualPath + '):\n---------\n' + + (isJSON ? actualJSON : actual) + + '\n---------'); } exports.scanDir = function(autoTestDir, run, options) { diff --git a/test/fixtures/compiler/autotest/simple/expected.js b/test/fixtures/compiler/autotest/simple/expected.js index 2fd9f9570..bea7c115c 100644 --- a/test/fixtures/compiler/autotest/simple/expected.js +++ b/test/fixtures/compiler/autotest/simple/expected.js @@ -1 +1,42 @@ -TBD \ No newline at end of file +function create(__helpers) { + var str = __helpers.s, + empty = __helpers.e, + notEmpty = __helpers.ne, + escapeXml = __helpers.x, + forEach = __helpers.f; + + return function render(data, out) { + out.w("Hello ! " + + escapeXml(data.name)); + + if (notEmpty(data.colors)) { + out.w(""); + } else { + out.w("
No colors!
"); + } + + if (notEmpty(data.colors)) { + out.w(""); + } else { + out.w("
No colors!
"); + } + }; +} + +(module.exports = require("marko").c(__filename)).c(create); diff --git a/test/fixtures/pretty-print/autotest/assignment/actual.json b/test/fixtures/pretty-print/autotest/assignment/actual.json new file mode 100644 index 000000000..471c8a635 --- /dev/null +++ b/test/fixtures/pretty-print/autotest/assignment/actual.json @@ -0,0 +1,16 @@ +{ + "type": "TemplateRoot", + "body": [ + { + "type": "Assignment", + "left": "a", + "right": "1" + } + ], + "staticVars": { + "str": "__helpers.s", + "empty": "__helpers.e", + "notEmpty": "__helpers.ne", + "escapeXml": "__helpers.x" + } +} \ No newline at end of file diff --git a/test/fixtures/pretty-print/autotest/assignment/expected.json b/test/fixtures/pretty-print/autotest/assignment/expected.json new file mode 100644 index 000000000..471c8a635 --- /dev/null +++ b/test/fixtures/pretty-print/autotest/assignment/expected.json @@ -0,0 +1,16 @@ +{ + "type": "TemplateRoot", + "body": [ + { + "type": "Assignment", + "left": "a", + "right": "1" + } + ], + "staticVars": { + "str": "__helpers.s", + "empty": "__helpers.e", + "notEmpty": "__helpers.ne", + "escapeXml": "__helpers.x" + } +} \ No newline at end of file diff --git a/test/fixtures/pretty-print/autotest/marko-template/expected.js b/test/fixtures/pretty-print/autotest/marko-template/actual.json similarity index 97% rename from test/fixtures/pretty-print/autotest/marko-template/expected.js rename to test/fixtures/pretty-print/autotest/marko-template/actual.json index 6fcd8750e..f9b10bb53 100644 --- a/test/fixtures/pretty-print/autotest/marko-template/expected.js +++ b/test/fixtures/pretty-print/autotest/marko-template/actual.json @@ -67,7 +67,7 @@ { "type": "HtmlElement", "tagName": "ul", - "attributes": [ + "_attributes": [ { "name": "class", "value": { @@ -92,7 +92,7 @@ { "type": "HtmlElement", "tagName": "li", - "attributes": [ + "_attributes": [ { "name": "class", "value": { diff --git a/test/fixtures/pretty-print/autotest/marko-template/expected.json b/test/fixtures/pretty-print/autotest/marko-template/expected.json new file mode 100644 index 000000000..f9b10bb53 --- /dev/null +++ b/test/fixtures/pretty-print/autotest/marko-template/expected.json @@ -0,0 +1,135 @@ +{ + "type": "TemplateRoot", + "body": [ + { + "type": "FunctionDeclaration", + "name": "create", + "params": [ + "__helpers" + ], + "body": [ + { + "type": "Vars", + "kind": "var", + "declarations": [ + { + "id": "str", + "init": "__helpers.s" + }, + { + "id": "empty", + "init": "__helpers.e" + }, + { + "id": "notEmpty", + "init": "__helpers.ne" + } + ] + }, + { + "type": "Return", + "argument": { + "type": "FunctionDeclaration", + "name": "render", + "params": [ + "data", + "out" + ], + "body": [ + { + "type": "TextOutput", + "argument": { + "type": "Literal", + "value": "Hello" + } + }, + { + "type": "HtmlOutput", + "argument": "data.name" + }, + { + "type": "TextOutput", + "argument": { + "type": "Literal", + "value": "!" + } + }, + { + "type": "If", + "test": { + "type": "FunctionCall", + "callee": "notEmpty", + "args": [ + "data.colors" + ] + }, + "body": [ + { + "type": "HtmlElement", + "tagName": "ul", + "_attributes": [ + { + "name": "class", + "value": { + "type": "Literal", + "value": "colors" + } + } + ], + "body": [ + { + "type": "FunctionCall", + "callee": "forEach", + "args": [ + "data.colors", + { + "type": "FunctionDeclaration", + "name": null, + "params": [ + "color" + ], + "body": [ + { + "type": "HtmlElement", + "tagName": "li", + "_attributes": [ + { + "name": "class", + "value": { + "type": "Literal", + "value": "color" + } + } + ], + "body": [ + { + "type": "TextOutput", + "argument": "color" + } + ], + "allowSelfClosing": false, + "startTagOnly": false + } + ] + } + ] + } + ], + "allowSelfClosing": false, + "startTagOnly": false + } + ] + } + ] + } + } + ] + } + ], + "staticVars": { + "str": "__helpers.s", + "empty": "__helpers.e", + "notEmpty": "__helpers.ne", + "escapeXml": "__helpers.x" + } +} \ No newline at end of file diff --git a/test/fixtures/render/autotest/attr-escape-xml/expected.html b/test/fixtures/render/autotest/attr-escape-xml/expected.html new file mode 100644 index 000000000..8606804a1 --- /dev/null +++ b/test/fixtures/render/autotest/attr-escape-xml/expected.html @@ -0,0 +1 @@ +
Hello World!
\ No newline at end of file diff --git a/test/fixtures/render/autotest/attr-escape-xml/template.marko b/test/fixtures/render/autotest/attr-escape-xml/template.marko new file mode 100644 index 000000000..c49ca8ffa --- /dev/null +++ b/test/fixtures/render/autotest/attr-escape-xml/template.marko @@ -0,0 +1,3 @@ +
+ Hello World! +
\ No newline at end of file diff --git a/test/fixtures/render/autotest/attr-escape-xml/test.js b/test/fixtures/render/autotest/attr-escape-xml/test.js new file mode 100644 index 000000000..c4013b344 --- /dev/null +++ b/test/fixtures/render/autotest/attr-escape-xml/test.js @@ -0,0 +1 @@ +exports.templateData = {}; diff --git a/test/fixtures/render/autotest/attrs/template.marko b/test/fixtures/render/autotest/attrs/template.marko index 3fdf3d3ec..4386a4800 100644 --- a/test/fixtures/render/autotest/attrs/template.marko +++ b/test/fixtures/render/autotest/attrs/template.marko @@ -1,5 +1,3 @@ - - -
+
Hello World!
\ No newline at end of file diff --git a/test/pretty-print-test.js b/test/pretty-print-test.js index ebceccc03..e63b8b0e1 100644 --- a/test/pretty-print-test.js +++ b/test/pretty-print-test.js @@ -12,9 +12,15 @@ var autotest = require('./autotest'); describe('compiler/pretty-print', function() { var autoTestDir = path.join(__dirname, 'fixtures/pretty-print/autotest'); - autotest.scanDir(autoTestDir, function run(dir) { - var getAST = require(path.join(dir, 'index.js')); - var ast = getAST(builder); - return JSON.stringify(ast, null, 2); - }); + autotest.scanDir( + autoTestDir, + function run(dir) { + var getAST = require(path.join(dir, 'index.js')); + var ast = getAST(builder); + return ast; + }, + { + deepEqual: true, + compareExtension: '.json' + }); }); \ No newline at end of file