mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
Simple template compilation is working
This commit is contained in:
parent
a5ad8e681a
commit
4cf0ae528c
@ -26,8 +26,8 @@
|
||||
*
|
||||
*
|
||||
*/
|
||||
var createError = require('raptor-util').createError;
|
||||
'use strict';
|
||||
var createError = require('raptor-util').createError;
|
||||
var strings = require('raptor-strings');
|
||||
var TypeConverter = require('./TypeConverter');
|
||||
var regExp = /"(?:[^"]|\\")*"|'(?:[^']|\\')*'|==|===|[;=]/g;
|
||||
@ -16,12 +16,13 @@
|
||||
|
||||
'use strict';
|
||||
var createError = require('raptor-util').createError;
|
||||
var forEach = raptor.forEach;
|
||||
var objects = require('raptor-objects');
|
||||
var escapeXmlAttr = require('raptor-xml/utils').escapeXmlAttr;
|
||||
var escapeXmlAttr = require('raptor-xml/util').escapeXmlAttr;
|
||||
var XML_URI = 'http://www.w3.org/XML/1998/namespace';
|
||||
var XML_URI_ALT = 'http://www.w3.org/XML/1998/namespace';
|
||||
var ExpressionParser = require('./ExpressionParser');
|
||||
var forEachEntry = require('raptor-util').forEachEntry;
|
||||
|
||||
function ElementNode(localName, uri, prefix) {
|
||||
ElementNode.$super.call(this, 'element');
|
||||
if (!this._elementNode) {
|
||||
@ -127,7 +128,7 @@ ElementNode.prototype = {
|
||||
delete this.attributesByNS[uri || ''];
|
||||
},
|
||||
isPreserveWhitespace: function () {
|
||||
var preserveSpace = ElementNode.superclass.isPreserveWhitespace.call(this);
|
||||
var preserveSpace = ElementNode.$super.prototype.isPreserveWhitespace.call(this);
|
||||
if (preserveSpace === true) {
|
||||
return true;
|
||||
}
|
||||
@ -217,7 +218,7 @@ ElementNode.prototype = {
|
||||
template.attr(name, attrParts[0].expression, attrParts[0].escapeXml !== false);
|
||||
} else {
|
||||
template.text(' ' + name + '="');
|
||||
forEach(attrParts, function (part) {
|
||||
attrParts.forEach(function (part) {
|
||||
if (part.text) {
|
||||
template.text(part.escapeXml !== false ? escapeXmlAttr(part.text) : part.text);
|
||||
} else if (part.expression) {
|
||||
@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
define.Enum('raptor/templating/compiler/EscapeXmlContext', [
|
||||
module.exports = require('raptor-util').makeEnum([
|
||||
'Element',
|
||||
'Attribute'
|
||||
]);
|
||||
@ -13,8 +13,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
var createError = require('raptor-util').createError;
|
||||
'use strict';
|
||||
var createError = require('raptor-util').createError;
|
||||
var Expression = require('./Expression');
|
||||
var strings = require('raptor-strings');
|
||||
var stringify = require('raptor-json/stringify');
|
||||
@ -29,13 +29,12 @@ var endingTokens = {
|
||||
};
|
||||
function createStartRegExpStr(starts) {
|
||||
var parts = [];
|
||||
raptor.forEach(starts, function (start) {
|
||||
starts.forEach(function (start) {
|
||||
parts.push(regexp.escape('\\\\' + start));
|
||||
parts.push(regexp.escape('\\' + start));
|
||||
parts.push(regexp.escape(start));
|
||||
});
|
||||
module.exports = parts.join('|');
|
||||
return;
|
||||
return parts.join('|');
|
||||
}
|
||||
var startRegExpStr = createStartRegExpStr([
|
||||
'{%',
|
||||
@ -46,9 +45,9 @@ var startRegExpStr = createStartRegExpStr([
|
||||
'{?'
|
||||
]);
|
||||
function createStartRegExp() {
|
||||
module.exports = new RegExp(startRegExpStr, 'g');
|
||||
return;
|
||||
return new RegExp(startRegExpStr, 'g');
|
||||
}
|
||||
|
||||
function getLine(str, pos) {
|
||||
var lines = str.split('\n');
|
||||
var index = 0;
|
||||
@ -68,8 +67,7 @@ function getLine(str, pos) {
|
||||
str: line,
|
||||
pos: pos
|
||||
};
|
||||
module.exports = ExpressionParser;
|
||||
return;
|
||||
return ExpressionParser;
|
||||
}
|
||||
function errorContext(str, pos, length) {
|
||||
var line = getLine(str, pos);
|
||||
@ -96,8 +94,7 @@ function errorContext(str, pos, length) {
|
||||
for (i = 0; i < suffix.length; i++) {
|
||||
context += ' ';
|
||||
}
|
||||
module.exports = context;
|
||||
return;
|
||||
return context;
|
||||
}
|
||||
function getConditionalExpression(expression) {
|
||||
var tokensRegExp = /"(?:[^"]|\\")*"|'(?:[^']|\\')*'|\\\\;|\\;|[\{\};]/g;
|
||||
@ -150,18 +147,14 @@ function getConditionalExpression(expression) {
|
||||
expressionParts.push(expression);
|
||||
}
|
||||
});
|
||||
module.exports = expressionParts.join('+');
|
||||
return;
|
||||
return expressionParts.join('+');
|
||||
}
|
||||
if (parts.length === 1) {
|
||||
module.exports = '(' + parts[0] + ' ? ' + 'null' + ' : \'\')';
|
||||
return;
|
||||
return '(' + parts[0] + ' ? ' + 'null' + ' : \'\')';
|
||||
} else if (parts.length === 2) {
|
||||
module.exports = '(' + parts[0] + ' ? ' + getExpression(parts[1]) + ' : \'\')';
|
||||
return;
|
||||
return '(' + parts[0] + ' ? ' + getExpression(parts[1]) + ' : \'\')';
|
||||
} else if (parts.length === 3) {
|
||||
module.exports = '(' + parts[0] + ' ? ' + getExpression(parts[1]) + ' : ' + getExpression(parts[2]) + ')';
|
||||
return;
|
||||
return'(' + parts[0] + ' ? ' + getExpression(parts[1]) + ' : ' + getExpression(parts[2]) + ')';
|
||||
} else {
|
||||
throw new Error('Invalid simple conditional of "' + expression + '". Simple conditionals should be in the form {?<expression>;<true-template>[;<false-template>]}');
|
||||
}
|
||||
@ -191,8 +184,7 @@ function processNestedStrings(expression, foundStrings) {
|
||||
expression = expression.substring(0, foundString.start) + '(' + parts.join('+') + ')' + expression.substring(foundString.end);
|
||||
}
|
||||
}
|
||||
module.exports = expression;
|
||||
return;
|
||||
return expression;
|
||||
}
|
||||
var ExpressionParserHelper = function () {
|
||||
function Class(callback, callbackThisObj) {
|
||||
@ -244,6 +236,7 @@ var ExpressionParserHelper = function () {
|
||||
};
|
||||
return Class;
|
||||
}();
|
||||
|
||||
function ExpressionParser() {
|
||||
}
|
||||
/**
|
||||
@ -13,8 +13,9 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
var createError = require('raptor-util').createError;
|
||||
'use strict';
|
||||
var createError = require('raptor-util').createError;
|
||||
var forEachEntry = require('raptor-util').forEachEntry;
|
||||
var isArray = Array.isArray;
|
||||
var isEmpty = require('raptor-objects').isEmpty;
|
||||
function Node(nodeType) {
|
||||
@ -245,7 +246,7 @@ Node.prototype = {
|
||||
if (!childNodes) {
|
||||
return;
|
||||
}
|
||||
raptor.forEach(childNodes, function (childNode) {
|
||||
childNodes.forEach(function (childNode) {
|
||||
this.appendChild(childNode);
|
||||
}, this);
|
||||
},
|
||||
@ -335,7 +336,7 @@ Node.prototype = {
|
||||
return false;
|
||||
}
|
||||
if (isArray(node)) {
|
||||
raptor.forEach(node, function (node) {
|
||||
node.forEach(function (node) {
|
||||
this.insertAfter(node, referenceNode);
|
||||
referenceNode = node;
|
||||
}, this);
|
||||
@ -13,10 +13,9 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
var createError = require('raptor-util').createError;
|
||||
'use strict';
|
||||
var createError = require('raptor-util').createError;
|
||||
var sax = require('raptor-xml/sax');
|
||||
var forEach = raptor.forEach;
|
||||
var TextNode = require('./TextNode');
|
||||
var ElementNode = require('./ElementNode');
|
||||
function ParseTreeBuilder() {
|
||||
@ -67,7 +66,7 @@ ParseTreeBuilder.prototype = {
|
||||
var elementNode = new ElementNode(el.getLocalName(), taglibs.resolveURI(el.getNamespaceURI()), el.getPrefix());
|
||||
elementNode.addNamespaceMappings(el.getNamespaceMappings());
|
||||
elementNode.pos = parser.getPos();
|
||||
forEach(el.getAttributes(), function (attr) {
|
||||
el.getAttributes().forEach(function (attr) {
|
||||
if (attr.getLocalName() === 'imports' && !attr.getNamespaceURI()) {
|
||||
importsAttr = attr.getValue();
|
||||
}
|
||||
@ -80,7 +79,7 @@ ParseTreeBuilder.prototype = {
|
||||
imports = taglibs.getImports(importsAttr);
|
||||
}
|
||||
}
|
||||
forEach(el.getAttributes(), function (attr) {
|
||||
el.getAttributes().forEach(function (attr) {
|
||||
var attrURI = taglibs.resolveURI(attr.getNamespaceURI());
|
||||
var attrLocalName = attr.getLocalName();
|
||||
var attrPrefix = attr.getPrefix();
|
||||
@ -28,6 +28,7 @@ function Taglib() {
|
||||
this.functions = [];
|
||||
this.helperObject = null;
|
||||
this.patternAttributes = [];
|
||||
this.importPaths = [];
|
||||
}
|
||||
|
||||
Taglib.prototype = {
|
||||
@ -268,11 +269,11 @@ Taglib.Transformer = function () {
|
||||
}
|
||||
Transformer.prototype = {
|
||||
getInstance: function () {
|
||||
if (!this.className) {
|
||||
if (!this.filename) {
|
||||
throw createError(new Error('Transformer class not defined for tag transformer (tag=' + this.tag + ')'));
|
||||
}
|
||||
if (!this.instance) {
|
||||
var Clazz = require(this.className);
|
||||
var Clazz = require(this.filename);
|
||||
if (Clazz.process) {
|
||||
return Clazz;
|
||||
}
|
||||
@ -282,19 +283,19 @@ Taglib.Transformer = function () {
|
||||
return this.instance;
|
||||
},
|
||||
toString: function () {
|
||||
return '[Taglib.Transformer: ' + this.className + ']';
|
||||
return '[Taglib.Transformer: ' + this.filename + ']';
|
||||
}
|
||||
};
|
||||
return Transformer;
|
||||
}();
|
||||
Taglib.Function = function () {
|
||||
function Function() {
|
||||
function Func() {
|
||||
this.name = null;
|
||||
this.functionClass = null;
|
||||
this.bindToContext = false;
|
||||
}
|
||||
Function.prototype = {};
|
||||
return Function;
|
||||
Func.prototype = {};
|
||||
return Func;
|
||||
}();
|
||||
Taglib.HelperObject = function () {
|
||||
function HelperObject() {
|
||||
@ -16,10 +16,9 @@
|
||||
/**
|
||||
* Merges a set of taglibs for ea
|
||||
*/
|
||||
'use strict';
|
||||
var createError = require('raptor-util').createError;
|
||||
var forEachEntry = require('raptor-util').forEachEntry;
|
||||
'use strict';
|
||||
var forEach = raptor.forEach;
|
||||
var strings = require('raptor-strings');
|
||||
var ElementNode = require('./ElementNode');
|
||||
var TextNode = require('./TextNode');
|
||||
@ -38,26 +37,21 @@ function getImported(lookup, localName, imports) {
|
||||
name = localName.substring(prefixEnd + 1);
|
||||
uri = imports._prefixes[prefix];
|
||||
if (uri) {
|
||||
function TaglibCollection() {
|
||||
}
|
||||
TaglibCollection.prototype = {
|
||||
return {
|
||||
uri: uri,
|
||||
name: name,
|
||||
prefix: prefix
|
||||
};
|
||||
module.exports = TaglibCollection;
|
||||
return;
|
||||
}
|
||||
}
|
||||
module.exports = null;
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
function Imports(taglibs, importsStr) {
|
||||
this._tagImports = {};
|
||||
this._attrImports = {};
|
||||
this._prefixes = {};
|
||||
var parts = strings.trim(importsStr).split(/\s*;\s*/);
|
||||
forEach(parts, function (part) {
|
||||
parts.forEach(function (part) {
|
||||
if (!part) {
|
||||
//Skip empty strings
|
||||
return;
|
||||
@ -83,7 +77,7 @@ function Imports(taglibs, importsStr) {
|
||||
}
|
||||
this._prefixes[as] = from;
|
||||
if (imports) {
|
||||
forEach(imports.split(/\s*,\s*/), function (importedTagName) {
|
||||
imports.split(/\s*,\s*/).forEach(function (importedTagName) {
|
||||
importsLookup[importedTagName] = true;
|
||||
});
|
||||
}
|
||||
@ -243,10 +237,11 @@ TaglibCollection.prototype = {
|
||||
/*
|
||||
* Now register all of the text transformers that are part of the provided taglibs
|
||||
*/
|
||||
forEach(taglib.textTransformers, function (textTransformer) {
|
||||
taglib.textTransformers.forEach(function (textTransformer) {
|
||||
this.textTransformers[textTransformer.className] = textTransformer;
|
||||
}, this);
|
||||
forEach(taglib.functions, function (func) {
|
||||
|
||||
taglib.functions.forEach(function (func) {
|
||||
if (!func.name) {
|
||||
throw createError(new Error('Function name not set.'));
|
||||
}
|
||||
@ -310,7 +305,11 @@ TaglibCollection.prototype = {
|
||||
var handled = {};
|
||||
var before = {};
|
||||
function _addTransformers(transformers) {
|
||||
raptor.forEach(transformers, function (transformer) {
|
||||
if (!transformers) {
|
||||
return;
|
||||
}
|
||||
|
||||
transformers.forEach(function (transformer) {
|
||||
if (!transformer) {
|
||||
throw createError(new Error('Invalid transformer'));
|
||||
}
|
||||
@ -343,7 +342,11 @@ TaglibCollection.prototype = {
|
||||
}
|
||||
_handleTransformer(matchingTransformersByName[transformer.after]); //Handle any transformers that this transformer is supposed to run after
|
||||
}
|
||||
raptor.forEach(before[transformer.className], _handleTransformer);
|
||||
|
||||
if (before[transformer.className]) {
|
||||
before[transformer.className].forEach(_handleTransformer);
|
||||
}
|
||||
|
||||
//Handle any transformers that are configured to run before this transformer
|
||||
callback.call(thisObj, transformer);
|
||||
}
|
||||
@ -13,9 +13,9 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
var createError = require('raptor-util').createError;
|
||||
'use strict';
|
||||
var objectMapper = require('raptor-xml/sax/object-mapper');
|
||||
var createError = require('raptor-util').createError;
|
||||
var objectMapper = require('raptor-xml/object-mapper');
|
||||
var regexp = require('raptor-regexp');
|
||||
var Taglib = require('./Taglib');
|
||||
var Tag = Taglib.Tag;
|
||||
@ -24,26 +24,33 @@ var Property = Taglib.Property;
|
||||
var NestedVariable = Taglib.NestedVariable;
|
||||
var ImportedVariable = Taglib.ImportedVariable;
|
||||
var Transformer = Taglib.Transformer;
|
||||
var Function = Taglib.Function;
|
||||
var Func = Taglib.Function;
|
||||
var HelperObject = Taglib.HelperObject;
|
||||
var nodePath = require('path');
|
||||
var fs = require('fs');
|
||||
var STRING = 'string';
|
||||
var BOOLEAN = 'boolean';
|
||||
var OBJECT = 'object';
|
||||
function TaglibXmlLoader(src, resource) {
|
||||
|
||||
function TaglibXmlLoader(src, filePath) {
|
||||
this.src = src;
|
||||
this.filePath = typeof resource === 'string' ? resource : resource.getURL();
|
||||
this.resource = resource;
|
||||
this.filePath = filePath;
|
||||
}
|
||||
TaglibXmlLoader.load = function (src, resource) {
|
||||
var loader = new TaglibXmlLoader(src, resource);
|
||||
TaglibXmlLoader.load = function (src, filePath) {
|
||||
var loader = new TaglibXmlLoader(src, filePath);
|
||||
return loader.load();
|
||||
};
|
||||
TaglibXmlLoader.prototype = {
|
||||
load: function () {
|
||||
var src = this.src;
|
||||
var filePath = this.filePath;
|
||||
var taglibResource = this.resource;
|
||||
var dirname = nodePath.dirname(filePath);
|
||||
var tagsById = {};
|
||||
|
||||
function resolve(path) {
|
||||
return nodePath.resolve(dirname, path);
|
||||
}
|
||||
|
||||
function handleTagExtends(subTag) {
|
||||
var extendsId = subTag['extends'];
|
||||
if (!extendsId) {
|
||||
@ -164,11 +171,7 @@ TaglibXmlLoader.prototype = {
|
||||
_type: STRING,
|
||||
_targetProp: 'version'
|
||||
},
|
||||
'short-name': {
|
||||
_type: STRING,
|
||||
_targetProp: 'shortName'
|
||||
},
|
||||
'uri': {
|
||||
'alias': {
|
||||
_type: STRING,
|
||||
_set: function (taglib, name, value, context) {
|
||||
if (!taglib.uri) {
|
||||
@ -178,7 +181,6 @@ TaglibXmlLoader.prototype = {
|
||||
}
|
||||
}
|
||||
},
|
||||
'prefix': { _type: STRING },
|
||||
'tag': {
|
||||
_type: OBJECT,
|
||||
_begin: function () {
|
||||
@ -295,9 +297,10 @@ TaglibXmlLoader.prototype = {
|
||||
'import-variable': importVariableHandler,
|
||||
'transformer-class': {
|
||||
_type: STRING,
|
||||
_set: function (tag, name, value) {
|
||||
_set: function (tag, name, path) {
|
||||
path = resolve(path);
|
||||
var transformer = new Transformer();
|
||||
transformer.className = value;
|
||||
transformer.filename = path;
|
||||
tag.addTransformer(transformer);
|
||||
}
|
||||
},
|
||||
@ -311,7 +314,10 @@ TaglibXmlLoader.prototype = {
|
||||
},
|
||||
'class-name': {
|
||||
_type: STRING,
|
||||
_targetProp: 'className'
|
||||
_set: function (transformer, name, path) {
|
||||
path = resolve(path);
|
||||
transformer.filename = path;
|
||||
}
|
||||
},
|
||||
'after': {
|
||||
_type: STRING,
|
||||
@ -324,7 +330,7 @@ TaglibXmlLoader.prototype = {
|
||||
'<properties>': {
|
||||
_type: OBJECT,
|
||||
_begin: function (parent) {
|
||||
return parent.properties = {};
|
||||
return (parent.properties = {});
|
||||
},
|
||||
'<*>': { _type: STRING }
|
||||
}
|
||||
@ -340,7 +346,10 @@ TaglibXmlLoader.prototype = {
|
||||
},
|
||||
'class-name': {
|
||||
_type: STRING,
|
||||
_targetProp: 'className'
|
||||
_set: function (transformer, name, path) {
|
||||
path = resolve(path);
|
||||
transformer.filename = path;
|
||||
}
|
||||
}
|
||||
},
|
||||
'import-taglib': {
|
||||
@ -349,27 +358,23 @@ TaglibXmlLoader.prototype = {
|
||||
return {};
|
||||
},
|
||||
_end: function (importedTaglib) {
|
||||
var path = importedTaglib.path;
|
||||
var importedXmlSource;
|
||||
var importedTaglibResource;
|
||||
if (path.startsWith('/')) {
|
||||
importedTaglibResource = require('raptor-resources').findResource(path);
|
||||
} else {
|
||||
importedTaglibResource = taglibResource.resolve(path);
|
||||
}
|
||||
if (!importedTaglibResource.exists()) {
|
||||
var path = resolve(importedTaglib.path);
|
||||
taglib.importPaths.push(path);
|
||||
|
||||
if (!fs.existsSync(path)) {
|
||||
throw createError(new Error('Imported taglib with path "' + path + '" not found in taglib at path "' + filePath + '"'));
|
||||
}
|
||||
require('raptor-templates/compiler').recordLoadedTaglib(importedTaglibResource);
|
||||
importedXmlSource = importedTaglibResource.readAsString();
|
||||
objectMapper.read(importedXmlSource, importedTaglibResource.getURL(), handlers);
|
||||
|
||||
var importedXmlSource = fs.readFileSync(path);
|
||||
require('../work-dir').recordLoadedTaglib(path);
|
||||
objectMapper.read(importedXmlSource, path, handlers);
|
||||
},
|
||||
'path': { _type: STRING }
|
||||
},
|
||||
'function': {
|
||||
_type: OBJECT,
|
||||
_begin: function () {
|
||||
return new Function();
|
||||
return new Func();
|
||||
},
|
||||
_end: function (func) {
|
||||
taglib.addFunction(func);
|
||||
@ -377,7 +382,10 @@ TaglibXmlLoader.prototype = {
|
||||
'name': { _type: STRING },
|
||||
'class': {
|
||||
_type: STRING,
|
||||
_targetProp: 'functionClass'
|
||||
_set: function (func, name, path) {
|
||||
path = resolve(path);
|
||||
func.filename = path;
|
||||
}
|
||||
},
|
||||
'bind-to-context': {
|
||||
_type: BOOLEAN,
|
||||
@ -394,11 +402,17 @@ TaglibXmlLoader.prototype = {
|
||||
},
|
||||
'module-name': {
|
||||
_type: STRING,
|
||||
_targetProp: 'moduleName'
|
||||
_set: function (helperObject, name, path) {
|
||||
path = resolve(path);
|
||||
helperObject.moduleName = path;
|
||||
}
|
||||
},
|
||||
'class-name': {
|
||||
_type: STRING,
|
||||
_targetProp: 'className'
|
||||
_set: function (helperObject, name, path) {
|
||||
path = resolve(path);
|
||||
helperObject.className = path;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -13,16 +13,17 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
var createError = require('raptor-util').createError;
|
||||
'use strict';
|
||||
var createError = require('raptor-util').createError;
|
||||
var INDENT = ' ';
|
||||
var stringify = require('raptor-json/stringify');
|
||||
var strings = require('raptor-strings');
|
||||
var StringBuilder = require('raptor-strings/StringBuilder');
|
||||
var Expression = require('./Expression');
|
||||
var forEach = raptor.forEach;
|
||||
var arrayFromArguments = require('raptor-util').arrayFromArguments;
|
||||
|
||||
function CodeWriter(indent) {
|
||||
this._indent = indent != null ? indent : INDENT + INDENT;
|
||||
this._code = strings.createStringBuilder();
|
||||
this._code = new StringBuilder();
|
||||
this.firstStatement = true;
|
||||
this._bufferedText = null;
|
||||
this._bufferedContextMethodCalls = null;
|
||||
@ -43,7 +44,7 @@ CodeWriter.prototype = {
|
||||
if (!this._bufferedContextMethodCalls) {
|
||||
this._bufferedContextMethodCalls = [];
|
||||
}
|
||||
args = require('raptor-arrays').arrayFromArguments(arguments, 1);
|
||||
args = arrayFromArguments(arguments, 1);
|
||||
this._bufferedContextMethodCalls.push([
|
||||
methodName,
|
||||
args
|
||||
@ -117,7 +118,7 @@ CodeWriter.prototype = {
|
||||
}
|
||||
this.firstStatement = false;
|
||||
this._bufferedContextMethodCalls = null;
|
||||
forEach(_bufferedContextMethodCalls, function (curWrite, i) {
|
||||
_bufferedContextMethodCalls.forEach(function (curWrite, i) {
|
||||
var methodName = curWrite[0];
|
||||
var args = curWrite[1];
|
||||
if (i === 0) {
|
||||
@ -278,7 +279,7 @@ TemplateBuilder.prototype = {
|
||||
}
|
||||
out.append(indent + 'var ');
|
||||
var declarations = [];
|
||||
forEach(vars, function (v, i) {
|
||||
vars.forEach(function (v, i) {
|
||||
declarations.push((i !== 0 ? indent + ' ' : '') + v.name + ' = ' + v.expression + (i === vars.length - 1 ? ';\n' : ',\n'));
|
||||
});
|
||||
out.append(declarations.join(''));
|
||||
@ -404,7 +405,7 @@ TemplateBuilder.prototype = {
|
||||
if (this.hasErrors()) {
|
||||
return '';
|
||||
}
|
||||
var out = strings.createStringBuilder();
|
||||
var out = new StringBuilder();
|
||||
var templateName = this.getTemplateName();
|
||||
if (!templateName) {
|
||||
this.addError('Template name not defined in template at path "' + this.getFilePath() + '"');
|
||||
@ -415,21 +416,18 @@ TemplateBuilder.prototype = {
|
||||
} else {
|
||||
params = ['context'];
|
||||
}
|
||||
out.append('$rset("rhtml", ');
|
||||
out.append(stringify(templateName));
|
||||
out.append(', ');
|
||||
out.append('function(helpers, templateInfo) {\n');
|
||||
out.append('function create(helpers) {\n');
|
||||
//Write out the static variables
|
||||
this.writer.flush();
|
||||
this._writeVars(this.staticVars, out, INDENT);
|
||||
out.append('\n' + INDENT + 'return function(data, context) {\n');
|
||||
out.append('\n' + INDENT + 'return function render(data, context) {\n');
|
||||
//Write out the render variables
|
||||
if (this.vars && this.vars.length) {
|
||||
this._writeVars(this.vars, out, INDENT + INDENT);
|
||||
out.append('\n');
|
||||
}
|
||||
out.append(this.writer.getOutput());
|
||||
out.append(INDENT + '}\n});');
|
||||
out.append(INDENT + '};\n}');
|
||||
return out.toString();
|
||||
},
|
||||
setTemplateName: function (templateName) {
|
||||
@ -13,38 +13,40 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
var createError = require('raptor-util').createError;
|
||||
'use strict';
|
||||
var createError = require('raptor-util').createError;
|
||||
var TemplateBuilder = require('./TemplateBuilder');
|
||||
var ParseTreeBuilder = require('./ParseTreeBuilder');
|
||||
var Expression = require('./Expression');
|
||||
var minifier = require.exists('raptor/js-minifier') ? require('raptor-js-minifier') : null;
|
||||
var TypeConverter = require('./TypeConverter');
|
||||
var logger = require('raptor-logging').logger(module);
|
||||
|
||||
function TemplateCompiler(taglibs, options) {
|
||||
this.taglibs = taglibs;
|
||||
this.options = options || {};
|
||||
this.workDir = this.options.workDir || require('raptor-templates/compiler').workDir || require('raptor-temp').workDir;
|
||||
this.errors = [];
|
||||
}
|
||||
|
||||
TemplateCompiler.prototype = {
|
||||
transformTree: function (rootNode, templateBuilder) {
|
||||
if (!templateBuilder) {
|
||||
throw createError(new Error('The templateBuilder argument is required'));
|
||||
}
|
||||
|
||||
var _this = this;
|
||||
|
||||
function transformTreeHelper(node) {
|
||||
try {
|
||||
this.taglibs.forEachNodeTransformer(node, function (transformer) {
|
||||
_this.taglibs.forEachNodeTransformer(node, function (transformer) {
|
||||
if (!node.isTransformerApplied(transformer)) {
|
||||
//Check to make sure a transformer of a certain type is only applied once to a node
|
||||
node.setTransformerApplied(transformer);
|
||||
//Mark the node as have been transformed by the current transformer
|
||||
this._transformerApplied = true;
|
||||
_this._transformerApplied = true;
|
||||
//Set the flag to indicate that a node was transformed
|
||||
node.compiler = this;
|
||||
transformer.getInstance().process(node, this, templateBuilder); //Have the transformer process the node (NOTE: Just because a node is being processed by the transformer doesn't mean that it has to modify the parse tree)
|
||||
node.compiler = _this;
|
||||
transformer.getInstance().process(node, _this, templateBuilder); //Have the transformer process the node (NOTE: Just because a node is being processed by the transformer doesn't mean that it has to modify the parse tree)
|
||||
}
|
||||
}, this);
|
||||
});
|
||||
} catch (e) {
|
||||
throw createError(new Error('Unable to compile template at path "' + templateBuilder.filePath + '. Error: ' + e.message), e);
|
||||
}
|
||||
@ -60,8 +62,8 @@ TemplateCompiler.prototype = {
|
||||
if (!childNode.parentNode) {
|
||||
return; //The child node might have been removed from the tree
|
||||
}
|
||||
transformTreeHelper.call(this, childNode);
|
||||
}, this);
|
||||
transformTreeHelper(childNode);
|
||||
});
|
||||
}
|
||||
/*
|
||||
* The tree is continuously transformed until we go through an entire pass where
|
||||
@ -71,10 +73,10 @@ TemplateCompiler.prototype = {
|
||||
do {
|
||||
this._transformerApplied = false;
|
||||
//Reset the flag to indicate that no transforms were yet applied to any of the nodes for this pass
|
||||
transformTreeHelper.call(this, rootNode); //Run the transforms on the tree
|
||||
transformTreeHelper(rootNode); //Run the transforms on the tree
|
||||
} while (this._transformerApplied);
|
||||
},
|
||||
compile: function (xmlSrc, resource, callback, thisObj) {
|
||||
compile: function (xmlSrc, filePath, callback, thisObj) {
|
||||
var _this = this;
|
||||
var rootNode;
|
||||
var templateBuilder;
|
||||
@ -88,24 +90,20 @@ TemplateCompiler.prototype = {
|
||||
error.errors = _this.getErrors();
|
||||
throw error;
|
||||
}
|
||||
var filePath;
|
||||
if (require('raptor-resources').isResource(resource)) {
|
||||
filePath = resource.getURL();
|
||||
} else if (typeof resource === 'string') {
|
||||
filePath = resource;
|
||||
}
|
||||
|
||||
try {
|
||||
/*
|
||||
* First build the parse tree for the tempate
|
||||
*/
|
||||
rootNode = ParseTreeBuilder.parse(xmlSrc, filePath, this.taglibs);
|
||||
//Build a parse tree from the input XML
|
||||
templateBuilder = new TemplateBuilder(this, resource, rootNode);
|
||||
templateBuilder = new TemplateBuilder(this, filePath, rootNode);
|
||||
//The templateBuilder object is need to manage the compiled JavaScript output
|
||||
this.transformTree(rootNode, templateBuilder);
|
||||
} catch (e) {
|
||||
throw createError(new Error('An error occurred while trying to compile template at path "' + filePath + '". Exception: ' + e), e);
|
||||
}
|
||||
|
||||
try {
|
||||
/*
|
||||
* The tree has been transformed and we can now generate
|
||||
@ -120,43 +118,20 @@ TemplateCompiler.prototype = {
|
||||
var output = templateBuilder.getOutput();
|
||||
//Get the compiled output from the template builder
|
||||
//console.error('COMPILED TEMPLATE (' + filePath + ')\n', '\n' + output, '\n------------------');
|
||||
if (minifier && this.options.minify === true) {
|
||||
output = minifier.minify(output);
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
callback.call(thisObj, {
|
||||
source: output,
|
||||
templateName: templateBuilder.getTemplateName()
|
||||
});
|
||||
}
|
||||
|
||||
var options = this.options;
|
||||
if (options && options.nameCallback) {
|
||||
options.nameCallback(templateBuilder.getTemplateName());
|
||||
}
|
||||
return output;
|
||||
},
|
||||
compileAndLoad: function (xmlSrc, resource) {
|
||||
var compiledSrc = this.compile(xmlSrc, resource, function (result) {
|
||||
//Get the compiled output for the template
|
||||
require('raptor-templates').unload(result.templateName); //Unload any existing template with the same name
|
||||
});
|
||||
try {
|
||||
//console.log('compileAndLoad: ' + (resource ? resource.getURL() : '(no resource') + ': ' + compiledSrc);
|
||||
this._eval(compiledSrc, resource); //Evaluate the compiled code and register the template
|
||||
} catch (e) {
|
||||
var filePath;
|
||||
if (typeof resource === 'string') {
|
||||
filePath = resource;
|
||||
} else if (require('raptor-resources').isResource(resource)) {
|
||||
filePath = resource.getURL();
|
||||
}
|
||||
logger.error('Unable to load compiled template: ' + compiledSrc, e);
|
||||
throw createError(new Error('Unable to load template at path "' + filePath + '". Exception: ' + e.message), e);
|
||||
}
|
||||
},
|
||||
_eval: function (compiledSrc, resource) {
|
||||
eval(compiledSrc);
|
||||
},
|
||||
isExpression: function (expression) {
|
||||
return expression instanceof Expression;
|
||||
},
|
||||
@ -13,9 +13,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
var createError = require('raptor-util').createError;
|
||||
'use strict';
|
||||
var escapeXml = require('raptor-xml/utils').escapeXml;
|
||||
var createError = require('raptor-util').createError;
|
||||
var escapeXml = require('raptor-xml/util').escapeXml;
|
||||
var EscapeXmlContext = require('./EscapeXmlContext');
|
||||
|
||||
var attrReplace = /[&<>\"\']/g;
|
||||
var replacements = {
|
||||
'<': '<',
|
||||
@ -30,7 +32,7 @@ function escapeXmlAttr(str) {
|
||||
});
|
||||
return;
|
||||
}
|
||||
var EscapeXmlContext = require('./EscapeXmlContext');
|
||||
|
||||
function TextNode(text, escapeXml) {
|
||||
TextNode.$super.call(this, 'text');
|
||||
if (text != null && typeof text !== 'string') {
|
||||
7
compiler/lib/expressions.js
Normal file
7
compiler/lib/expressions.js
Normal file
@ -0,0 +1,7 @@
|
||||
var ExpressionParser = require('./ExpressionParser');
|
||||
|
||||
function registerCustomExpressionHandler(name, func) {
|
||||
ExpressionParser.custom[name] = func;
|
||||
}
|
||||
|
||||
exports.registerCustomExpressionHandler = registerCustomExpressionHandler;
|
||||
@ -14,10 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
var TaglibCollection = require('./TaglibCollection');
|
||||
var taglibs = new TaglibCollection();
|
||||
var extend = require('raptor-util').extend;
|
||||
var ExpressionParser = require('./ExpressionParser');
|
||||
|
||||
var defaultOptions = {
|
||||
minify: false,
|
||||
preserveWhitespace: {
|
||||
@ -34,12 +32,9 @@ var defaultOptions = {
|
||||
'hr': true
|
||||
}
|
||||
};
|
||||
module.exports = {
|
||||
|
||||
extend(exports, {
|
||||
createCompiler: function (options) {
|
||||
if (this.discoverTaglibs) {
|
||||
//Only discover taglibs if that method is implemented
|
||||
this.discoverTaglibs(); //The discoverTaglibs method is implemented on the server so execute it now
|
||||
}
|
||||
var TemplateCompiler = require('./TemplateCompiler');
|
||||
//Get a reference to the TemplateCompiler class
|
||||
if (options) {
|
||||
@ -51,37 +46,28 @@ module.exports = {
|
||||
} else {
|
||||
options = defaultOptions; //Otherwise, no options were provided so use the default options
|
||||
}
|
||||
|
||||
var taglibs = require('./taglibs').getTaglibCollection();
|
||||
return new TemplateCompiler(taglibs, options);
|
||||
},
|
||||
compile: function (xmlSource, path, options) {
|
||||
return this.createCompiler(options).compile(xmlSource, path);
|
||||
|
||||
compile: function (src, path, options) {
|
||||
return this.createCompiler(options).compile(src, path);
|
||||
},
|
||||
compileAndLoad: function (xmlSource, path, options) {
|
||||
this.createCompiler(options).compileAndLoad(xmlSource, path);
|
||||
},
|
||||
loadTaglibXml: function (taglibXml, path) {
|
||||
var TaglibXmlLoader = require('./TaglibXmlLoader');
|
||||
var taglib = TaglibXmlLoader.load(taglibXml, path);
|
||||
this.addTaglib(taglib);
|
||||
return taglib;
|
||||
},
|
||||
addTaglib: function (taglib) {
|
||||
taglibs.add(taglib);
|
||||
},
|
||||
addTaglibAlias: function (uri, alias) {
|
||||
taglibs.addAlias(uri, alias);
|
||||
},
|
||||
clearTaglibs: function () {
|
||||
this.taglibs = taglibs = new TaglibCollection();
|
||||
},
|
||||
hasTaglib: function (uri) {
|
||||
return taglibs.isTaglib(uri);
|
||||
},
|
||||
registerCustomExpressionHandler: function (name, func) {
|
||||
ExpressionParser.custom[name] = func;
|
||||
},
|
||||
recordLoadedTaglib: function (taglibResource) {
|
||||
},
|
||||
defaultOptions: defaultOptions,
|
||||
taglibs: taglibs
|
||||
};
|
||||
|
||||
Node: require('./Node'),
|
||||
ElementNode: require('./ElementNode'),
|
||||
TextNode: require('./TextNode'),
|
||||
AttributeSplitter: require('./AttributeSplitter'),
|
||||
ExpressionParser: require('./ExpressionParser'),
|
||||
Expression: require('./Expression'),
|
||||
TypeConverter: require('./TypeConverter'),
|
||||
|
||||
defaultOptions: defaultOptions
|
||||
});
|
||||
|
||||
require('raptor-detect/runtime', {
|
||||
server: function() {
|
||||
require('./index_server');
|
||||
}
|
||||
});
|
||||
80
compiler/lib/index_server.js
Normal file
80
compiler/lib/index_server.js
Normal file
@ -0,0 +1,80 @@
|
||||
'use strict';
|
||||
var createError = require('raptor-util').createError;
|
||||
var compiler = require('./compiler');
|
||||
var resources = require('raptor-resources');
|
||||
var packaging = require('raptor-packaging');
|
||||
var discoveryComplete = false;
|
||||
var searchPathListenerHandler = null;
|
||||
var loadedTaglibPaths = {};
|
||||
|
||||
require('raptor-util').extend(compiler, {
|
||||
findAndLoadTaglib: function (uri) {
|
||||
var pathBuilders = [
|
||||
function (uri) {
|
||||
var path = uri;
|
||||
if (!path.endsWith('.rtld')) {
|
||||
path += '.rtld';
|
||||
}
|
||||
if (!path.startsWith('/')) {
|
||||
path = '/' + path;
|
||||
}
|
||||
return path;
|
||||
},
|
||||
function (uri) {
|
||||
var lastSlash = uri.lastIndexOf('/');
|
||||
var shortName = lastSlash === -1 ? uri : uri.substring(lastSlash + 1);
|
||||
path = uri + '/' + shortName;
|
||||
if (!path.endsWith('.rtld')) {
|
||||
path += '.rtld';
|
||||
}
|
||||
if (!path.startsWith('/')) {
|
||||
path = '/' + path;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
];
|
||||
for (var i = 0, len = pathBuilders.length; i < len; i++) {
|
||||
var pathBuilder = pathBuilders[i];
|
||||
var path = pathBuilder(uri);
|
||||
var taglibResource = require('raptor-resources').findResource(path);
|
||||
if (taglibResource && taglibResource.exists()) {
|
||||
var taglib = require('raptor-templates/compiler').loadTaglib(taglibResource);
|
||||
this.addTaglibAlias(taglib.uri, uri);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Last resort: see if the URI is associated with a module that registers
|
||||
// the taglibs...
|
||||
require('raptor-templates/compiler').loadModuleTaglibs(uri);
|
||||
},
|
||||
discoverTaglibs: function (force) {
|
||||
if (discoveryComplete && force !== true) {
|
||||
return;
|
||||
}
|
||||
discoveryComplete = true;
|
||||
this.clearTaglibs();
|
||||
loadedTaglibPaths = {};
|
||||
packaging.forEachTopLevelPackageManifest(this.loadPackageTaglibs, this);
|
||||
resources.forEach('/rtlds', function (rtldsResource) {
|
||||
if (rtldsResource.isDirectory()) {
|
||||
rtldsResource.forEachChild(function (rtldResource) {
|
||||
if (rtldResource.isFile() && rtldResource.getName().endsWith('.rtld')) {
|
||||
this.loadTaglib(rtldResource);
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
}, this);
|
||||
if (!searchPathListenerHandler) {
|
||||
searchPathListenerHandler = require('raptor-resources').getSearchPath().subscribe('modified', function () {
|
||||
discoveryComplete = false;
|
||||
this.discoverTaglibs(); //If the search path is modified then rediscover the taglibs
|
||||
}, this);
|
||||
}
|
||||
},
|
||||
loadTaglib: function (taglibResource) {
|
||||
this.recordLoadedTaglib(taglibResource);
|
||||
var xml = taglibResource.readAsString();
|
||||
return this.loadTaglibXml(xml, taglibResource);
|
||||
}
|
||||
|
||||
});
|
||||
36
compiler/lib/taglibs.js
Normal file
36
compiler/lib/taglibs.js
Normal file
@ -0,0 +1,36 @@
|
||||
var TaglibCollection = require('./TaglibCollection');
|
||||
var fs = require('fs');
|
||||
var nodePath = require('path');
|
||||
|
||||
exports.taglibs = new TaglibCollection();
|
||||
|
||||
function getTaglibCollection() {
|
||||
return exports.taglibs;
|
||||
}
|
||||
|
||||
function addTaglib(taglib) {
|
||||
getTaglibCollection().add(taglib);
|
||||
}
|
||||
|
||||
function hasTaglib(uri) {
|
||||
return getTaglibCollection().isTaglib(uri);
|
||||
}
|
||||
|
||||
function loadTaglibXml(taglibXml, path) {
|
||||
var TaglibXmlLoader = require('./TaglibXmlLoader');
|
||||
var taglib = TaglibXmlLoader.load(taglibXml, path);
|
||||
addTaglib(taglib);
|
||||
return taglib;
|
||||
}
|
||||
|
||||
function loadTaglibFromFile(path) {
|
||||
var src = fs.readFileSync(path, {encoding: 'utf8'});
|
||||
loadTaglibXml(src, path);
|
||||
}
|
||||
|
||||
loadTaglibFromFile(nodePath.join(__dirname, '../../taglibs/core/core.rtld'));
|
||||
|
||||
exports.addTaglib = addTaglib;
|
||||
exports.hasTaglib = hasTaglib;
|
||||
exports.loadTaglibXml = loadTaglibXml;
|
||||
exports.getTaglibCollection = getTaglibCollection;
|
||||
3
compiler/package.json
Normal file
3
compiler/package.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"main": "lib/index.js"
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
/Users/psteeleidem/development/github/raptorjs3/raptor-templates/test/test-project/simple.rhtml.actual.js
|
||||
@ -1,28 +0,0 @@
|
||||
var createError = require('raptor-util').createError;
|
||||
'use strict';
|
||||
var nodeRequire = require;
|
||||
var target = require('./TemplateCompiler');
|
||||
var vm = require('vm');
|
||||
require('raptor-util').extend(target, {
|
||||
_eval: function (compiledSrc, resource) {
|
||||
var filePath;
|
||||
if (resource) {
|
||||
if (typeof resource === 'string') {
|
||||
filePath = resource;
|
||||
} else if (require('raptor-resources').isResource(resource)) {
|
||||
filePath = resource.isFileResource() ? resource.getFilePath() : resource.getURL();
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (filePath && require('raptor-files').exists(filePath)) {
|
||||
//This is a hack, but line numbers for SyntaxErrors are getting lost if we don't use require
|
||||
delete nodeRequire.cache[filePath];
|
||||
nodeRequire(filePath);
|
||||
} else {
|
||||
vm.runInThisContext(compiledSrc, filePath || null);
|
||||
}
|
||||
} catch (e) {
|
||||
throw createError(new Error('Unable to load compile templated at path "' + filePath + '". Exception: ' + e), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -1,15 +0,0 @@
|
||||
'use strict';
|
||||
var target = require('./TemplateCompiler');
|
||||
require('raptor-util').extend(target, {
|
||||
_eval: function (compiledSrc, resource) {
|
||||
var filePath;
|
||||
if (resource) {
|
||||
if (typeof resource === 'string') {
|
||||
filePath = resource;
|
||||
} else if (require('raptor-resources').isResource(resource)) {
|
||||
filePath = resource.getURL();
|
||||
}
|
||||
}
|
||||
__rhinoHelpers.runtime.evaluateString(compiledSrc, filePath || null);
|
||||
}
|
||||
});
|
||||
@ -1,87 +0,0 @@
|
||||
var createError = require('raptor-util').createError;
|
||||
'use strict';
|
||||
var target = require('./TemplateCompiler');
|
||||
var File = require('raptor-files/File');
|
||||
var resources = require('raptor-resources');
|
||||
function optionsKey(options) {
|
||||
var key = JSON.stringify(options);
|
||||
var crypto = require('crypto');
|
||||
var shasum = crypto.createHash('sha1');
|
||||
shasum.update(key);
|
||||
var checksum = shasum.digest('hex');
|
||||
if (checksum.length > 5) {
|
||||
checksum = checksum.substring(0, 5);
|
||||
}
|
||||
require('raptor-util').extend(target, checksum);
|
||||
return;
|
||||
}
|
||||
var logger = require('raptor-logging').logger('raptor/templating/compiler/TemplateCompiler_server');
|
||||
require('raptor-util').extend(target, {
|
||||
_getOptionsKey: function () {
|
||||
if (!this._optionsKey) {
|
||||
this._optionsKey = optionsKey(this.options);
|
||||
}
|
||||
return this._optionsKey;
|
||||
},
|
||||
_getWorkFile: function (resource) {
|
||||
if (!this.workDir || !resource || !resource.isFileResource()) {
|
||||
return null;
|
||||
}
|
||||
var path = typeof resource === 'string' ? resource : resource.getPath();
|
||||
var workFile = new File(this.workDir, path + '.js');
|
||||
return workFile;
|
||||
},
|
||||
_compileResource: function (path) {
|
||||
var resource = resources.findResource(path);
|
||||
if (!resource.exists()) {
|
||||
throw createError(new Error('Unable to compile template with resource path "' + path + '". Resource not found'));
|
||||
}
|
||||
var compiledSource;
|
||||
var outputPath;
|
||||
var workFile;
|
||||
if (this.workDir) {
|
||||
workFile = this._getWorkFile(resource);
|
||||
}
|
||||
if (!workFile || !workFile.exists() || resource.lastModified() > workFile.lastModified()) {
|
||||
var xmlSource = resource.readAsString();
|
||||
compiledSource = this.compile(xmlSource, resource);
|
||||
if (workFile) {
|
||||
// If there is a work file then write out the compiled source so that we don't have to recompile again until the input resource is modified
|
||||
workFile.writeAsString(compiledSource);
|
||||
}
|
||||
} else {
|
||||
// The work file exists and it is up-to-date so we can use that to return the compiled source
|
||||
compiledSource = workFile.readAsString();
|
||||
}
|
||||
if (workFile) {
|
||||
outputPath = workFile.getAbsolutePath();
|
||||
} else {
|
||||
outputPath = resource.getURL() + '.js';
|
||||
}
|
||||
return {
|
||||
templateResource: resource,
|
||||
compiledSource: compiledSource,
|
||||
outputPath: outputPath,
|
||||
outputFile: workFile
|
||||
};
|
||||
},
|
||||
compileResource: function (path) {
|
||||
var compiledInfo = this._compileResource(path);
|
||||
return compiledInfo.compiledSource;
|
||||
},
|
||||
compileAndLoadResource: function (path) {
|
||||
var compiledInfo = this._compileResource(path);
|
||||
this._eval(compiledInfo.compiledSource, compiledInfo.outputPath);
|
||||
var resource = compiledInfo.templateResource;
|
||||
if (require('raptor-templates/compiler').isWatchingEnabled()) {
|
||||
resource.watch(function () {
|
||||
console.log('Template modified at path "' + resource.getURL() + '". Reloading template...');
|
||||
try {
|
||||
this.compileAndLoadResource(resource);
|
||||
} catch (e) {
|
||||
logger.warn('Unable to re-compile modified template at path "' + resource.getURL() + '". Exception: ' + e, e);
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 eBay Software Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* @extension Server
|
||||
*/
|
||||
'use strict';
|
||||
var compiler = require('raptor-templates/compiler');
|
||||
var discoveryComplete = false;
|
||||
require('raptor-util').extend(compiler, {
|
||||
discoverTaglibs: function () {
|
||||
if (discoveryComplete) {
|
||||
return;
|
||||
}
|
||||
discoveryComplete = true;
|
||||
var taglibPaths = $rget('rtld');
|
||||
raptor.forEach(taglibPaths, function (path) {
|
||||
var resource = require('raptor-resources').findResource(path);
|
||||
if (resource && resource.exists()) {
|
||||
this.loadTaglibXml(resource.readAsString(), resource.getPath());
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
});
|
||||
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 eBay Software Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* @extension Rhino
|
||||
*/
|
||||
'use strict';
|
||||
var compiler = require('raptor-templates/compiler');
|
||||
function convertJavaOptions(javaOptions) {
|
||||
var options = {};
|
||||
options.templateName = javaOptions.templateName;
|
||||
require('raptor-util').extend(compiler, options);
|
||||
return;
|
||||
}
|
||||
require('raptor-util').extend(compiler, {
|
||||
rhinoCompile: function (src, path, javaOptions) {
|
||||
return this.compile(src, path, convertJavaOptions(javaOptions));
|
||||
},
|
||||
rhinoCompileResource: function (path, javaOptions) {
|
||||
return this.compileResource(path, convertJavaOptions(javaOptions));
|
||||
},
|
||||
rhinoCompileAndLoadResource: function (path, javaOptions) {
|
||||
return this.compileAndLoadResource(path, convertJavaOptions(javaOptions));
|
||||
}
|
||||
});
|
||||
@ -1,230 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 eBay Software Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* @extension Server
|
||||
*/
|
||||
var createError = require('raptor-util').createError;
|
||||
'use strict';
|
||||
var compiler = require('raptor-templates/compiler');
|
||||
var logger = require('raptor-logging').logger('raptor/templating/compiler');
|
||||
var resources = require('raptor-resources');
|
||||
var packaging = require('raptor-packaging');
|
||||
var discoveryComplete = false;
|
||||
var searchPathListenerHandler = null;
|
||||
var watchingEnabled = false;
|
||||
var loadedTaglibPaths = {};
|
||||
var taglibsLastModified = null;
|
||||
Object.defineProperty(compiler, 'workDir', {
|
||||
get: function () {
|
||||
return this._workDir;
|
||||
},
|
||||
set: function (val) {
|
||||
this.setWorkDir(val);
|
||||
}
|
||||
});
|
||||
require('raptor-util').extend(compiler, {
|
||||
enableWatching: function () {
|
||||
watchingEnabled = true;
|
||||
},
|
||||
disableWatching: function () {
|
||||
watchingEnabled = false;
|
||||
},
|
||||
isWatchingEnabled: function () {
|
||||
return watchingEnabled;
|
||||
},
|
||||
setWatchingEnabled: function (enabled) {
|
||||
watchingEnabled = enabled;
|
||||
},
|
||||
compileAndLoadResource: function (path, options) {
|
||||
this.createCompiler(options).compileAndLoadResource(path);
|
||||
},
|
||||
compileResource: function (path, options) {
|
||||
return this.createCompiler(options).compileResource(path);
|
||||
},
|
||||
loadModuleTaglibs: function (moduleName) {
|
||||
var manifest = require('raptor-packaging').getModuleManifest(moduleName);
|
||||
if (manifest) {
|
||||
this.loadPackageTaglibs(manifest);
|
||||
}
|
||||
},
|
||||
loadPackageTaglibs: function (manifest) {
|
||||
var taglibs = manifest.getRaptorProp('taglibs');
|
||||
if (taglibs) {
|
||||
raptor.forEach(taglibs, function (rtldPath) {
|
||||
var key = manifest.getURL() + ':' + rtldPath;
|
||||
if (!loadedTaglibPaths[key]) {
|
||||
loadedTaglibPaths[key] = true;
|
||||
var rtldResource = manifest.resolveResource(rtldPath);
|
||||
if (!rtldResource || !rtldResource.exists()) {
|
||||
throw createError(new Error('Raptor TLD "' + rtldPath + '" not found for manifest "' + manifest.getURL() + '"'));
|
||||
}
|
||||
this.loadTaglib(rtldResource);
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
},
|
||||
findAndLoadTaglib: function (uri) {
|
||||
var pathBuilders = [
|
||||
function (uri) {
|
||||
var path = uri;
|
||||
if (!path.endsWith('.rtld')) {
|
||||
path += '.rtld';
|
||||
}
|
||||
if (!path.startsWith('/')) {
|
||||
path = '/' + path;
|
||||
}
|
||||
return path;
|
||||
},
|
||||
function (uri) {
|
||||
var lastSlash = uri.lastIndexOf('/');
|
||||
var shortName = lastSlash === -1 ? uri : uri.substring(lastSlash + 1);
|
||||
path = uri + '/' + shortName;
|
||||
if (!path.endsWith('.rtld')) {
|
||||
path += '.rtld';
|
||||
}
|
||||
if (!path.startsWith('/')) {
|
||||
path = '/' + path;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
];
|
||||
for (var i = 0, len = pathBuilders.length; i < len; i++) {
|
||||
var pathBuilder = pathBuilders[i];
|
||||
var path = pathBuilder(uri);
|
||||
var taglibResource = require('raptor-resources').findResource(path);
|
||||
if (taglibResource && taglibResource.exists()) {
|
||||
var taglib = require('raptor-templates/compiler').loadTaglib(taglibResource);
|
||||
this.addTaglibAlias(taglib.uri, uri);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Last resort: see if the URI is associated with a module that registers
|
||||
// the taglibs...
|
||||
require('raptor-templates/compiler').loadModuleTaglibs(uri);
|
||||
},
|
||||
discoverTaglibs: function (force) {
|
||||
if (discoveryComplete && force !== true) {
|
||||
return;
|
||||
}
|
||||
discoveryComplete = true;
|
||||
this.clearTaglibs();
|
||||
loadedTaglibPaths = {};
|
||||
packaging.forEachTopLevelPackageManifest(this.loadPackageTaglibs, this);
|
||||
resources.forEach('/rtlds', function (rtldsResource) {
|
||||
if (rtldsResource.isDirectory()) {
|
||||
rtldsResource.forEachChild(function (rtldResource) {
|
||||
if (rtldResource.isFile() && rtldResource.getName().endsWith('.rtld')) {
|
||||
this.loadTaglib(rtldResource);
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
}, this);
|
||||
if (!searchPathListenerHandler) {
|
||||
searchPathListenerHandler = require('raptor-resources').getSearchPath().subscribe('modified', function () {
|
||||
discoveryComplete = false;
|
||||
this.discoverTaglibs(); //If the search path is modified then rediscover the taglibs
|
||||
}, this);
|
||||
}
|
||||
},
|
||||
loadTaglib: function (taglibResource) {
|
||||
this.recordLoadedTaglib(taglibResource);
|
||||
var xml = taglibResource.readAsString();
|
||||
return this.loadTaglibXml(xml, taglibResource);
|
||||
},
|
||||
recordLoadedTaglib: function (taglibResource) {
|
||||
var workDir = this.getWorkDir();
|
||||
if (workDir) {
|
||||
var taglibsLastModified = this._readTaglibsLastModified(workDir);
|
||||
taglibsLastModified.lastModified = Math.max(taglibResource.lastModified(), taglibsLastModified.lastModified || 0);
|
||||
taglibsLastModified.urls[taglibResource.getURL()] = true;
|
||||
var newStr = taglibsLastModified.lastModified + '\n' + Object.keys(taglibsLastModified.urls).join('\n');
|
||||
if (newStr != taglibsLastModified.written) {
|
||||
taglibsLastModified.written = newStr;
|
||||
this._taglibsWorkFile.writeAsString(newStr);
|
||||
}
|
||||
}
|
||||
},
|
||||
_readTaglibsLastModified: function (workDir) {
|
||||
var taglibsWorkFile = this._taglibsWorkFile;
|
||||
if (taglibsLastModified == null) {
|
||||
taglibsLastModified = {
|
||||
lastModified: null,
|
||||
urls: {},
|
||||
written: null
|
||||
};
|
||||
if (taglibsWorkFile.exists()) {
|
||||
try {
|
||||
taglibsLastModified.str = taglibsWorkFile.readAsString();
|
||||
var lastModifiedEnd = taglibsLastModified.str.indexOf('\n');
|
||||
taglibsLastModified.lastModified = parseInt(taglibsLastModified.str.substring(0, lastModifiedEnd), 10);
|
||||
taglibsLastModified.str.substring(lastModifiedEnd + 1).split('\n').forEach(function (url) {
|
||||
taglibsLastModified.urls[url] = true;
|
||||
});
|
||||
} catch (e) {
|
||||
logger.warn('Unable to read "' + taglibsWorkFile.getAbsolutePath() + '". Exception: ' + e, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return taglibsLastModified;
|
||||
},
|
||||
_validateWorkDir: function (workDir) {
|
||||
if (!workDir) {
|
||||
return;
|
||||
}
|
||||
logger.debug('Validating work directory at path "' + workDir + '"...');
|
||||
var taglibsLastModified = this._readTaglibsLastModified(workDir);
|
||||
function isUpToDate() {
|
||||
var lastModified = taglibsLastModified.lastModified;
|
||||
if (lastModified == null) {
|
||||
return true;
|
||||
}
|
||||
var files = require('raptor-files');
|
||||
var urls = Object.keys(taglibsLastModified.urls);
|
||||
for (var i = 0, len = urls.length; i < len; i++) {
|
||||
var url = urls[i];
|
||||
if (url.startsWith('file://')) {
|
||||
var taglibFile = files.fromFileUrl(url);
|
||||
if (!taglibFile.exists() || taglibFile.lastModified() > lastModified) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (!isUpToDate()) {
|
||||
console.log('One ore more taglibs modified. Removing compiled templates work directory at path "' + workDir.getAbsolutePath() + '"...');
|
||||
workDir.remove();
|
||||
}
|
||||
},
|
||||
setWorkDir: function (workDir) {
|
||||
if (workDir) {
|
||||
logger.debug('Setting work directory to "' + workDir + '"...');
|
||||
var File = require('raptor-files/File');
|
||||
if (typeof workDir === 'string') {
|
||||
workDir = new File(workDir);
|
||||
}
|
||||
this._workDir = workDir;
|
||||
this._taglibsWorkFile = new File(this._workDir, 'taglibs.txt');
|
||||
this._validateWorkDir(workDir);
|
||||
} else {
|
||||
this._workDir = null;
|
||||
this._taglibsWorkFile = null;
|
||||
}
|
||||
},
|
||||
getWorkDir: function () {
|
||||
return this._workDir;
|
||||
}
|
||||
});
|
||||
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 eBay Software Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
*
|
||||
* @extension Rhino
|
||||
*
|
||||
*/
|
||||
'use strict';
|
||||
var createError = require('raptor-util').createError;
|
||||
|
||||
function WrappedWriter(javaWriter) {
|
||||
this.javaWriter = javaWriter;
|
||||
this.write = function (o) {
|
||||
if (o != null) {
|
||||
this.javaWriter.write(o.toString());
|
||||
}
|
||||
};
|
||||
}
|
||||
require('raptor-util').extend(require('raptor-templates'), {
|
||||
rhinoRender: function (templateName, data, context) {
|
||||
if (data && typeof data === 'string') {
|
||||
try {
|
||||
data = eval('(' + data + ')'); //Convert the JSON string to a native JavaScript object
|
||||
} catch (e) {
|
||||
throw createError('Invalid JSON data passed to "' + templateName + '". Exception: ' + e, e);
|
||||
}
|
||||
}
|
||||
this.render('' + templateName, data, context);
|
||||
},
|
||||
rhinoCreateContext: function (javaWriter) {
|
||||
var context = this.createContext(new WrappedWriter(javaWriter));
|
||||
//Wrap the Java writer with a JavaScript object
|
||||
return context;
|
||||
}
|
||||
});
|
||||
@ -18,6 +18,7 @@
|
||||
"author": "Patrick Steele-Idem <psteeleidem@ebay.com>",
|
||||
"maintainers": ["Patrick Steele-Idem <psteeleidem@ebay.com>"],
|
||||
"dependencies": {
|
||||
"raptor-detect": "~0.1.0-SNAPSHOT",
|
||||
"raptor-logging": "~0.1.0-SNAPSHOT",
|
||||
"raptor-strings": "~0.1.0-SNAPSHOT",
|
||||
"raptor-regexp" : "~0.1.0-SNAPSHOT",
|
||||
|
||||
@ -119,8 +119,8 @@ var helpers = {
|
||||
}
|
||||
};
|
||||
templating = {
|
||||
templateFunc: function (templateName) {
|
||||
var templateFunc = loadedTemplates[templateName];
|
||||
templateFunc: function (templatePath) {
|
||||
var templateFunc = loadedTemplates[templatePath];
|
||||
//Look for the template function in the loaded templates lookup
|
||||
if (!templateFunc) {
|
||||
//See if the template has already been loaded
|
||||
@ -129,58 +129,58 @@ templating = {
|
||||
* then it means that the template has not been fully loaded and initialized.
|
||||
* Therefore, check if the template has been registerd with the name provided
|
||||
*/
|
||||
templateFunc = getRegisteredTemplate(templateName);
|
||||
templateFunc = getRegisteredTemplate(templatePath);
|
||||
if (!templateFunc && this.findTemplate) {
|
||||
this.findTemplate(templateName);
|
||||
templateFunc = getRegisteredTemplate(templateName);
|
||||
this.findTemplate(templatePath);
|
||||
templateFunc = getRegisteredTemplate(templatePath);
|
||||
}
|
||||
if (templateFunc) {
|
||||
var templateInfo = this.getTemplateInfo(templateName);
|
||||
var templateInfo = this.getTemplateInfo(templatePath);
|
||||
templateFunc = templateFunc(helpers, templateInfo); //Invoke the factory function to get back the rendering function
|
||||
}
|
||||
if (!templateFunc) {
|
||||
throw createError(new Error('Template not found with name "' + templateName + '"'));
|
||||
throw createError(new Error('Template not found with name "' + templatePath + '"'));
|
||||
}
|
||||
loadedTemplates[templateName] = templateFunc; //Store the template rendering function in the lookup
|
||||
loadedTemplates[templatePath] = templateFunc; //Store the template rendering function in the lookup
|
||||
}
|
||||
return templateFunc;
|
||||
},
|
||||
getTemplateInfo: function (templateName) {
|
||||
return { name: templateName };
|
||||
getTemplateInfo: function (templatePath) {
|
||||
return { name: templatePath };
|
||||
},
|
||||
render: function (templateName, data, context) {
|
||||
render: function (templatePath, data, context) {
|
||||
if (!context) {
|
||||
throw createError(new Error('Context is required'));
|
||||
}
|
||||
var templateFunc = this.templateFunc(templateName);
|
||||
var templateFunc = this.templateFunc(templatePath);
|
||||
try {
|
||||
templateFunc(data || {}, context); //Invoke the template rendering function with the required arguments
|
||||
} catch (e) {
|
||||
throw createError(new Error('Unable to render template with name "' + templateName + '". Exception: ' + e), e);
|
||||
throw createError(new Error('Unable to render template with name "' + templatePath + '". Exception: ' + e), e);
|
||||
}
|
||||
},
|
||||
renderToString: function (templateName, data, context) {
|
||||
renderToString: function (templatePath, data, context) {
|
||||
var sb = new StringBuilder();
|
||||
//Create a StringBuilder object to serve as a buffer for the output
|
||||
if (context === undefined) {
|
||||
/*
|
||||
* If a context object is not provided then we need to create a new context object and use the StringBuilder as the writer
|
||||
*/
|
||||
this.render(templateName, data, new Context(sb));
|
||||
this.render(templatePath, data, new Context(sb));
|
||||
} else {
|
||||
var _this = this;
|
||||
/*
|
||||
* If a context is provided then we need to temporarily swap out the writer for the StringBuilder
|
||||
*/
|
||||
context.swapWriter(sb, function () {
|
||||
_this.render(templateName, data, context);
|
||||
_this.render(templatePath, data, context);
|
||||
}); //Swap in the writer, render the template and then restore the original writer
|
||||
}
|
||||
return sb.toString(); //Return the final string associated with the StringBuilder
|
||||
},
|
||||
unload: function (templateName) {
|
||||
delete loadedTemplates[templateName];
|
||||
$rset('rhtml', templateName, undefined);
|
||||
unload: function (templatePath) {
|
||||
delete loadedTemplates[templatePath];
|
||||
$rset('rhtml', templatePath, undefined);
|
||||
},
|
||||
getFunction: _getFunction,
|
||||
createContext: renderContext.createContext,
|
||||
@ -23,8 +23,9 @@ var strings = require('raptor-strings');
|
||||
var resources = require('raptor-resources');
|
||||
var File = require('raptor-files/File');
|
||||
var templateInfoByName = {};
|
||||
var logger = require('raptor-logging').logger('raptor/templating_server');
|
||||
require('raptor-util').extend(require('raptor-templates'), {
|
||||
var createError = require('raptor-util').createError;
|
||||
var logger = require('raptor-logging').logger(module);
|
||||
require('raptor-util').extend(require('./index'), {
|
||||
findTemplate: function (name) {
|
||||
var path = name;
|
||||
var resource;
|
||||
@ -86,5 +87,47 @@ require('raptor-util').extend(require('raptor-templates'), {
|
||||
}, function (e) {
|
||||
logger.error(e);
|
||||
});
|
||||
},
|
||||
_getWorkFile: function (resource) {
|
||||
if (!this.workDir || !resource || !resource.isFileResource()) {
|
||||
return null;
|
||||
}
|
||||
var path = typeof resource === 'string' ? resource : resource.getPath();
|
||||
var workFile = new File(this.workDir, path + '.js');
|
||||
return workFile;
|
||||
},
|
||||
_compileResource: function (path) {
|
||||
var resource = resources.findResource(path);
|
||||
if (!resource.exists()) {
|
||||
throw createError(new Error('Unable to compile template with resource path "' + path + '". Resource not found'));
|
||||
}
|
||||
var compiledSource;
|
||||
var outputPath;
|
||||
var workFile;
|
||||
if (this.workDir) {
|
||||
workFile = this._getWorkFile(resource);
|
||||
}
|
||||
if (!workFile || !workFile.exists() || resource.lastModified() > workFile.lastModified()) {
|
||||
var xmlSource = resource.readAsString();
|
||||
compiledSource = this.compile(xmlSource, resource);
|
||||
if (workFile) {
|
||||
// If there is a work file then write out the compiled source so that we don't have to recompile again until the input resource is modified
|
||||
workFile.writeAsString(compiledSource);
|
||||
}
|
||||
} else {
|
||||
// The work file exists and it is up-to-date so we can use that to return the compiled source
|
||||
compiledSource = workFile.readAsString();
|
||||
}
|
||||
if (workFile) {
|
||||
outputPath = workFile.getAbsolutePath();
|
||||
} else {
|
||||
outputPath = resource.getURL() + '.js';
|
||||
}
|
||||
return {
|
||||
templateResource: resource,
|
||||
compiledSource: compiledSource,
|
||||
outputPath: outputPath,
|
||||
outputFile: workFile
|
||||
};
|
||||
}
|
||||
});
|
||||
99
runtime/lib/work-dir.js
Normal file
99
runtime/lib/work-dir.js
Normal file
@ -0,0 +1,99 @@
|
||||
exports.workDir = null;
|
||||
|
||||
var logger = require('raptor-logging').logger(module);
|
||||
var taglibsWorkFile = null;
|
||||
var taglibsLastModified = null;
|
||||
|
||||
function getWorkDir() {
|
||||
return exports.workDir;
|
||||
}
|
||||
|
||||
function _readTaglibsLastModified(workDir) {
|
||||
var taglibsWorkFile = taglibsWorkFile;
|
||||
if (taglibsLastModified == null) {
|
||||
taglibsLastModified = {
|
||||
lastModified: null,
|
||||
urls: {},
|
||||
written: null
|
||||
};
|
||||
if (taglibsWorkFile.exists()) {
|
||||
try {
|
||||
taglibsLastModified.str = taglibsWorkFile.readAsString();
|
||||
var lastModifiedEnd = taglibsLastModified.str.indexOf('\n');
|
||||
taglibsLastModified.lastModified = parseInt(taglibsLastModified.str.substring(0, lastModifiedEnd), 10);
|
||||
taglibsLastModified.str.substring(lastModifiedEnd + 1).split('\n').forEach(function (url) {
|
||||
taglibsLastModified.urls[url] = true;
|
||||
});
|
||||
} catch (e) {
|
||||
logger.warn('Unable to read "' + taglibsWorkFile.getAbsolutePath() + '". Exception: ' + e, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return taglibsLastModified;
|
||||
}
|
||||
|
||||
function recordLoadedTaglib(taglibResource) {
|
||||
var workDir = getWorkDir();
|
||||
if (workDir) {
|
||||
var taglibsLastModified = _readTaglibsLastModified(workDir);
|
||||
taglibsLastModified.lastModified = Math.max(taglibResource.lastModified(), taglibsLastModified.lastModified || 0);
|
||||
taglibsLastModified.urls[taglibResource.getURL()] = true;
|
||||
var newStr = taglibsLastModified.lastModified + '\n' + Object.keys(taglibsLastModified.urls).join('\n');
|
||||
if (newStr != taglibsLastModified.written) {
|
||||
taglibsLastModified.written = newStr;
|
||||
taglibsWorkFile.writeAsString(newStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _validateWorkDir(workDir) {
|
||||
if (!workDir) {
|
||||
return;
|
||||
}
|
||||
logger.debug('Validating work directory at path "' + workDir + '"...');
|
||||
var taglibsLastModified = _readTaglibsLastModified(workDir);
|
||||
function isUpToDate() {
|
||||
var lastModified = taglibsLastModified.lastModified;
|
||||
if (lastModified == null) {
|
||||
return true;
|
||||
}
|
||||
var files = require('raptor-files');
|
||||
var urls = Object.keys(taglibsLastModified.urls);
|
||||
for (var i = 0, len = urls.length; i < len; i++) {
|
||||
var url = urls[i];
|
||||
if (url.startsWith('file://')) {
|
||||
var taglibFile = files.fromFileUrl(url);
|
||||
if (!taglibFile.exists() || taglibFile.lastModified() > lastModified) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (!isUpToDate()) {
|
||||
console.log('One ore more taglibs modified. Removing compiled templates work directory at path "' + workDir.getAbsolutePath() + '"...');
|
||||
workDir.remove();
|
||||
}
|
||||
}
|
||||
|
||||
function setWorkDir(workDir) {
|
||||
exports.workDir = _workDir;
|
||||
|
||||
if (workDir) {
|
||||
logger.debug('Setting work directory to "' + workDir + '"...');
|
||||
var File = require('raptor-files/File');
|
||||
if (typeof workDir === 'string') {
|
||||
workDir = new File(workDir);
|
||||
}
|
||||
|
||||
taglibsWorkFile = new File(workDir, 'taglibs.txt');
|
||||
_validateWorkDir(workDir);
|
||||
} else {
|
||||
workDir = null;
|
||||
taglibsWorkFile = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
exports.recordLoadedTaglib = recordLoadedTaglib;
|
||||
exports.setWorkDir = setWorkDir;
|
||||
@ -39,5 +39,5 @@ AssignNode.prototype = {
|
||||
}
|
||||
}
|
||||
};
|
||||
require('raptor-util').inherit(AssignNode, require('../../compiler/Node'));
|
||||
require('raptor-util').inherit(AssignNode, require('../../compiler').Node);
|
||||
module.exports = AssignNode;
|
||||
@ -61,5 +61,5 @@ ChooseNode.prototype = {
|
||||
}
|
||||
}
|
||||
};
|
||||
require('raptor-util').inherit(ChooseNode, require('../../compiler/Node'));
|
||||
require('raptor-util').inherit(ChooseNode, require('../../compiler').Node);
|
||||
module.exports = ChooseNode;
|
||||
@ -19,6 +19,7 @@ function removeDashes(str) {
|
||||
return lower.toUpperCase();
|
||||
});
|
||||
}
|
||||
var extend = require('raptor-util').extend;
|
||||
var coreNS = 'http://raptorjs.org/templates/core';
|
||||
var WriteNode = require('./WriteNode');
|
||||
var ForNode = require('./ForNode');
|
||||
@ -30,15 +31,19 @@ var WhenNode = require('./WhenNode');
|
||||
var OtherwiseNode = require('./OtherwiseNode');
|
||||
var TagHandlerNode = require('./TagHandlerNode');
|
||||
var IncludeNode = require('./IncludeNode');
|
||||
var Expression = require('../../compiler/Expression');
|
||||
var AttributeSplitter = require('../../compiler/AttributeSplitter');
|
||||
var TypeConverter = require('../../compiler/TypeConverter');
|
||||
var Expression = require('../../compiler').Expression;
|
||||
var AttributeSplitter = require('../../compiler').AttributeSplitter;
|
||||
var TypeConverter = require('../../compiler').TypeConverter;
|
||||
|
||||
function getPropValue(value, type, allowExpressions) {
|
||||
module.exports = TypeConverter.convert(value, type, allowExpressions);
|
||||
return;
|
||||
return TypeConverter.convert(value, type, allowExpressions);
|
||||
}
|
||||
|
||||
function CoreTagTransformer() {
|
||||
}
|
||||
|
||||
CoreTagTransformer.id = 'core/CoreTagTransformer';
|
||||
|
||||
CoreTagTransformer.prototype = {
|
||||
process: function (node, compiler, template) {
|
||||
//Find and handle nested <c:attrs> elements
|
||||
@ -102,7 +107,8 @@ CoreTagTransformer.prototype = {
|
||||
propName = attr.localName;
|
||||
}
|
||||
callback.call(thisObj, attrUri, propName, value, prefix, attrDef);
|
||||
}, this);
|
||||
});
|
||||
|
||||
tag.forEachStaticProperty(function (staticProp) {
|
||||
var value = getPropValue(staticProp.value, staticProp.type, false);
|
||||
callback.call(thisObj, '', staticProp.name, value, '', staticProp);
|
||||
@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
var ExpressionParser = require('../../compiler/ExpressionParser');
|
||||
var TextNode = require('../../compiler/TextNode');
|
||||
var ExpressionParser = require('../../compiler').ExpressionParser;
|
||||
var TextNode = require('../../compiler').TextNode;
|
||||
var WriteNode = require('./WriteNode');
|
||||
var ScriptletNode = require('./ScriptletNode');
|
||||
function CoreTextTransformer() {
|
||||
@ -55,5 +55,5 @@ DefNode.prototype = {
|
||||
}, this).line('}');
|
||||
}
|
||||
};
|
||||
require('raptor-util').inherit(DefNode, require('../../compiler/Node'));
|
||||
require('raptor-util').inherit(DefNode, require('../../compiler').Node);
|
||||
module.exports = DefNode;
|
||||
@ -32,5 +32,5 @@ ElseIfNode.prototype = {
|
||||
}, this).line('}');
|
||||
}
|
||||
};
|
||||
require('raptor-util').inherit(ElseIfNode, require('../../compiler/ElementNode'));
|
||||
require('raptor-util').inherit(ElseIfNode, require('../../compiler').ElementNode);
|
||||
module.exports = ElseIfNode;
|
||||
@ -30,5 +30,5 @@ ElseNode.prototype = {
|
||||
}, this).line('}');
|
||||
}
|
||||
};
|
||||
require('raptor-util').inherit(ElseNode, require('../../compiler/ElementNode'));
|
||||
require('raptor-util').inherit(ElseNode, require('../../compiler').ElementNode);
|
||||
module.exports = ElseNode;
|
||||
@ -20,28 +20,21 @@ var stringify = require('raptor-json/stringify').stringify;
|
||||
function parseForEach(value) {
|
||||
var match = value.match(forEachRegEx);
|
||||
if (match) {
|
||||
function ForNode() {
|
||||
}
|
||||
ForNode.prototype = {
|
||||
return {
|
||||
'var': match[1],
|
||||
'in': match[2]
|
||||
};
|
||||
module.exports = ForNode;
|
||||
return;
|
||||
} else {
|
||||
match = value.match(forEachPropRegEx);
|
||||
if (!match) {
|
||||
throw new Error('Invalid each attribute of "' + value + '"');
|
||||
}
|
||||
function ForNode() {
|
||||
}
|
||||
ForNode.prototype = {
|
||||
|
||||
return {
|
||||
'nameVar': match[1],
|
||||
'valueVar': match[2],
|
||||
'in': match[3]
|
||||
};
|
||||
module.exports = ForNode;
|
||||
return;
|
||||
}
|
||||
}
|
||||
function ForNode(props) {
|
||||
@ -146,5 +139,5 @@ ForNode.prototype = {
|
||||
}
|
||||
}
|
||||
};
|
||||
require('raptor-util').inherit(ForNode, require('../../compiler/Node'));
|
||||
require('raptor-util').inherit(ForNode, require('../../compiler').Node);
|
||||
module.exports = ForNode;
|
||||
@ -31,5 +31,5 @@ IfNode.prototype = {
|
||||
}, this).line('}');
|
||||
}
|
||||
};
|
||||
require('raptor-util').inherit(IfNode, require('../../compiler/Node'));
|
||||
require('raptor-util').inherit(IfNode, require('../../compiler').Node);
|
||||
module.exports = IfNode;
|
||||
@ -70,5 +70,5 @@ IncludeNode.prototype = {
|
||||
}
|
||||
}
|
||||
};
|
||||
require('raptor-util').inherit(IncludeNode, require('../../compiler/Node'));
|
||||
require('raptor-util').inherit(IncludeNode, require('../../compiler').Node);
|
||||
module.exports = IncludeNode;
|
||||
@ -94,5 +94,5 @@ InvokeNode.prototype = {
|
||||
}
|
||||
}
|
||||
};
|
||||
require('raptor-util').inherit(InvokeNode, require('../../compiler/Node'));
|
||||
require('raptor-util').inherit(InvokeNode, require('../../compiler').Node);
|
||||
module.exports = InvokeNode;
|
||||
@ -30,5 +30,5 @@ OtherwiseNode.prototype = {
|
||||
return '<c:otherwise>';
|
||||
}
|
||||
};
|
||||
require('raptor-util').inherit(OtherwiseNode, require('../../compiler/Node'));
|
||||
require('raptor-util').inherit(OtherwiseNode, require('../../compiler').Node);
|
||||
module.exports = OtherwiseNode;
|
||||
@ -28,5 +28,5 @@ ScriptletNode.prototype = {
|
||||
return '{%' + this.code + '%}';
|
||||
}
|
||||
};
|
||||
require('raptor-util').inherit(ScriptletNode, require('../../compiler/Node'));
|
||||
require('raptor-util').inherit(ScriptletNode, require('../../compiler').Node);
|
||||
module.exports = ScriptletNode;
|
||||
@ -15,9 +15,10 @@
|
||||
*/
|
||||
'use strict';
|
||||
var objects = require('raptor-objects');
|
||||
var forEach = raptor.forEach;
|
||||
var extend = require('raptor-util').extend;
|
||||
var forEachEntry = require('raptor-util').forEachEntry;
|
||||
var stringify = require('raptor-json/stringify');
|
||||
var Expression = require('../../compiler/Expression');
|
||||
var Expression = require('../../compiler').Expression;
|
||||
function addHandlerVar(template, handlerClass) {
|
||||
var handlerVars = template._handlerVars || (template._handlerVars = {});
|
||||
var handlerVar = handlerVars[handlerClass];
|
||||
@ -144,7 +145,7 @@ TagHandlerNode.prototype = {
|
||||
}
|
||||
if (_this.hasChildren()) {
|
||||
var bodyParams = [];
|
||||
forEach(variableNames, function (varName) {
|
||||
variableNames.forEach(function (varName) {
|
||||
bodyParams.push(varName);
|
||||
});
|
||||
template.code(',\n').line('function(' + bodyParams.join(',') + ') {').indent(function () {
|
||||
@ -183,5 +184,5 @@ TagHandlerNode.prototype = {
|
||||
}
|
||||
}
|
||||
};
|
||||
require('raptor-util').inherit(TagHandlerNode, require('../../compiler/Node'));
|
||||
require('raptor-util').inherit(TagHandlerNode, require('../../compiler').Node);
|
||||
module.exports = TagHandlerNode;
|
||||
@ -14,7 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
var forEach = raptor.forEach;
|
||||
function TemplateNode(props) {
|
||||
TemplateNode.$super.call(this);
|
||||
if (props) {
|
||||
@ -23,11 +22,10 @@ function TemplateNode(props) {
|
||||
}
|
||||
TemplateNode.prototype = {
|
||||
doGenerateCode: function (template) {
|
||||
var name = this.getProperty('name');
|
||||
var params = this.getProperty('params');
|
||||
if (params) {
|
||||
params = params.split(/(?:\s*,\s*)|(?:\s+)/g);
|
||||
forEach(params, function (param) {
|
||||
params.forEach(function (param) {
|
||||
param = param.trim();
|
||||
if (param.length) {
|
||||
template.addVar(param, 'data.' + param);
|
||||
@ -41,7 +39,7 @@ TemplateNode.prototype = {
|
||||
uri = this.uri;
|
||||
}
|
||||
if (name === 'functions' || name === 'importFunctions' || name === 'importHelperFunctions') {
|
||||
forEach(value.split(/\s*[,;]\s*/g), function (funcName) {
|
||||
value.split(/\s*[,;]\s*/g).forEach(function (funcName) {
|
||||
var func = template.compiler.taglibs.getFunction(uri, funcName);
|
||||
if (!func) {
|
||||
this.addError('Function with name "' + funcName + '" not found in taglib "' + uri + '"');
|
||||
@ -67,13 +65,9 @@ TemplateNode.prototype = {
|
||||
}
|
||||
}
|
||||
}, this);
|
||||
if (name) {
|
||||
template.setTemplateName(name);
|
||||
} else if (!template.getTemplateName()) {
|
||||
this.addError('The "name" attribute is required for the ' + this.toString() + ' tag or it must be passed in as a compiler option.');
|
||||
}
|
||||
|
||||
this.generateCodeForChildren(template);
|
||||
}
|
||||
};
|
||||
require('raptor-util').inherit(TemplateNode, require('../../compiler/Node'));
|
||||
require('raptor-util').inherit(TemplateNode, require('../../compiler').Node);
|
||||
module.exports = TemplateNode;
|
||||
@ -36,5 +36,5 @@ VarNode.prototype = {
|
||||
}
|
||||
}
|
||||
};
|
||||
require('raptor-util').inherit(VarNode, require('../../compiler/Node'));
|
||||
require('raptor-util').inherit(VarNode, require('../../compiler').Node);
|
||||
module.exports = VarNode;
|
||||
@ -37,5 +37,5 @@ WhenNode.prototype = {
|
||||
}, this).line('}');
|
||||
}
|
||||
};
|
||||
require('raptor-util').inherit(WhenNode, require('../../compiler/Node'));
|
||||
require('raptor-util').inherit(WhenNode, require('../../compiler').Node);
|
||||
module.exports = WhenNode;
|
||||
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
var AttributeSplitter = require('../../compiler/AttributeSplitter');
|
||||
var AttributeSplitter = require('../../compiler').AttributeSplitter;
|
||||
var varNameRegExp = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
||||
function WithNode(props) {
|
||||
WithNode.$super.call(this);
|
||||
@ -48,5 +48,5 @@ WithNode.prototype = {
|
||||
}, this).line('}());');
|
||||
}
|
||||
};
|
||||
require('raptor-util').inherit(WithNode, require('../../compiler/Node'));
|
||||
require('raptor-util').inherit(WithNode, require('../../compiler').Node);
|
||||
module.exports = WithNode;
|
||||
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
var EscapeXmlContext = require('../../compiler/EscapeXmlContext');
|
||||
var EscapeXmlContext = require('../../compiler/lib/EscapeXmlContext');
|
||||
function WriteNode(props) {
|
||||
WriteNode.$super.call(this, 'write');
|
||||
if (props) {
|
||||
@ -48,5 +48,5 @@ WriteNode.prototype = {
|
||||
return '<c:write expression="' + this.getExpression() + '">';
|
||||
}
|
||||
};
|
||||
require('raptor-util').inherit(WriteNode, require('../../compiler/Node'));
|
||||
require('raptor-util').inherit(WriteNode, require('../../compiler').Node);
|
||||
module.exports = WriteNode;
|
||||
@ -3,9 +3,8 @@
|
||||
|
||||
<tlib-version>1.0</tlib-version>
|
||||
|
||||
<uri>http://raptorjs.org/templates/core</uri>
|
||||
<short-name>core</short-name>
|
||||
<prefix>c</prefix>
|
||||
<alias>core</alias>
|
||||
<alias>c</alias>
|
||||
|
||||
<tag id="template">
|
||||
|
||||
@ -44,7 +43,7 @@
|
||||
<allow-expressions>false</allow-expressions>
|
||||
</attribute>
|
||||
|
||||
<node-class>raptor/templating/taglibs/core/TemplateNode</node-class>
|
||||
<node-class>./TemplateNode</node-class>
|
||||
</tag>
|
||||
|
||||
<tag extends="template">
|
||||
@ -157,7 +156,7 @@
|
||||
|
||||
<!-- Compiler that applies to all tags as well -->
|
||||
<transformer>
|
||||
<class-name>raptor/templating/taglibs/core/CoreTagTransformer</class-name>
|
||||
<class-name>./CoreTagTransformer</class-name>
|
||||
</transformer>
|
||||
</tag>
|
||||
|
||||
@ -167,7 +166,7 @@
|
||||
|
||||
<name>for</name>
|
||||
|
||||
<node-class>raptor/templating/taglibs/core/ForNode</node-class>
|
||||
<node-class>./ForNode</node-class>
|
||||
|
||||
<attribute>
|
||||
<name>each</name>
|
||||
@ -208,7 +207,7 @@
|
||||
|
||||
<name>write</name>
|
||||
|
||||
<node-class>raptor/templating/taglibs/core/WriteNode</node-class>
|
||||
<node-class>./WriteNode</node-class>
|
||||
|
||||
<attribute>
|
||||
<name>value</name>
|
||||
@ -235,7 +234,7 @@
|
||||
|
||||
<name>if</name>
|
||||
|
||||
<node-class>raptor/templating/taglibs/core/IfNode</node-class>
|
||||
<node-class>./IfNode</node-class>
|
||||
|
||||
<attribute>
|
||||
<name>test</name>
|
||||
@ -246,11 +245,11 @@
|
||||
|
||||
<tag>
|
||||
<name>else</name>
|
||||
<node-class>raptor/templating/taglibs/core/ElseNode</node-class>
|
||||
<node-class>./ElseNode</node-class>
|
||||
|
||||
<transformer>
|
||||
<class-name>raptor/templating/taglibs/core/ElseTagTransformer</class-name>
|
||||
<after>raptor/templating/taglibs/core/CoreTagTransformer</after>
|
||||
<class-name>./ElseTagTransformer</class-name>
|
||||
<after>core/CoreTagTransformer</after>
|
||||
<properties>
|
||||
<type>else</type>
|
||||
</properties>
|
||||
@ -261,11 +260,11 @@
|
||||
<name>else-if</name>
|
||||
<attribute name="test" type="expression"/>
|
||||
|
||||
<node-class>raptor/templating/taglibs/core/ElseIfNode</node-class>
|
||||
<node-class>./ElseIfNode</node-class>
|
||||
|
||||
<transformer>
|
||||
<class-name>raptor/templating/taglibs/core/ElseTagTransformer</class-name>
|
||||
<after>raptor/templating/taglibs/core/CoreTagTransformer</after>
|
||||
<class-name>./ElseTagTransformer</class-name>
|
||||
<after>core/CoreTagTransformer</after>
|
||||
<properties>
|
||||
<type>else-if</type>
|
||||
</properties>
|
||||
@ -276,7 +275,7 @@
|
||||
|
||||
<name>invoke</name>
|
||||
|
||||
<node-class>raptor/templating/taglibs/core/InvokeNode</node-class>
|
||||
<node-class>./InvokeNode</node-class>
|
||||
|
||||
<attribute>
|
||||
<name>function</name>
|
||||
@ -297,7 +296,7 @@
|
||||
|
||||
<name>choose</name>
|
||||
|
||||
<node-class>raptor/templating/taglibs/core/ChooseNode</node-class>
|
||||
<node-class>./ChooseNode</node-class>
|
||||
|
||||
</tag>
|
||||
|
||||
@ -305,7 +304,7 @@
|
||||
|
||||
<name>when</name>
|
||||
|
||||
<node-class>raptor/templating/taglibs/core/WhenNode</node-class>
|
||||
<node-class>./WhenNode</node-class>
|
||||
|
||||
<attribute>
|
||||
<name>test</name>
|
||||
@ -318,7 +317,7 @@
|
||||
|
||||
<name>otherwise</name>
|
||||
|
||||
<node-class>raptor/templating/taglibs/core/OtherwiseNode</node-class>
|
||||
<node-class>./OtherwiseNode</node-class>
|
||||
|
||||
</tag>
|
||||
|
||||
@ -326,7 +325,7 @@
|
||||
|
||||
<name>def</name>
|
||||
|
||||
<node-class>raptor/templating/taglibs/core/DefNode</node-class>
|
||||
<node-class>./DefNode</node-class>
|
||||
|
||||
<attribute>
|
||||
<name>function</name>
|
||||
@ -346,7 +345,7 @@
|
||||
|
||||
<name>with</name>
|
||||
|
||||
<node-class>raptor/templating/taglibs/core/WithNode</node-class>
|
||||
<node-class>./WithNode</node-class>
|
||||
|
||||
<attribute>
|
||||
<name>vars</name>
|
||||
@ -360,7 +359,7 @@
|
||||
|
||||
<name>include</name>
|
||||
|
||||
<node-class>raptor/templating/taglibs/core/IncludeNode</node-class>
|
||||
<node-class>./IncludeNode</node-class>
|
||||
|
||||
<attribute>
|
||||
<name>template</name>
|
||||
@ -422,7 +421,7 @@
|
||||
|
||||
<name>var</name>
|
||||
|
||||
<node-class>raptor/templating/taglibs/core/VarNode</node-class>
|
||||
<node-class>./VarNode</node-class>
|
||||
|
||||
<attribute>
|
||||
<name>name</name>
|
||||
@ -455,7 +454,7 @@
|
||||
|
||||
<name>assign</name>
|
||||
|
||||
<node-class>raptor/templating/taglibs/core/AssignNode</node-class>
|
||||
<node-class>./AssignNode</node-class>
|
||||
|
||||
<attribute>
|
||||
<name>var</name>
|
||||
@ -470,7 +469,7 @@
|
||||
</tag>
|
||||
|
||||
<text-transformer>
|
||||
<class-name>raptor/templating/taglibs/core/CoreTextTransformer</class-name>
|
||||
<class-name>./CoreTextTransformer</class-name>
|
||||
</text-transformer>
|
||||
|
||||
</raptor-taglib>
|
||||
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
var ExpressionParser = require('../../compiler/ExpressionParser');
|
||||
var ExpressionParser = require('../../compiler').ExpressionParser;
|
||||
function DocTypeNode(props) {
|
||||
DocTypeNode.$super.call(this);
|
||||
if (props) {
|
||||
@ -39,5 +39,5 @@ DocTypeNode.prototype = {
|
||||
template.text('>');
|
||||
}
|
||||
};
|
||||
require('raptor-util').inherit(DocTypeNode, require('../../compiler/ElementNode'));
|
||||
require('raptor-util').inherit(DocTypeNode, require('../../compiler').ElementNode);
|
||||
module.exports = DocTypeNode;
|
||||
@ -36,14 +36,14 @@ HtmlTagTransformer.prototype = {
|
||||
if (compiler.options.xhtml !== true && startTagOnly[lookupKey] === true) {
|
||||
node.setStartTagOnly(true);
|
||||
}
|
||||
if (node.getQName() === 'html' && node.hasAttributeNS('http://raptorjs.org/templates/html', 'doctype')) {
|
||||
var doctype = node.getAttributeNS('http://raptorjs.org/templates/html', 'doctype');
|
||||
if (node.getQName() === 'html' && node.hasAttributeNS('raptor-templates/html', 'doctype')) {
|
||||
var doctype = node.getAttributeNS('raptor-templates/html', 'doctype');
|
||||
var docTypeNode = new DocTypeNode({
|
||||
value: doctype,
|
||||
pos: node.getPosition()
|
||||
});
|
||||
node.parentNode.insertBefore(docTypeNode, node);
|
||||
node.removeAttributeNS('http://raptorjs.org/templates/html', 'doctype');
|
||||
node.removeAttributeNS('raptor-templates/templates/html', 'doctype');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -19,7 +19,7 @@ var widgetsNS = 'http://raptorjs.org/templates/widgets';
|
||||
var strings = require('raptor-strings');
|
||||
var objects = require('raptor-objects');
|
||||
var stringify = require('raptor-json/stringify');
|
||||
var AttributeSplitter = require('../../compiler/AttributeSplitter');
|
||||
var AttributeSplitter = require('../../compiler').AttributeSplitter;
|
||||
function WidgetsTagTransformer() {
|
||||
}
|
||||
WidgetsTagTransformer.prototype = {
|
||||
50
test/compiler-tests.js
Normal file
50
test/compiler-tests.js
Normal file
@ -0,0 +1,50 @@
|
||||
'use strict';
|
||||
var chai = require('chai');
|
||||
chai.Assertion.includeStack = true;
|
||||
require('chai').should();
|
||||
var expect = require('chai').expect;
|
||||
var nodePath = require('path');
|
||||
var fs = require('fs');
|
||||
var logger = require('raptor-logging').logger(module);
|
||||
|
||||
function testCompiler(path) {
|
||||
var inputPath = nodePath.join(__dirname, path);
|
||||
var expectedPath = nodePath.join(__dirname, path + '.expected.js');
|
||||
var actualPath = nodePath.join(__dirname, path + '.actual.js');
|
||||
|
||||
var compiler = require('../compiler').createCompiler();
|
||||
var src = fs.readFileSync(inputPath, {encoding: 'utf8'});
|
||||
var expected = fs.readFileSync(expectedPath, {encoding: 'utf8'});
|
||||
|
||||
var output = compiler.compile(src, path);
|
||||
fs.writeFileSync(actualPath, output, {encoding: 'utf8'});
|
||||
|
||||
if (output !== expected) {
|
||||
throw new Error('Unexpected output for "' + inputPath + '":\nEXPECTED (' + expectedPath + '):\n---------\n' + expected +
|
||||
'\n---------\nACTUAL (' + actualPath + '):\n---------\n' + output + '\n---------');
|
||||
}
|
||||
}
|
||||
|
||||
describe('raptor-templates/compiler' , function() {
|
||||
|
||||
beforeEach(function(done) {
|
||||
for (var k in require.cache) {
|
||||
if (require.cache.hasOwnProperty(k)) {
|
||||
delete require.cache[k];
|
||||
}
|
||||
}
|
||||
|
||||
require('raptor-logging').configureLoggers({
|
||||
'raptor-templates': 'INFO'
|
||||
});
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
it('should compile a simple template', function(done) {
|
||||
testCompiler('test-project/simple.rhtml');
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
@ -6,6 +6,7 @@ var expect = require('chai').expect;
|
||||
var path = require('path');
|
||||
|
||||
|
||||
|
||||
describe('raptor-templates' , function() {
|
||||
|
||||
beforeEach(function(done) {
|
||||
|
||||
3
test/test-project/simple.rhtml
Normal file
3
test/test-project/simple.rhtml
Normal file
@ -0,0 +1,3 @@
|
||||
<c:template xmlns:c="core">
|
||||
Hello John
|
||||
</c:template>
|
||||
8
test/test-project/simple.rhtml.actual.js
Normal file
8
test/test-project/simple.rhtml.actual.js
Normal file
@ -0,0 +1,8 @@
|
||||
function create(helpers) {
|
||||
var empty = helpers.e,
|
||||
notEmpty = helpers.ne;
|
||||
|
||||
return function render(data, context) {
|
||||
context.w('Hello John');
|
||||
};
|
||||
}
|
||||
8
test/test-project/simple.rhtml.expected.js
Normal file
8
test/test-project/simple.rhtml.expected.js
Normal file
@ -0,0 +1,8 @@
|
||||
function create(helpers) {
|
||||
var empty = helpers.e,
|
||||
notEmpty = helpers.ne;
|
||||
|
||||
return function render(data, context) {
|
||||
context.w('Hello John');
|
||||
};
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user