From 294c6335be1c3ea54cdc50330bb0ca632df9b6aa Mon Sep 17 00:00:00 2001 From: Patrick Steele-Idem Date: Mon, 11 Jan 2016 13:15:26 -0700 Subject: [PATCH] Marko v3: Better handling of escaping for custom tags input --- compiler/CodeGenerator.js | 6 ++- compiler/CompileError.js | 2 +- compiler/HtmlJsParser.js | 4 +- compiler/ast/CustomTag.js | 10 ++++- compiler/ast/FunctionCall.js | 2 +- compiler/ast/HtmlAttribute.js | 39 ++----------------- compiler/ast/HtmlElement.js | 8 ++-- compiler/util/removeEscapeFunctions.js | 17 ++++++++ .../simple-handlers/expected.html | 1 - .../simple-handlers/template.marko | 13 ------- .../autotest-pending/simple-handlers/test.js | 3 -- .../expected.html | 1 + .../template.marko | 13 +++++++ .../custom-tag-data-placeholders/test.js | 1 + .../fixtures/taglib/test-hello/marko-tag.json | 3 +- test/fixtures/taglib/test-hello/renderer.js | 7 ++++ 16 files changed, 66 insertions(+), 64 deletions(-) create mode 100644 compiler/util/removeEscapeFunctions.js delete mode 100644 test/fixtures/render/autotest-pending/simple-handlers/expected.html delete mode 100644 test/fixtures/render/autotest-pending/simple-handlers/template.marko delete mode 100644 test/fixtures/render/autotest-pending/simple-handlers/test.js create mode 100644 test/fixtures/render/autotest/custom-tag-data-placeholders/expected.html create mode 100644 test/fixtures/render/autotest/custom-tag-data-placeholders/template.marko create mode 100644 test/fixtures/render/autotest/custom-tag-data-placeholders/test.js diff --git a/compiler/CodeGenerator.js b/compiler/CodeGenerator.js index 6aaaac1ec..840e9012a 100644 --- a/compiler/CodeGenerator.js +++ b/compiler/CodeGenerator.js @@ -288,7 +288,11 @@ class Generator { let startPos = this._code.length; - this.generateCode(node); + if (Array.isArray(node) || (node instanceof Container)) { + this.generateStatements(node); + } else { + this.generateCode(node); + } if (this._code.length === startPos) { // No code was generated. Remove any code that was previously added diff --git a/compiler/CompileError.js b/compiler/CompileError.js index a609c3d73..b722b8128 100644 --- a/compiler/CompileError.js +++ b/compiler/CompileError.js @@ -38,7 +38,7 @@ class CompileError { pos = ''; } var str = pos + this.message; - if (this.node) { + if (pos == null && this.node) { str += ' (' + this.node.toString() + ')'; } return str; diff --git a/compiler/HtmlJsParser.js b/compiler/HtmlJsParser.js index 7a20b444b..3ff331d40 100644 --- a/compiler/HtmlJsParser.js +++ b/compiler/HtmlJsParser.js @@ -20,9 +20,9 @@ class HtmlJsParser { onattributeplaceholder(event) { // placeholder within attribute if (event.escape) { - event.expression = 'escapeXml(' + event.expression + ')'; + event.expression = '$escapeXml(' + event.expression + ')'; } else { - event.expression = 'noEscapeXml(' + event.expression + ')'; + event.expression = '$noEscapeXml(' + event.expression + ')'; } }, diff --git a/compiler/ast/CustomTag.js b/compiler/ast/CustomTag.js index 10d7c34e9..6b40679ba 100644 --- a/compiler/ast/CustomTag.js +++ b/compiler/ast/CustomTag.js @@ -3,6 +3,7 @@ var HtmlElement = require('./HtmlElement'); var path = require('path'); var removeDashes = require('../util/removeDashes'); +var removeEscapeFunctions = require('../util/removeEscapeFunctions'); function removeExt(filename) { var ext = path.extname(filename); @@ -20,6 +21,11 @@ function buildInputProps(node, context) { var attrName = attr.name; var attrDef = attr.def || context.taglibLookup.getAttribute(node.tagName, attr.name); + var attrValue = removeEscapeFunctions(attr.value); + + if (!attrDef) { + return; // Skip over attributes that are not supported + } var propName; var parentPropName; @@ -52,9 +58,9 @@ function buildInputProps(node, context) { if (parentPropName) { let parent = inputProps[parentPropName] = (inputProps[parentPropName] = {}); - parent[propName] = attr.value; + parent[propName] = attrValue; } else { - inputProps[propName] = attr.value; + inputProps[propName] = attrValue; } }); diff --git a/compiler/ast/FunctionCall.js b/compiler/ast/FunctionCall.js index 8153155e8..5724d2a47 100644 --- a/compiler/ast/FunctionCall.js +++ b/compiler/ast/FunctionCall.js @@ -9,7 +9,7 @@ class FunctionCall extends Node { this.callee = def.callee; ok(this.callee, '"callee" is required'); - + this.args = def.args; if (this.args && !Array.isArray(this.args)) { diff --git a/compiler/ast/HtmlAttribute.js b/compiler/ast/HtmlAttribute.js index 5d45ccfd1..ad692cac9 100644 --- a/compiler/ast/HtmlAttribute.js +++ b/compiler/ast/HtmlAttribute.js @@ -3,8 +3,8 @@ var Node = require('./Node'); var Literal = require('./Literal'); var ok = require('assert').ok; var escapeXmlAttr = require('raptor-util/escapeXml').attr; -var compiler = require('../'); var parseExpression = require('../util/parseExpression'); +var removeEscapeFunctions = require('../util/removeEscapeFunctions'); function isStringLiteral(node) { return node.type === 'Literal' && typeof node.value === 'string'; @@ -13,18 +13,12 @@ function isStringLiteral(node) { function isNoEscapeXml(node) { return node.type === 'FunctionCall' && node.callee.type === 'Identifier' && - node.callee.name === 'noEscapeXml'; -} - -function isEscapeXml(node) { - return node.type === 'FunctionCall' && - node.callee.type === 'Identifier' && - node.callee.name === 'escapeXml'; + node.callee.name === '$noEscapeXml'; } function isStringExpression(node) { return node.type === 'FunctionCall' && node.callee.type === 'Identifier' && - (node.callee.name === 'noEscapeXml' || node.callee.name === 'escapeXml'); + (node.callee.name === '$noEscapeXml' || node.callee.name === '$escapeXml'); } function flattenAttrConcats(node) { @@ -61,33 +55,6 @@ function flattenAttrConcats(node) { return final.concats; } -// function handleEscaping(node) { -// -// function handleEscapingHelper(node, escaping) { -// if (node.type === 'Literal') { -// } else if (isEscapeXml(node)) { -// return handleEscapingHelper(node.arguments[0], true); -// } else if (isNoEscapeXml(node)) { -// return handleEscapingHelper(node.arguments[0], escaping false); -// } -// } -// -// var finalNode = handleEscapingHelper(node, true /* default to escaping */); -// return finalNode; -// } - -function removeEscapeFunctions(node) { - var walker = compiler.createWalker({ - enter: function(node, parent) { - if (isNoEscapeXml(node) || isEscapeXml(node)) { - return node.args[0]; - } - } - }); - - return walker.walk(node); -} - function generateCodeForExpressionAttr(name, value, codegen) { var flattenedConcats = flattenAttrConcats(value); var hasLiteral = false; diff --git a/compiler/ast/HtmlElement.js b/compiler/ast/HtmlElement.js index 83ab85a68..71d65dd5a 100644 --- a/compiler/ast/HtmlElement.js +++ b/compiler/ast/HtmlElement.js @@ -157,9 +157,11 @@ class HtmlElement extends Node { if (openTagOnly) { codegen.generateCode(startTag); } else { - codegen.generateCode(startTag); - codegen.generateCode(body); - codegen.generateCode(endTag); + return [ + startTag, + body, + endTag + ]; } } } diff --git a/compiler/util/removeEscapeFunctions.js b/compiler/util/removeEscapeFunctions.js new file mode 100644 index 000000000..3a57df804 --- /dev/null +++ b/compiler/util/removeEscapeFunctions.js @@ -0,0 +1,17 @@ +var compiler = require('../'); + +function removeEscapeFunctions(node) { + var walker = compiler.createWalker({ + enter: function(node, parent) { + if (node.type === 'FunctionCall' && + node.callee.type === 'Identifier' && + (node.callee.name === '$noEscapeXml' || node.callee.name === '$escapeXml')) { + return node.args[0]; + } + } + }); + + return walker.walk(node); +} + +module.exports = removeEscapeFunctions; \ No newline at end of file diff --git a/test/fixtures/render/autotest-pending/simple-handlers/expected.html b/test/fixtures/render/autotest-pending/simple-handlers/expected.html deleted file mode 100644 index 7e8e1fe33..000000000 --- a/test/fixtures/render/autotest-pending/simple-handlers/expected.html +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/test/fixtures/render/autotest-pending/simple-handlers/template.marko b/test/fixtures/render/autotest-pending/simple-handlers/template.marko deleted file mode 100644 index 9ca4c51bf..000000000 --- a/test/fixtures/render/autotest-pending/simple-handlers/template.marko +++ /dev/null @@ -1,13 +0,0 @@ - - - \ No newline at end of file diff --git a/test/fixtures/render/autotest-pending/simple-handlers/test.js b/test/fixtures/render/autotest-pending/simple-handlers/test.js deleted file mode 100644 index d14b4238d..000000000 --- a/test/fixtures/render/autotest-pending/simple-handlers/test.js +++ /dev/null @@ -1,3 +0,0 @@ -exports.templateData = { - "dynamic": "universe" -}; diff --git a/test/fixtures/render/autotest/custom-tag-data-placeholders/expected.html b/test/fixtures/render/autotest/custom-tag-data-placeholders/expected.html new file mode 100644 index 000000000..85a47efa4 --- /dev/null +++ b/test/fixtures/render/autotest/custom-tag-data-placeholders/expected.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/fixtures/render/autotest/custom-tag-data-placeholders/template.marko b/test/fixtures/render/autotest/custom-tag-data-placeholders/template.marko new file mode 100644 index 000000000..5cb683b2d --- /dev/null +++ b/test/fixtures/render/autotest/custom-tag-data-placeholders/template.marko @@ -0,0 +1,13 @@ + + +
    +
  • + +
  • +
  • + +
  • +
  • + +
  • +
\ No newline at end of file diff --git a/test/fixtures/render/autotest/custom-tag-data-placeholders/test.js b/test/fixtures/render/autotest/custom-tag-data-placeholders/test.js new file mode 100644 index 000000000..c4013b344 --- /dev/null +++ b/test/fixtures/render/autotest/custom-tag-data-placeholders/test.js @@ -0,0 +1 @@ +exports.templateData = {}; diff --git a/test/fixtures/taglib/test-hello/marko-tag.json b/test/fixtures/taglib/test-hello/marko-tag.json index 4b18cf6bc..e83d0748c 100644 --- a/test/fixtures/taglib/test-hello/marko-tag.json +++ b/test/fixtures/taglib/test-hello/marko-tag.json @@ -1,4 +1,5 @@ { "renderer": "./renderer.js", - "@name": "string" + "@name": "string", + "@adult": "boolean" } \ No newline at end of file diff --git a/test/fixtures/taglib/test-hello/renderer.js b/test/fixtures/taglib/test-hello/renderer.js index 85e30308a..eff3f3789 100644 --- a/test/fixtures/taglib/test-hello/renderer.js +++ b/test/fixtures/taglib/test-hello/renderer.js @@ -1,7 +1,14 @@ exports.render = function(input, out) { out.write('Hello ' + input.name + '!'); + if (input.adult === true) { + out.write(' (adult)'); + } else if (input.adult === false) { + out.write(' (child)'); + } + if (input.renderBody) { out.write(' BODY: '); input.renderBody(out); } + }; \ No newline at end of file