Comparing version 1.3.1 to 1.4.0
103
compiler.js
"use strict"; | ||
var push = Array.prototype.push; | ||
var utilities = require("./utilities"); | ||
@@ -38,64 +37,2 @@ | ||
function OutputBuffer(parts) { | ||
this.parts = parts || []; | ||
} | ||
OutputBuffer.prototype.addText = function(text) { | ||
this.parts.push({ | ||
type: "text", | ||
value: text | ||
}); | ||
}; | ||
OutputBuffer.prototype.addCode = function(code) { | ||
this.parts.push({ | ||
type: "code", | ||
value: code | ||
}); | ||
}; | ||
OutputBuffer.prototype.addInterpolated = function(code) { | ||
this.parts.push({ | ||
type: "interpolated", | ||
value: code | ||
}); | ||
}; | ||
OutputBuffer.prototype.addBuffer = function(buffer) { | ||
push.apply(this.parts, buffer.parts); | ||
}; | ||
Object.defineProperty(OutputBuffer.prototype, "code", { | ||
get: function() { | ||
var isCode = true; | ||
var code = ""; | ||
for(var i = 0; i < this.parts.length; i++) { | ||
var part = this.parts[i]; | ||
if(part.type === "code") { | ||
if(!isCode) { | ||
code += "';\n"; | ||
isCode = true; | ||
} | ||
code += part.value; | ||
} else { | ||
if(isCode) { | ||
code += "\n__output += '"; | ||
isCode = false; | ||
} | ||
code += part.type === "interpolated" ? part.value : part.value.replace(/'/g, "\\'"); | ||
} | ||
} | ||
if(!isCode) { | ||
code += "';\n"; | ||
} | ||
return code; | ||
} | ||
}); | ||
var voidTags = [ | ||
@@ -116,3 +53,3 @@ "area", "base", "br", "col", "command", "embed", "hr", "img", "input", | ||
return { | ||
attributes: new OutputBuffer([ | ||
attributes: new utilities.CodeContext(null, [ | ||
{ | ||
@@ -123,11 +60,11 @@ type: "text", | ||
]), | ||
content: isVoid ? null : new OutputBuffer(), | ||
content: isVoid ? null : new utilities.CodeContext(null), | ||
scope: context.scope, | ||
parent: context, | ||
done: function() { | ||
this.parent.content.addBuffer(this.attributes); | ||
this.parent.content.addContext(this.attributes); | ||
this.parent.content.addText(">"); | ||
if(!isVoid) { | ||
this.parent.content.addBuffer(this.content); | ||
this.parent.content.addContext(this.content); | ||
this.parent.content.addText("</" + node.name + ">"); | ||
@@ -143,3 +80,3 @@ } | ||
context.content.addInterpolated(node.content.code); | ||
context.content.addContext(node.content); | ||
}, | ||
@@ -155,3 +92,3 @@ attribute: function(node, context) { | ||
context.attributes.addText("=\""); | ||
context.attributes.addInterpolated(node.value.content.code); | ||
context.attributes.addContext(node.value.content); | ||
context.attributes.addText("\""); | ||
@@ -162,3 +99,3 @@ } | ||
return { | ||
content: new OutputBuffer(), | ||
content: new utilities.CodeContext(), | ||
scope: context.scope, | ||
@@ -171,7 +108,7 @@ parent: context, | ||
this.parent.content.addCode("{"); | ||
this.parent.content.addBuffer(this.content); | ||
this.parent.content.addContext(this.content); | ||
this.parent.content.addCode("}\n"); | ||
} else { | ||
this.parent.content.addCode(";"); | ||
this.parent.content.addBuffer(this.content); | ||
this.parent.content.addContext(this.content); | ||
} | ||
@@ -216,3 +153,3 @@ } | ||
var context = { | ||
content: new OutputBuffer(), | ||
content: new utilities.CodeContext(), | ||
scope: new Scope(), | ||
@@ -283,4 +220,4 @@ done: function() {} | ||
return { | ||
attributes: new OutputBuffer(), | ||
content: new OutputBuffer(), | ||
attributes: new utilities.CodeContext(), | ||
content: new utilities.CodeContext(), | ||
scope: context.scope, | ||
@@ -293,4 +230,4 @@ parent: context, | ||
elseContext = { | ||
attributes: new OutputBuffer(), | ||
content: new OutputBuffer(), | ||
attributes: new utilities.CodeContext(), | ||
content: new utilities.CodeContext(), | ||
scope: context.scope, | ||
@@ -312,3 +249,3 @@ parent: context | ||
this.parent.attributes.addCode("if(" + conditionName + ") {\n"); | ||
this.parent.attributes.addBuffer(this.attributes); | ||
this.parent.attributes.addContext(this.attributes); | ||
this.parent.attributes.addCode("}\n"); | ||
@@ -318,3 +255,3 @@ | ||
this.parent.attributes.addCode("else {\n"); | ||
this.parent.attributes.addBuffer(elseContext.attributes); | ||
this.parent.attributes.addContext(elseContext.attributes); | ||
this.parent.attributes.addCode("}\n"); | ||
@@ -326,3 +263,3 @@ } | ||
this.parent.content.addCode("if(" + conditionName + ") {\n"); | ||
this.parent.content.addBuffer(this.content); | ||
this.parent.content.addContext(this.content); | ||
this.parent.content.addCode("}\n"); | ||
@@ -333,3 +270,3 @@ } | ||
this.parent.content.addCode("else {\n"); | ||
this.parent.content.addBuffer(elseContext.content); | ||
this.parent.content.addContext(elseContext.content); | ||
this.parent.content.addCode("}\n"); | ||
@@ -354,3 +291,3 @@ } | ||
return { | ||
content: new OutputBuffer(), | ||
content: new utilities.CodeContext(), | ||
scope: context.scope, | ||
@@ -364,3 +301,3 @@ parent: context, | ||
); | ||
this.parent.content.addBuffer(this.content); | ||
this.parent.content.addContext(this.content); | ||
this.parent.content.addCode("}\n"); | ||
@@ -367,0 +304,0 @@ |
{ | ||
"name": "razorleaf", | ||
"version": "1.3.1", | ||
"version": "1.4.0", | ||
"main": "razorleaf.js", | ||
@@ -5,0 +5,0 @@ "files": [ |
104
parser.js
"use strict"; | ||
var push = Array.prototype.push; | ||
var utilities = require("./utilities"); | ||
@@ -9,97 +8,2 @@ | ||
function escapeStringLiteral(string) { | ||
var result = ""; | ||
var escaped = false; | ||
for(var i = 0; i < string.length; i++) { | ||
var c = string.charAt(i); | ||
if(escaped) { | ||
escaped = false; | ||
result += c; | ||
} else if(c === "\\") { | ||
escaped = true; | ||
result += c; | ||
} else if(c === "\n") { | ||
result += "\\n"; | ||
} else if(c === "\r") { | ||
result += "\\r"; | ||
} else if(c === "\u2028") { | ||
result += "\\u2028"; | ||
} else if(c === "\u2029") { | ||
result += "\\u2029"; | ||
} else if(c === "'") { | ||
result += "\\'"; | ||
} else { | ||
result += c; | ||
} | ||
} | ||
return result; | ||
} | ||
function InterpolatedString(escapeFunction) { | ||
this.parts = []; | ||
this.escapeFunction = escapeFunction; | ||
} | ||
InterpolatedString.prototype.addText = function(text) { | ||
this.parts.push({ | ||
type: "text", | ||
value: text | ||
}); | ||
}; | ||
InterpolatedString.prototype.addCode = function(code) { | ||
this.parts.push({ | ||
type: "code", | ||
value: code | ||
}); | ||
}; | ||
InterpolatedString.prototype.addBuffer = function(buffer) { | ||
push.apply(this.parts, buffer.parts); | ||
}; | ||
Object.defineProperty(InterpolatedString.prototype, "code", { | ||
get: function() { | ||
var isCode = false; | ||
var code = ""; | ||
for(var i = 0; i < this.parts.length; i++) { | ||
var part = this.parts[i]; | ||
if(part.type === "code") { | ||
if(!isCode) { | ||
code += "' + "; | ||
isCode = true; | ||
} | ||
if(this.escapeFunction) { | ||
code += "__util." + this.escapeFunction + "((" + part.value + "\n)) + "; | ||
} else { | ||
code += "(" + part.value + "\n) + "; | ||
} | ||
} else { | ||
if(isCode) { | ||
code += "'"; | ||
isCode = false; | ||
} | ||
if(this.escapeFunction) { | ||
code += escapeStringLiteral(utilities[this.escapeFunction](part.value)); | ||
} else { | ||
code += escapeStringLiteral(part.value); | ||
} | ||
} | ||
} | ||
if(isCode) { | ||
code += "'"; | ||
} | ||
return code; | ||
} | ||
}); | ||
var specialBlocks = {}; | ||
@@ -138,3 +42,3 @@ | ||
type: "string", | ||
content: new InterpolatedString("escapeContent"), | ||
content: new utilities.CodeContext("escapeContent"), | ||
current: "", | ||
@@ -153,3 +57,3 @@ parent: this.context, | ||
type: "string", | ||
content: new InterpolatedString(null), | ||
content: new utilities.CodeContext(null), | ||
current: "", | ||
@@ -261,3 +165,3 @@ parent: this.context, | ||
} else if(c === "}") { | ||
this.context.parent.content.addCode(this.context.value); | ||
this.context.parent.content.addExpression(this.context.value); | ||
this.context = this.context.parent; | ||
@@ -312,3 +216,3 @@ return states.string; | ||
type: "string", | ||
content: new InterpolatedString("escapeAttributeValue"), | ||
content: new utilities.CodeContext("escapeAttributeValue"), | ||
current: "", | ||
@@ -315,0 +219,0 @@ parent: attribute.parent, |
122
utilities.js
"use strict"; | ||
var push = Array.prototype.push; | ||
var amp = /&/g; | ||
@@ -17,5 +18,126 @@ var quot = /"/g; | ||
.replace(gt, ">"); | ||
}, | ||
CodeContext: CodeContext | ||
}; | ||
function escapeStringLiteral(string) { | ||
var result = ""; | ||
var escaped = false; | ||
for(var i = 0; i < string.length; i++) { | ||
var c = string.charAt(i); | ||
if(escaped) { | ||
escaped = false; | ||
result += c; | ||
} else if(c === "\\") { | ||
escaped = true; | ||
result += c; | ||
} else if(c === "\n") { | ||
result += "\\n"; | ||
} else if(c === "\r") { | ||
result += "\\r"; | ||
} else if(c === "\u2028") { | ||
result += "\\u2028"; | ||
} else if(c === "\u2029") { | ||
result += "\\u2029"; | ||
} else if(c === "'") { | ||
result += "\\'"; | ||
} else { | ||
result += c; | ||
} | ||
} | ||
return result; | ||
} | ||
function CodeContext(escapeFunction, initialParts) { | ||
this.parts = initialParts || []; | ||
this.escapeFunction = escapeFunction; | ||
} | ||
CodeContext.prototype.addCode = function(code) { | ||
this.parts.push({type: "code", value: code}); | ||
}; | ||
CodeContext.prototype.addText = function(text) { | ||
if(this.escapeFunction) { | ||
text = utilities[this.escapeFunction](text); | ||
} | ||
this.parts.push({type: "text", value: text}); | ||
}; | ||
CodeContext.prototype.addExpression = function(expression) { | ||
this.parts.push({type: "expression", value: expression, escapeFunction: this.escapeFunction}); | ||
}; | ||
CodeContext.prototype.addContext = function(context) { | ||
push.apply(this.parts, context.parts); | ||
}; | ||
Object.defineProperty(CodeContext.prototype, "code", { | ||
get: function() { | ||
var current = "code"; | ||
var generated = ""; | ||
for(var i = 0; i < this.parts.length; i++) { | ||
var part = this.parts[i]; | ||
switch(part.type) { | ||
case "code": | ||
if(current === "text") { | ||
generated += "';\n"; | ||
} else if(current === "expression") { | ||
generated += ";\n"; | ||
} | ||
generated += part.value; | ||
current = "code"; | ||
break; | ||
case "text": | ||
if(current === "code") { | ||
generated += "__output += '"; | ||
} else if(current === "expression") { | ||
generated += " + '"; | ||
} | ||
generated += escapeStringLiteral(part.value); | ||
current = "text"; | ||
break; | ||
case "expression": | ||
if(current === "code") { | ||
generated += "__output += "; | ||
} else if(current === "text") { | ||
generated += "' + "; | ||
} else { | ||
generated += " + "; | ||
} | ||
if(part.escapeFunction) { | ||
generated += "__util." + part.escapeFunction + "((" + part.value + "))"; | ||
} else { | ||
generated += "(" + part.value + ")"; | ||
} | ||
current = "expression"; | ||
break; | ||
default: | ||
throw new Error("Unknown part type"); | ||
} | ||
} | ||
if(current === "text") { | ||
generated += "';"; | ||
} else if(current === "expression") { | ||
generated += ";"; | ||
} | ||
return generated; | ||
} | ||
}); | ||
module.exports = utilities; |
29655
920