Skip to content

Commit

Permalink
fix: regression with nullish values in partial string attribute values (
Browse files Browse the repository at this point in the history
  • Loading branch information
DylanPiercey committed Apr 3, 2020
1 parent f206862 commit a469e02
Show file tree
Hide file tree
Showing 23 changed files with 80 additions and 114 deletions.
4 changes: 0 additions & 4 deletions packages/marko/src/compiler/CodeGenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,6 @@ class CodeGenerator {
this.context.setMeta(key, value);
}

getEscapeXmlAttrVar() {
return this.context.getEscapeXmlAttrVar();
}

importModule(varName, path) {
return this.context.importModule(varName, path);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/marko/src/compiler/CompileContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ const helpers = {
},
escapeDoubleQuoteAttrValue: {
html: {
module: "marko/runtime/html/helpers/escape-xml",
module: "marko/runtime/html/helpers/escape-quotes",
method: "d"
}
},
Expand Down
1 change: 0 additions & 1 deletion packages/marko/src/compiler/ast/AttributePlaceholder.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ class AttributePlaceholder extends Node {
constructor(def) {
super("AttributePlaceholder");
this.value = def.value;
this.escape = def.escape;
}

generateCode(codegen) {
Expand Down
42 changes: 10 additions & 32 deletions packages/marko/src/compiler/ast/HtmlAttribute/html/generateCode.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
"use strict";

var attr = require("../../../../runtime/html/helpers/attr");
var escapeDoubleQuotes = require("../../../../runtime/html/helpers/escape-xml")
var escapeDoubleQuoteAttrValue = require("../../../../runtime/html/helpers/escape-quotes")
.d;

function isStringLiteral(node) {
return node.type === "Literal" && typeof node.value === "string";
}

function isNoEscapeXml(node) {
return node.type === "AttributePlaceholder" && node.escape === false;
}

function flattenAttrConcats(node) {
// return [node];

function flattenHelper(node) {
if (node.type === "BinaryExpression" && node.operator === "+") {
let left = flattenHelper(node.left);
Expand Down Expand Up @@ -45,7 +39,7 @@ function flattenAttrConcats(node) {
return final.concats;
}

function generateCodeForExpressionAttr(name, value, escape, codegen) {
function generateCodeForExpressionAttr(name, value, codegen) {
var flattenedConcats = flattenAttrConcats(value);

var hasLiteral = false;
Expand Down Expand Up @@ -75,19 +69,13 @@ function generateCodeForExpressionAttr(name, value, escape, codegen) {
addHtmlLiteral(" " + name + '="');
for (let i = 0; i < flattenedConcats.length; i++) {
var part = flattenedConcats[i];
if (isStringLiteral(part)) {
part.value = escapeDoubleQuotes(part.value);
} else if (part.type !== "Literal") {
if (isNoEscapeXml(part)) {
part = codegen.builder.functionCall(context.helper("str"), [part]);
} else {
if (escape !== false) {
part = builder.functionCall(
context.helper("escapeDoubleQuoteAttrValue"),
[part]
);
}
}
if (part.type === "Literal") {
part.value = escapeDoubleQuoteAttrValue(part.value);
} else {
part = builder.functionCall(
context.helper("escapeDoubleQuoteAttrValue"),
[part]
);
}
addHtml(part);
}
Expand All @@ -102,16 +90,7 @@ function generateCodeForExpressionAttr(name, value, escape, codegen) {
codegen.builder.functionCall(context.helper("styleAttr"), [value])
);
} else {
if (escape === false || isNoEscapeXml(value)) {
escape = false;
}

let attrArgs = [codegen.builder.literal(name), value];

if (escape === false) {
attrArgs.push(codegen.builder.literal(false));
}

addHtml(codegen.builder.functionCall(context.helper("attr"), attrArgs));
}
}
Expand All @@ -123,7 +102,6 @@ module.exports = function generateCode(node, codegen) {
let name = node.name;
let value = node.value;
let argument = node.argument;
let escape = node.escape !== false;
var builder = codegen.builder;

if (!name) {
Expand All @@ -142,7 +120,7 @@ module.exports = function generateCode(node, codegen) {
if (value.type === "TemplateLiteral") {
value.nonstandard = false;
}
return generateCodeForExpressionAttr(name, value, escape, codegen);
return generateCodeForExpressionAttr(name, value, codegen);
} else if (argument) {
return [
builder.htmlLiteral(" " + name + "("),
Expand Down
1 change: 0 additions & 1 deletion packages/marko/src/compiler/ast/HtmlAttribute/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ class HtmlAttribute extends Node {
this.name = def.name;
this.value = def.value;
this.rawValue = def.rawValue;
this.escape = def.escape;
this.spread = def.spread;

if (typeof this.value === "string") {
Expand Down
8 changes: 2 additions & 6 deletions packages/marko/src/compiler/ast/HtmlAttributeCollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,14 @@ class HtmlAttributeCollection {
return this.lookup[name];
}

setAttributeValue(name, value, escape) {
setAttributeValue(name, value) {
var attr = this.getAttribute(name);
if (attr) {
attr.value = value;
if (typeof escape === "boolean") {
attr.escape = escape;
}
} else {
this.addAttribute({
name: name,
value: value,
escape: escape
value: value
});
}
}
Expand Down
5 changes: 3 additions & 2 deletions packages/marko/src/compiler/ast/Text/html/generateCode.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use strict";

var escapeXml = require("../../../../runtime/html/helpers/escape-xml").x;
var escapeXmlOrNullish = require("../../../../runtime/html/helpers/escape-xml")
.x;
var Literal = require("../../Literal");

module.exports = function(node, codegen) {
Expand All @@ -21,7 +22,7 @@ module.exports = function(node, codegen) {
}

if (escape === true) {
argument.value = escapeXml(argument.value.toString());
argument.value = escapeXmlOrNullish(argument.value.toString());
}

htmlArray.push(argument);
Expand Down
8 changes: 5 additions & 3 deletions packages/marko/src/runtime/html/AsyncStream.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ var defaultDocument = typeof document != "undefined" && document;
var RenderResult = require("../RenderResult");
var attrsHelper = require("./helpers/attrs");
var markoAttr = require("./helpers/data-marko");
var escapeXml = require("./helpers/escape-xml").x;
var escapeXmlHelper = require("./helpers/escape-xml");
var escapeXmlOrNullish = escapeXmlHelper.x;
var escapeXmlString = escapeXmlHelper.___escapeXML;
var selfClosingTags = require("self-closing-tags");

var voidWriter = { write: function() {} };
Expand Down Expand Up @@ -553,12 +555,12 @@ var proto = (AsyncStream.prototype = {
},

text: function(str) {
this.write(escapeXml(str));
this.write(escapeXmlOrNullish(str));
},

___beginFragment: function(key, component, preserve) {
if (preserve) {
this.write("<!--F#" + escapeXml(key) + "-->");
this.write("<!--F#" + escapeXmlString(key) + "-->");
}
if (this._elStack) {
this._elStack.push(preserve);
Expand Down
3 changes: 2 additions & 1 deletion packages/marko/src/runtime/html/StringWriter.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use strict";

var escapeDoubleQuotes = require("./helpers/escape-xml").d;
var escapeDoubleQuotes = require("./helpers/escape-quotes")
.___escapeDoubleQuotes;

function StringWriter() {
this._content = "";
Expand Down
6 changes: 3 additions & 3 deletions packages/marko/src/runtime/html/helpers/attr.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"use strict";

var escape = require("./escape-xml");
var escapeDoubleQuotes = escape.d;
var escapeSingleQuotes = escape.s;
var escapeQuoteHelpers = require("./escape-quotes");
var escapeDoubleQuotes = escapeQuoteHelpers.___escapeDoubleQuotes;
var escapeSingleQuotes = escapeQuoteHelpers.___escapeSingleQuotes;
var complain = "MARKO_DEBUG" && require("complain");

module.exports = function attr(name, value) {
Expand Down
6 changes: 3 additions & 3 deletions packages/marko/src/runtime/html/helpers/data-marko.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"use strict";

var escapeXml = require("./escape-xml");
var escapeSingleQuotes = escapeXml.s;
var escapeDoubleQuotes = escapeXml.d;
var escapeQuoteHelpers = require("./escape-quotes");
var escapeSingleQuotes = escapeQuoteHelpers.___escapeSingleQuotes;
var escapeDoubleQuotes = escapeQuoteHelpers.___escapeDoubleQuotes;
var FLAG_WILL_RERENDER_IN_BROWSER = 1;
// var FLAG_HAS_BODY_EL = 2;
// var FLAG_HAS_HEAD_EL = 4;
Expand Down
35 changes: 35 additions & 0 deletions packages/marko/src/runtime/html/helpers/escape-quotes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"use strict";

exports.d = function(value) {
return escapeDoubleQuotes(value + "");
};

exports.___escapeDoubleQuotes = escapeDoubleQuotes;

exports.___escapeSingleQuotes = escapeSingleQuotes;

function escapeSingleQuotes(value) {
return escapeQuote(value, "'", "&#39;");
}

function escapeDoubleQuotes(value) {
return escapeQuote(value, '"', "&#34;");
}

function escapeQuote(str, quote, escaped) {
var result = "";
var lastPos = 0;

for (var i = 0, len = str.length; i < len; i++) {
if (str[i] === quote) {
result += str.slice(lastPos, i) + escaped;
lastPos = i + 1;
}
}

if (lastPos) {
return result + str.slice(lastPos);
}

return str;
}
32 changes: 4 additions & 28 deletions packages/marko/src/runtime/html/helpers/escape-xml.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
"use strict";

exports.d = function(value) {
return escapeQuote(value, '"', "&#34;");
};

exports.s = function(value) {
return escapeQuote(value, "'", "&#39;");
};

exports.x = function(value) {
module.exports.x = function(value) {
if (value == null) {
return "";
}
Expand All @@ -17,28 +9,12 @@ exports.x = function(value) {
return value.toHTML();
}

return escapeBody(value + "");
return escapeXML(value + "");
};

function escapeQuote(str, quote, escaped) {
var result = "";
var lastPos = 0;

for (var i = 0, len = str.length; i < len; i++) {
if (str[i] === quote) {
result += str.slice(lastPos, i) + escaped;
lastPos = i + 1;
}
}

if (lastPos) {
return result + str.slice(lastPos);
}

return str;
}
exports.___escapeXML = escapeXML;

function escapeBody(str) {
function escapeXML(str) {
var len = str.length;
var result = "";
var lastPos = 0;
Expand Down
2 changes: 1 addition & 1 deletion packages/marko/src/runtime/html/helpers/props-script.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use strict";

var escapeDoubleQuotes = require("./escape-xml").d;
var escapeDoubleQuotes = require("./escape-quotes").___escapeDoubleQuotes;
var escapeScript = require("./escape-script-placeholder");
var assignPropsFunction = `
function ap_(p) {
Expand Down

This file was deleted.

20 changes: 0 additions & 20 deletions packages/marko/test/codegen/fixtures/attr-no-escape/index.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
out.w("<div class=\"foo" +
className +
marko_escapeDoubleQuoteAttrValue(className) +
"\">Hello World</div>")
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ var marko_template = module.exports = require("marko/src/html").t(__filename),
marko_renderer = require("marko/src/runtime/components/renderer"),
marko_classAttr = require("marko/src/runtime/html/helpers/class-attr"),
marko_attr = require("marko/src/runtime/html/helpers/attr"),
helpers_escape_xml = require("marko/src/runtime/html/helpers/escape-xml"),
marko_escapeDoubleQuoteAttrValue = helpers_escape_xml.d;
helpers_escape_quotes = require("marko/src/runtime/html/helpers/escape-quotes"),
marko_escapeDoubleQuoteAttrValue = helpers_escape_quotes.d;

function render(input, out, __component, component, state) {
var data = input;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ var marko_template = module.exports = require("marko/src/html").t(__filename),
marko_renderer = require("marko/src/runtime/components/renderer"),
marko_classAttr = require("marko/src/runtime/html/helpers/class-attr"),
marko_attr = require("marko/src/runtime/html/helpers/attr"),
helpers_escape_xml = require("marko/src/runtime/html/helpers/escape-xml"),
marko_escapeDoubleQuoteAttrValue = helpers_escape_xml.d;
helpers_escape_quotes = require("marko/src/runtime/html/helpers/escape-quotes"),
marko_escapeDoubleQuoteAttrValue = helpers_escape_quotes.d;

function render(input, out, __component, component, state) {
var data = input;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div data-foo="anull"></div><div data-foo="bnull"></div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<div data-foo="a"+input.text/>
<div data-foo=`b${input.text}`/>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
exports.templateData = { text: null };
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<DIV data-foo="anull">
<DIV data-foo="bnull">

0 comments on commit a469e02

Please sign in to comment.