Comparing version 2.1.0 to 2.1.1-1
@@ -307,3 +307,3 @@ "use strict"; | ||
"(function template(data) {\n" + code + "\n})", | ||
options.globals | ||
options.globals, options.name | ||
); | ||
@@ -310,0 +310,0 @@ } |
{ | ||
"name": "razorleaf", | ||
"version": "2.1.0", | ||
"version": "2.1.1-1", | ||
"main": "razorleaf.js", | ||
@@ -5,0 +5,0 @@ "files": [ |
191
parser.js
@@ -14,2 +14,3 @@ "use strict"; | ||
var JS_IDENTIFIER = /\w/; | ||
var JS_IDENTIFIER_INITIAL_CHARACTER = /[a-zA-Z_$]/; | ||
@@ -39,2 +40,6 @@ var singleCharEscapes = { | ||
function describe(c) { | ||
if (c === null) { | ||
return "end of input"; | ||
} | ||
if (RECOGNIZABLE.test(c)) { | ||
@@ -209,2 +214,21 @@ return c; | ||
function identifierState(parser, c) { | ||
if (c === "(") { | ||
parser.context = { | ||
type: "functionCall", | ||
functionName: parser.identifier, | ||
arguments: [], | ||
parent: parser.context, | ||
unexpected: parser.error("Unexpected function call"), | ||
undefined: parser.error(parser.identifier + " is not defined"), | ||
position: { | ||
line: parser.position.line, | ||
character: parser.position.character | ||
} | ||
}; | ||
parser.context.parent.children.push(parser.context); | ||
return functionInitialArgumentState; | ||
} | ||
if (c === ":") { | ||
@@ -466,2 +490,48 @@ return possibleAttributeState; | ||
function functionInitialArgumentState(parser, c) { | ||
if (c === " ") { | ||
return functionInitialArgumentState; | ||
} | ||
if (c === ")") { | ||
return contentState; | ||
} | ||
if (c === null) { | ||
throw parser.error("Expected argument or closing parenthesis"); | ||
//throw parser.error("Function argument never resolves to a valid JavaScript expression"); // TODO: Where did it start? | ||
} | ||
return functionArgumentState(parser, c); | ||
} | ||
function functionArgumentState(parser, c) { | ||
if (c === "," && isExpression(parser.context.currentArgument)) { | ||
parser.context.arguments.push(parser.context.currentArgument); | ||
parser.context.currentArgument = ""; | ||
return functionBeforeArgumentState; | ||
} | ||
if (c === ")" && isExpression(parser.context.currentArgument)) { | ||
parser.context.arguments.push(parser.context.currentArgument); | ||
parser.context.currentArgument = null; | ||
return contentState; | ||
} | ||
parser.context.currentArgument += c; | ||
return functionInitialArgumentState; | ||
} | ||
function functionBeforeArgumentState(parser, c) { | ||
if (c === " ") { | ||
return functionInitialArgumentState; | ||
} | ||
if (c === ")" || c === "," || c === null) { | ||
throw parser.error("Expected argument"); | ||
} | ||
return functionArgumentState(parser, c); | ||
} | ||
var keywords = { | ||
@@ -523,3 +593,3 @@ doctype: function (parser, c) { | ||
push: function () { | ||
throw parser.error("A template that extends another can only contain block actions directly"); | ||
throw parser.error("A template that extends another can only contain block actions or functions directly"); | ||
} | ||
@@ -956,2 +1026,111 @@ }; | ||
return leadingWhitespace(parser, c); | ||
}, | ||
function: function (parser, c) { | ||
parser.context = { | ||
type: "function", | ||
functionName: "", | ||
arguments: [], | ||
parent: parser.context, | ||
children: [], | ||
indent: parser.indent, | ||
position: { | ||
line: parser.position.line, | ||
character: parser.position.character | ||
} | ||
}; | ||
parser.currentArgumentName = ""; | ||
function leadingWhitespace(parser, c) { | ||
if (c === " ") { | ||
return leadingWhitespace; | ||
} | ||
return functionName(parser, c); | ||
} | ||
function functionName(parser, c) { | ||
if (c !== null && IDENTIFIER.test(c)) { | ||
parser.context.functionName += c; | ||
return functionName; | ||
} | ||
if (parser.root.functions.hasOwnProperty(parser.context.functionName)) { | ||
throw parser.error("A function named " + parser.context.functionName + " already exists in this template"); | ||
} | ||
parser.root.functions[parser.context.functionName] = parser.context; | ||
console.log(parser.root.functions); | ||
return beforeArgumentList(parser, c); | ||
} | ||
function beforeArgumentList(parser, c) { | ||
if (c === " ") { | ||
return beforeArgumentList; | ||
} | ||
if (c === "(") { | ||
return initialArgument; | ||
} | ||
throw parser.error("Expected argument list, not " + describe(c)); | ||
} | ||
function initialArgument(parser, c) { | ||
if (c === " ") { | ||
return initialArgument; | ||
} | ||
if (c === ")") { | ||
return contentState; | ||
} | ||
if (c === null || !JS_IDENTIFIER_INITIAL_CHARACTER.test(c)) { | ||
throw parser.error("Expected argument name or closing parenthesis, not " + describe(c)); | ||
} | ||
return argumentName(parser, c); | ||
} | ||
function beforeArgumentName(parser, c) { | ||
if (c === " ") { | ||
return beforeArgumentName; | ||
} | ||
if (c === null || !JS_IDENTIFIER_INITIAL_CHARACTER.test(c)) { | ||
throw parser.error("Expected argument name, not " + describe(c)); | ||
} | ||
return argumentName(parser, c); | ||
} | ||
function argumentName(parser, c) { | ||
if (c !== null && JS_IDENTIFIER.test(c)) { | ||
parser.currentArgumentName += c; | ||
return argumentName; | ||
} | ||
parser.context.arguments.push(parser.currentArgumentName); | ||
return afterArgumentName(parser, c); | ||
} | ||
function afterArgumentName(parser, c) { | ||
if (c === " ") { | ||
return afterArgumentName; | ||
} | ||
if (c === ",") { | ||
parser.currentArgumentName = ""; | ||
return beforeArgumentName; | ||
} | ||
if (c === ")") { | ||
return contentState; | ||
} | ||
throw parser.error("Expected comma or closing parenthesis, not " + describe(c)); | ||
} | ||
return leadingWhitespace(parser, c); | ||
} | ||
@@ -971,3 +1150,4 @@ }; | ||
blockActions: null, | ||
blocks: {} | ||
blocks: {}, | ||
functions: {} | ||
}; | ||
@@ -984,2 +1164,3 @@ | ||
indexIdentifier: null, | ||
currentArgumentName: null, | ||
raw: null, | ||
@@ -1001,6 +1182,4 @@ string: null, | ||
warn: function (message) { | ||
if (options.debug) { | ||
var where = eof ? "EOF" : "line " + parser.position.line + ", character " + parser.position.character; | ||
console.warn("⚠ %s at %s in %s.", message, where, options.name); | ||
} | ||
var where = eof ? "EOF" : "line " + parser.position.line + ", character " + parser.position.character; | ||
console.warn("⚠ %s at %s in %s.", message, where, options.name); | ||
} | ||
@@ -1007,0 +1186,0 @@ }); |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
975808
25823
1