Skip to content

Commit

Permalink
identify static attributes correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
kbrsh committed May 19, 2019
1 parent 1b21a0f commit 9b4d608
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 88 deletions.
89 changes: 53 additions & 36 deletions packages/moon/dist/moon.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,23 +114,12 @@
"\n": "\\n",
"\r": "\\r"
};
/**
* Checks if a given character is a quote.
*
* @param {string} char
* @returns {boolean} True if the character is a quote
*/

function isQuote(_char) {
return _char === "\"" || _char === "'";
}
/**
* Escape text to make it usable in a JavaScript string literal.
*
* @param {string} text
*/


function escapeText(text) {
return text.replace(textRE, function (match) {
return escapeTextMap[match];
Expand All @@ -144,9 +133,22 @@


function scopeExpression(expression) {
return expression.replace(expressionRE, function (match, name) {
return name === undefined || name[0] === "$" || globals.indexOf(name) !== -1 ? match : "data." + name;
var isStatic = true;
var value = expression.replace(expressionRE, function (match, name) {
if (name === undefined || globals.indexOf(name) !== -1) {
// Return a static match if there are no dynamic names or if it is a
// global variable.
return match;
} else {
// Return a dynamic match if there is a dynamic name or a local.
isStatic = false;
return name[0] === "$" ? match : "data." + name;
}
});
return {
value: value,
isStatic: isStatic
};
}
/**
* Convert a token into a string, accounting for `<text/>` components.
Expand All @@ -163,18 +165,18 @@
// and doesn't need the quotes. If not, it was an expression and
// needs to be formatted with curly braces.

if (isQuote(content[0])) {
return content.slice(1, -1);
if (content.isStatic) {
return content.value.slice(1, -1);
} else {
return "{" + content + "}";
return "{" + content.value + "}";
}
} else {
var tag = "<" + token.value;
var attributes = token.attributes;

for (var attributeKey in attributes) {
var attributeValue = attributes[attributeKey];
tag += " " + attributeKey + "=" + (isQuote(attributeValue[0]) ? attributeValue : "{" + attributeValue + "}");
tag += " " + attributeKey + "=" + (attributeValue.isStatic ? attributeValue.value : "{" + attributeValue.value + "}");
}

if (token.closed) {
Expand Down Expand Up @@ -230,9 +232,9 @@
var tokens = [];

for (var i = 0; i < input.length;) {
var _char2 = input[i];
var _char = input[i];

if (_char2 === "<") {
if (_char === "<") {
var charNext = input[i + 1];

if ("development" === "development" && charNext === undefined) {
Expand Down Expand Up @@ -308,10 +310,18 @@
} else {
// Store the key/value pair using the matched value or
// expression.
attributes[attributeKey] = attributeExpression === undefined ? attributeValue === undefined ? "\"\"" : attributeValue : scopeExpression(attributeExpression); // Add a wrapper function for events.
if (attributeExpression === undefined) {
attributes[attributeKey] = {
value: attributeValue === undefined ? "\"\"" : attributeValue,
isStatic: true
};
} else {
attributes[attributeKey] = scopeExpression(attributeExpression);
} // Add a wrapper function for events.


if (attributeKey[0] === "@") {
attributes[attributeKey] = "function($event){" + attributes[attributeKey] + "}";
attributes[attributeKey].value = "function($event){" + attributes[attributeKey].value + "}";
}
}
} // Append an opening tag token with the name, attributes, and optional
Expand All @@ -325,18 +335,18 @@
closed: closeSlash === "/"
});
i += nameMatch.length;
} else if (_char2 === "{") {
} else if (_char === "{") {
// If a sequence of characters begins with "{", process it as an
// expression token.
var expression = ""; // Consume the input until the end of the expression.

for (i += 1; i < input.length; i++) {
var _char3 = input[i];
var _char2 = input[i];

if (_char3 === "}") {
if (_char2 === "}") {
break;
} else {
expression += _char3;
expression += _char2;
}
} // Append the expression as a `<text/>` element with the appropriate
// text content attribute.
Expand All @@ -356,12 +366,12 @@
var text = ""; // Consume the input until the start of a new tag or expression.

for (; i < input.length; i++) {
var _char4 = input[i];
var _char3 = input[i];

if (_char4 === "<" || _char4 === "{") {
if (_char3 === "<" || _char3 === "{") {
break;
} else {
text += _char4;
text += _char3;
}
} // Append the text as a `<text/>` element with the appropriate text
// content attribute if it isn't only whitespace.
Expand All @@ -372,7 +382,10 @@
type: "tagOpen",
value: "text",
attributes: {
"": "\"" + escapeText(text) + "\""
"": {
value: "\"" + escapeText(text) + "\"",
isStatic: true
}
},
closed: true
});
Expand Down Expand Up @@ -622,11 +635,12 @@

function generateNodeIf(element, parent, index, staticNodes) {
var variable = "m" + generateVariable;
var attributes = element.attributes;
var prelude = "";
var emptyElseClause = true;
setGenerateVariable(generateVariable + 1); // Generate the initial `if` clause.

prelude += "var " + variable + ";if(" + element.attributes[""] + "){" + generateClause(variable, element, staticNodes) + "}"; // Search for `else-if` and `else` clauses if there are siblings.
prelude += "var " + variable + ";if(" + attributes[""].value + "){" + generateClause(variable, element, staticNodes) + "}"; // Search for `else-if` and `else` clauses if there are siblings.

if (parent !== null) {
var siblings = parent.children;
Expand All @@ -636,7 +650,7 @@

if (sibling.name === "else-if") {
// Generate the `else-if` clause.
prelude += "else if(" + sibling.attributes[""] + "){" + generateClause(variable, sibling, staticNodes) + "}"; // Remove the `else-if` clause so that it isn't generated
prelude += "else if(" + attributes[""].value + "){" + generateClause(variable, sibling, staticNodes) + "}"; // Remove the `else-if` clause so that it isn't generated
// individually by the parent.

siblings.splice(i, 1);
Expand Down Expand Up @@ -681,9 +695,10 @@

function generateNodeFor(element, staticNodes) {
var variable = "m" + generateVariable;
var dataLocals = element.attributes[""].split(",");
var dataArray = element.attributes.of;
var dataObject = element.attributes["in"];
var attributes = element.attributes;
var dataLocals = attributes[""].value.split(",");
var dataArray = attributes.of;
var dataObject = attributes["in"];
var dataKey;
var dataValue;
var prelude;
Expand All @@ -704,6 +719,7 @@
// Generate a `for` loop over an object. The first local is the key and
// the second is the value.
var dataObjectValue;
dataObject = dataObject.value;
dataKey = dataLocals[0];

if (dataLocals.length === 2) {
Expand All @@ -717,6 +733,7 @@
} else {
// Generate a `for` loop over an array. The first local is the value and
// the second is the key (index).
dataArray = dataArray.value;
dataKey = dataLocals.length === 2 ? dataLocals[1] : "mi";
dataValue = dataLocals[0];
prelude = "for(var " + dataKey + "=0;" + dataKey + "<" + dataArray + ".length;" + dataKey + "++){var " + dataValue + "=" + dataArray + "[" + dataKey + "];" + body + "}";
Expand Down Expand Up @@ -765,11 +782,11 @@
var attributeValue = attributes[attribute]; // Mark the current node as dynamic if there are any events or dynamic
// attributes.

if (attribute[0] === "@" || attributeValue[0] !== "\"" && attributeValue[0] !== "'") {
if (attribute[0] === "@" || !attributeValue.isStatic) {
isStatic = false;
}

data += separator + "\"" + attribute + "\":" + attributeValue;
data += separator + "\"" + attribute + "\":" + attributeValue.value;
separator = ",";
}

Expand Down
2 changes: 1 addition & 1 deletion packages/moon/dist/moon.min.js

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions packages/moon/src/compiler/generator/components/for.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import { generateVariable, setGenerateVariable } from "../util/globals";
*/
export function generateNodeFor(element, staticNodes) {
const variable = "m" + generateVariable;
const dataLocals = element.attributes[""].split(",");
const dataArray = element.attributes.of;
const dataObject = element.attributes.in;
const attributes = element.attributes;
const dataLocals = attributes[""].value.split(",");
let dataArray = attributes.of;
let dataObject = attributes.in;
let dataKey;
let dataValue;
let prelude;
Expand All @@ -31,7 +32,6 @@ export function generateNodeFor(element, staticNodes) {
if (generateChild.isStatic) {
// If the body is static, then use a static node in place of it.
body = `${variable}.push(m[${staticNodes.length}]);`;

staticNodes.push(generateChild);
} else {
// If the body is dynamic, then use the dynamic node in the loop body.
Expand All @@ -42,7 +42,7 @@ export function generateNodeFor(element, staticNodes) {
// Generate a `for` loop over an object. The first local is the key and
// the second is the value.
let dataObjectValue;

dataObject = dataObject.value;
dataKey = dataLocals[0];

if (dataLocals.length === 2) {
Expand All @@ -56,6 +56,7 @@ export function generateNodeFor(element, staticNodes) {
} else {
// Generate a `for` loop over an array. The first local is the value and
// the second is the key (index).
dataArray = dataArray.value;
dataKey = dataLocals.length === 2 ? dataLocals[1] : "mi";
dataValue = dataLocals[0];
prelude = `for(var ${dataKey}=0;${dataKey}<${dataArray}.length;${dataKey}++){var ${dataValue}=${dataArray}[${dataKey}];${body}}`;
Expand Down
5 changes: 3 additions & 2 deletions packages/moon/src/compiler/generator/components/if.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,14 @@ function generateClause(variable, element, staticNodes) {
*/
export function generateNodeIf(element, parent, index, staticNodes) {
const variable = "m" + generateVariable;
const attributes = element.attributes;
let prelude = "";
let emptyElseClause = true;

setGenerateVariable(generateVariable + 1);

// Generate the initial `if` clause.
prelude += `var ${variable};if(${element.attributes[""]}){${generateClause(variable, element, staticNodes)}}`;
prelude += `var ${variable};if(${attributes[""].value}){${generateClause(variable, element, staticNodes)}}`;

// Search for `else-if` and `else` clauses if there are siblings.
if (parent !== null) {
Expand All @@ -55,7 +56,7 @@ export function generateNodeIf(element, parent, index, staticNodes) {

if (sibling.name === "else-if") {
// Generate the `else-if` clause.
prelude += `else if(${sibling.attributes[""]}){${generateClause(variable, sibling, staticNodes)}}`;
prelude += `else if(${attributes[""].value}){${generateClause(variable, sibling, staticNodes)}}`;

// Remove the `else-if` clause so that it isn't generated
// individually by the parent.
Expand Down
4 changes: 2 additions & 2 deletions packages/moon/src/compiler/generator/generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ export function generateNode(element, parent, index, staticNodes) {
// attributes.
if (
attribute[0] === "@" ||
(attributeValue[0] !== "\"" && attributeValue[0] !== "'")
!attributeValue.isStatic
) {
isStatic = false;
}

data += `${separator}"${attribute}":${attributeValue}`;
data += `${separator}"${attribute}":${attributeValue.value}`;
separator = ",";
}

Expand Down

0 comments on commit 9b4d608

Please sign in to comment.