underscore-template-loader
Advanced tools
Comparing version 0.5.0 to 0.5.1
129
index.js
@@ -0,1 +1,6 @@ | ||
var path = require('path'); | ||
var loaderUtils = require('loader-utils'); | ||
var attributeParser = require('./lib/attributeParser'); | ||
var macroParser = require('./lib/macroParser'); | ||
try { | ||
@@ -7,85 +12,75 @@ var _ = require('underscore'); | ||
module.exports = function() { | ||
var path = require('path'); | ||
var loaderUtils = require('loader-utils'); | ||
// Extendable arguments | ||
var macros = _.extend({}, require('./lib/macros')); | ||
// Parsers | ||
var attributeParser = require('./lib/attributeParser'); | ||
var macroParser = require('./lib/macroParser'); | ||
module.exports = function(content) { | ||
this.cacheable && this.cacheable(); | ||
var callback = this.async(); | ||
// Extendable arguments | ||
var macros = _.extend({}, require('./lib/macros')); | ||
// Default arguments | ||
var root, | ||
parseMacros = true, | ||
attributes = ['img:src']; | ||
return function(content) { | ||
this.cacheable && this.cacheable(); | ||
var callback = this.async(); | ||
// Parse arguments | ||
var query = this.query instanceof Object ? this.query : loaderUtils.parseQuery(this.query); | ||
// Default arguments | ||
var root, | ||
parseMacros = true, | ||
attributes = ['img:src']; | ||
if (_.isObject(query)) { | ||
root = query.root; | ||
// Parse arguments | ||
var query = loaderUtils.parseQuery(this.query); | ||
// Apply template settings | ||
_.each(_.pick(query, 'interpolate', 'escape', 'evaluate'), function(value, key) { | ||
_.templateSettings[key] = new RegExp(value, 'g'); | ||
}); | ||
if (_.isObject(query)) { | ||
root = query.root; | ||
// Apply template settings | ||
_.each(_.pick(query, 'interpolate', 'escape', 'evaluate'), function(value, key) { | ||
_.templateSettings[key] = new RegExp(value, 'g'); | ||
}); | ||
// Set tag+attribute to parse for external resources | ||
if (query.attributes !== undefined) { | ||
attributes = _.isArray(query.attributes) ? query.attributes : []; | ||
} | ||
// Parse / ignore macros | ||
if (query.parseMacros !== undefined) { | ||
parseMacros = !!query.parseMacros; | ||
} | ||
// Prepend a html comment with the filename in it | ||
if (query.prependFilenameComment) { | ||
var filename = loaderUtils.getRemainingRequest(this); | ||
var filenameRelative = path.relative(query.prependFilenameComment, filename); | ||
content = "\n<!-- " + filenameRelative + " -->\n" + content; | ||
} | ||
// Set tag+attribute to parse for external resources | ||
if (query.attributes !== undefined) { | ||
attributes = _.isArray(query.attributes) ? query.attributes : []; | ||
} | ||
// Include additional macros | ||
if (_.isObject(this.options.macros)) { | ||
_.extend(macros, this.options.macros); | ||
// Parse / ignore macros | ||
if (query.parseMacros !== undefined) { | ||
parseMacros = !!query.parseMacros; | ||
} | ||
// Parse macros | ||
if (parseMacros) { | ||
var macrosContext = macroParser(content, function (macro) { | ||
return _.isFunction(macros[macro]); | ||
}, 'MACRO'); | ||
content = macrosContext.replaceMatches(content); | ||
// Prepend a html comment with the filename in it | ||
if (query.prependFilenameComment) { | ||
var filenameRelative = path.relative(query.prependFilenameComment, this.resource); | ||
content = "\n<!-- " + filenameRelative + " -->\n" + content; | ||
} | ||
} | ||
// Parse attributes | ||
var attributesContext = attributeParser(content, function (tag, attr) { | ||
return attributes.indexOf(tag + ':' + attr) != -1; | ||
}, 'ATTRIBUTE', root); | ||
content = attributesContext.replaceMatches(content); | ||
// Include additional macros | ||
if (_.isObject(this.options.macros)) { | ||
_.extend(macros, this.options.macros); | ||
} | ||
// Compile template | ||
var source = _.template(content).source; | ||
// Parse macros | ||
if (parseMacros) { | ||
var macrosContext = macroParser(content, function (macro) { | ||
return _.isFunction(macros[macro]); | ||
}, 'MACRO'); | ||
content = macrosContext.replaceMatches(content); | ||
} | ||
// Resolve macros | ||
if (parseMacros) { | ||
source = macrosContext.resolveMacros(source, macros); | ||
} | ||
// Parse attributes | ||
var attributesContext = attributeParser(content, function (tag, attr) { | ||
return attributes.indexOf(tag + ':' + attr) != -1; | ||
}, 'ATTRIBUTE', root); | ||
content = attributesContext.replaceMatches(content); | ||
// Resolve attributes | ||
source = attributesContext.resolveAttributes(source); | ||
// Compile template | ||
var source = _.template(content).source; | ||
callback(null, "module.exports = " + source + ";"); | ||
}; | ||
}(); | ||
// Resolve macros | ||
if (parseMacros) { | ||
source = macrosContext.resolveMacros(source, macros); | ||
} | ||
module.exports._ = _; | ||
// Resolve attributes | ||
source = attributesContext.resolveAttributes(source); | ||
callback(null, "module.exports = " + source + ";"); | ||
}; | ||
module.exports._ = _; |
@@ -23,3 +23,3 @@ var path = require('path'); | ||
this.matches.reverse(); | ||
this.matches.forEach(function (match) { | ||
@@ -56,3 +56,3 @@ // Ignore if path is absolute and no root path has been defined | ||
content.reverse(); | ||
content.reverse(); | ||
return content.join(''); | ||
@@ -89,2 +89,6 @@ }; | ||
outside: { | ||
"<!--.*?-->": true, | ||
"<![CDATA[.*?]]>": true, | ||
"<[!\\?].*?>": true, | ||
"<\/[^>]+>": true, | ||
"<([a-zA-Z\\-:]+)\\s*": function (match, tagName) { | ||
@@ -110,2 +114,2 @@ this.currentTag = tagName; | ||
return parser.parse('outside', html, context); | ||
}; | ||
}; |
@@ -23,3 +23,3 @@ var Parser = require("fastparse"); | ||
var MacroContext = function (isMacroAvailable, usid) { | ||
this.currentDirective = null; | ||
this.currentMacro = null; | ||
this.matches = []; | ||
@@ -67,7 +67,7 @@ this.isMacroAvailable = isMacroAvailable; | ||
var macro = self.data[match]; | ||
return "' + " + macros[macro.name].apply(null, macro.getArguments()) + " + '"; | ||
return "' + " + macros[macro.name].apply(null, macro.getArguments()) + " + '"; | ||
}); | ||
// Replace escaped macros | ||
content = content.replace(/\\+(@[\w]+)/, function (match, expr) { | ||
content = content.replace(/\\+(@\w+)/, function (match, expr) { | ||
return expr; | ||
@@ -81,4 +81,4 @@ }); | ||
var processStringArg = function (match, value, index, length) { | ||
if (!this.currentDirective) return; | ||
this.currentDirective.args.push({ | ||
if (!this.currentMacro) return; | ||
this.currentMacro.args.push({ | ||
start: index + value.length, | ||
@@ -93,4 +93,4 @@ index: index, | ||
var processNumArg = function (match, value, index, length) { | ||
if (!this.currentDirective) return; | ||
this.currentDirective.args.push({ | ||
if (!this.currentMacro) return; | ||
this.currentMacro.args.push({ | ||
start: index + value.length, | ||
@@ -105,4 +105,4 @@ index: index, | ||
var processBooleanArg = function (match, value, index, length) { | ||
if (!this.currentDirective) return; | ||
this.currentDirective.args.push({ | ||
if (!this.currentMacro) return; | ||
this.currentMacro.args.push({ | ||
start: index + value.length, | ||
@@ -118,11 +118,13 @@ index: index, | ||
outside: { | ||
"[^\\\\]@([\\w]+)\\(": function (match, name, index, length) { | ||
"^@(\\w+)\\(|([^\\\\])@(\\w+)\\(": function (match, name, prefix, _name, index, length) { | ||
var name = name || _name; | ||
if (!this.isMacroAvailable(name)) { | ||
this.currentDirective = null; | ||
this.currentMacro = null; | ||
return 'inside'; | ||
} | ||
var directive = new Macro(name, index, length); | ||
this.matches.push(directive); | ||
this.currentDirective = directive; | ||
var macro = new Macro(name, prefix ? index + 1 : index, length); | ||
this.matches.push(macro); | ||
this.currentMacro = macro; | ||
return 'inside'; | ||
@@ -134,4 +136,4 @@ } | ||
"\\)": function (match, index) { | ||
if (this.currentDirective !== null) { | ||
this.currentDirective.length = 1 + index - this.currentDirective.start; | ||
if (this.currentMacro !== null) { | ||
this.currentMacro.length = 1 + index - this.currentMacro.start; | ||
} | ||
@@ -138,0 +140,0 @@ return 'outside'; |
@@ -32,2 +32,2 @@ var loaderUtils = require('loader-utils'); | ||
} | ||
}; | ||
}; |
{ | ||
"name": "underscore-template-loader", | ||
"version": "0.5.0", | ||
"version": "0.5.1", | ||
"description": "An Underscore and Lodash template loader for Webpack", | ||
@@ -10,2 +10,3 @@ "main": "index.js", | ||
}, | ||
"license": "MIT", | ||
"author": { | ||
@@ -31,2 +32,13 @@ "name": "Emmanuel Antico", | ||
}, | ||
"devDependencies": { | ||
"chai": "^3.2.0", | ||
"chai-string": "^1.1.2", | ||
"istanbul": "^0.3.18", | ||
"mocha": "^2.2.5", | ||
"underscore": "^1.8.3" | ||
}, | ||
"scripts": { | ||
"test": "mocha", | ||
"cover": "istanbul cover node_modules/mocha/bin/_mocha" | ||
}, | ||
"keywords": [ | ||
@@ -33,0 +45,0 @@ "underscore", |
@@ -128,3 +128,3 @@ underscore-template-loader | ||
<br> | ||
Images with an absolute path are not translated unless a `root` argument is defined | ||
Images with an absolute path are not translated unless a `root` option is defined | ||
@@ -223,3 +223,3 @@ <br> | ||
<br> | ||
####'br' and 'nl' | ||
####*br* and *nl* | ||
@@ -256,3 +256,3 @@ <br> | ||
macros: { | ||
'copyright': function () { | ||
copyright: function () { | ||
return "'<p>Copyright FakeCorp 2014 - 2015</p>'"; | ||
@@ -301,2 +301,60 @@ } | ||
<br> | ||
####Arguments | ||
<br> | ||
Macros can accept an arbitrary number of arguments. Only boolean, strings and numeric types are supported. | ||
<br> | ||
```javascript | ||
// File: webpack.config.js | ||
module.exports = { | ||
// ... | ||
module: { | ||
loaders: { | ||
// ... | ||
{ test: /\.html$/, loader: "underscore-template-loader" }, | ||
} | ||
}, | ||
macros: { | ||
header: function (size, content) { | ||
return "'<h" + size + ">" + content + "</h" + size + ">'"; | ||
} | ||
} | ||
} | ||
``` | ||
<br> | ||
```html | ||
@header(1, 'Welcome') | ||
<p>Lorem ipsum</p> | ||
@header(3, 'Contents') | ||
<p>Sit amet</p> | ||
``` | ||
<br> | ||
####Escaping | ||
<br> | ||
Macro expressions can be escaped with the `\` character. | ||
<br> | ||
```html | ||
@br(3) | ||
\@nl() | ||
@br() | ||
``` | ||
<br> | ||
Translates to | ||
<br> | ||
```html | ||
<br><br><br> | ||
@nl() | ||
<br> | ||
``` | ||
<br> | ||
####Known issues | ||
@@ -303,0 +361,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
39309
45
649
365
0
5
5