mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
Fixes #73 - Prevent same taglib from being loaded multiple times
This commit is contained in:
parent
f791bf8011
commit
d04c994271
@ -18,9 +18,9 @@
|
|||||||
var forEachEntry = require('raptor-util').forEachEntry;
|
var forEachEntry = require('raptor-util').forEachEntry;
|
||||||
var ok = require('assert').ok;
|
var ok = require('assert').ok;
|
||||||
|
|
||||||
function Taglib(id) {
|
function Taglib(path) {
|
||||||
ok(id, '"id" expected');
|
ok(path, '"path" expected');
|
||||||
this.id = id;
|
this.path = path;
|
||||||
this.dirname = null;
|
this.dirname = null;
|
||||||
this.tags = {};
|
this.tags = {};
|
||||||
this.textTransformers = [];
|
this.textTransformers = [];
|
||||||
|
|||||||
@ -33,7 +33,7 @@ function handleTag(taglibHandlers, tagName, path) {
|
|||||||
|
|
||||||
tagDirname = nodePath.dirname(path);
|
tagDirname = nodePath.dirname(path);
|
||||||
if (!exists(path)) {
|
if (!exists(path)) {
|
||||||
throw new Error('Tag at path "' + path + '" does not exist. Taglib: ' + taglib.id);
|
throw new Error('Tag at path "' + path + '" does not exist. Taglib: ' + taglib.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -44,7 +44,7 @@ function handleTag(taglibHandlers, tagName, path) {
|
|||||||
} else {
|
} else {
|
||||||
tagDirname = dirname; // Tag is in the same taglib file
|
tagDirname = dirname; // Tag is in the same taglib file
|
||||||
tagObject = path;
|
tagObject = path;
|
||||||
path = '<' + tagName + '> tag in ' + taglib.id;
|
path = '<' + tagName + '> tag in ' + taglib.path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -207,6 +207,20 @@ TaglibHandlers.prototype = {
|
|||||||
ok(transformer.path, '"path" is required for transformer');
|
ok(transformer.path, '"path" is required for transformer');
|
||||||
|
|
||||||
taglib.addTextTransformer(transformer);
|
taglib.addTextTransformer(transformer);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows an ID to be explicitly assigned to a taglib.
|
||||||
|
* The taglib ID is used to prevent the same taglib (even if different versions)
|
||||||
|
* from being loaded multiple times.
|
||||||
|
*
|
||||||
|
* NOTE: Introduced as part of fix for #73
|
||||||
|
*
|
||||||
|
* @param {String} value The taglib ID
|
||||||
|
*/
|
||||||
|
taglibId: function(value) {
|
||||||
|
var taglib = this.taglib;
|
||||||
|
taglib.id = value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -242,6 +256,32 @@ exports.loadTaglib = function(path) {
|
|||||||
|
|
||||||
propertyHandlers(taglibProps, taglibHandlers, path);
|
propertyHandlers(taglibProps, taglibHandlers, path);
|
||||||
|
|
||||||
taglib.id = taglib.path = path;
|
taglib.path = path;
|
||||||
|
|
||||||
|
if (!taglib.id) {
|
||||||
|
// Fixes #73
|
||||||
|
// See if there is a package.json in the same directory as the taglib file.
|
||||||
|
// If so, and if that package.json file has a "name" property then we will
|
||||||
|
// use the the name as the "taglib ID". The taglib ID is used to uniquely
|
||||||
|
// identity a taglib (ignoring version) and it is used to prevent the same
|
||||||
|
// taglib from being loaded multiple times.
|
||||||
|
//
|
||||||
|
// Using the file path as the taglib ID doesn't work so well since we might find
|
||||||
|
// the same taglib multiple times in the Node.js module search path with
|
||||||
|
// different paths.
|
||||||
|
var dirname = nodePath.dirname(path);
|
||||||
|
var packageJsonPath = nodePath.join(dirname, 'package.json');
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
var pkg = require(packageJsonPath);
|
||||||
|
taglib.id = pkg.name;
|
||||||
|
} catch(e) {}
|
||||||
|
|
||||||
|
if (!taglib.id) {
|
||||||
|
taglib.id = path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return taglib;
|
return taglib;
|
||||||
};
|
};
|
||||||
@ -20,8 +20,12 @@ function buildLookup(dirname) {
|
|||||||
var lookup = lookupCache[lookupCacheKey];
|
var lookup = lookupCache[lookupCacheKey];
|
||||||
if (lookup === undefined) {
|
if (lookup === undefined) {
|
||||||
lookup = new TaglibLookup();
|
lookup = new TaglibLookup();
|
||||||
|
// The taglibs "closer" to the template will be earlier in the list
|
||||||
for (var i=taglibs.length-1; i>=0; i--) {
|
// and the taglibs "farther" from the template will be later. We
|
||||||
|
// want closer taglibs to take precedence (especially when de-duping)
|
||||||
|
// so we loop from beginning to end. We used to loop from the end
|
||||||
|
// to the beginning, but that appears to have been a mistake.
|
||||||
|
for (var i=0; i<taglibs.length; i++) {
|
||||||
var taglib = taglibs[i];
|
var taglib = taglibs[i];
|
||||||
lookup.addTaglib(taglib);
|
lookup.addTaglib(taglib);
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"taglib-id": "marko-caching",
|
||||||
"tags": {
|
"tags": {
|
||||||
"cached-fragment": {
|
"cached-fragment": {
|
||||||
"renderer": "./cached-fragment-tag",
|
"renderer": "./cached-fragment-tag",
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"taglib-id": "marko-core",
|
||||||
"tags": {
|
"tags": {
|
||||||
"c-template": {
|
"c-template": {
|
||||||
"attributes": {
|
"attributes": {
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"taglib-id": "marko-html",
|
||||||
"tags": {
|
"tags": {
|
||||||
"html": {
|
"html": {
|
||||||
"attributes": {
|
"attributes": {
|
||||||
|
|||||||
3
test/fixtures/taglib-duplicate/foo-renderer.js
vendored
Normal file
3
test/fixtures/taglib-duplicate/foo-renderer.js
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
exports.render = function(input, out) {
|
||||||
|
|
||||||
|
};
|
||||||
6
test/fixtures/taglib-duplicate/marko-taglib.json
vendored
Normal file
6
test/fixtures/taglib-duplicate/marko-taglib.json
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"taglib-id": "taglib-duplicate",
|
||||||
|
"<duplicate-foo>": {
|
||||||
|
"renderer": "./foo-renderer.js"
|
||||||
|
}
|
||||||
|
}
|
||||||
3
test/fixtures/taglib-duplicate/taglib-duplicate/bar-renderer.js
vendored
Normal file
3
test/fixtures/taglib-duplicate/taglib-duplicate/bar-renderer.js
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
exports.render = function(input, out) {
|
||||||
|
|
||||||
|
};
|
||||||
6
test/fixtures/taglib-duplicate/taglib-duplicate/marko-taglib.json
vendored
Normal file
6
test/fixtures/taglib-duplicate/taglib-duplicate/marko-taglib.json
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"taglib-id": "taglib-duplicate",
|
||||||
|
"<duplicate-bar>": {
|
||||||
|
"renderer": "./bar-renderer.js"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -182,4 +182,20 @@ describe('taglib-lookup' , function() {
|
|||||||
expect(transformers[2].path.indexOf('html-tag-transformer')).to.not.equal(-1);
|
expect(transformers[2].path.indexOf('html-tag-transformer')).to.not.equal(-1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should de-duplicate taglibs', function() {
|
||||||
|
var taglibLookup = require('../compiler').taglibs.lookup;
|
||||||
|
var lookup = taglibLookup.buildLookup(nodePath.join(__dirname, 'fixtures/taglib-duplicate/taglib-duplicate'));
|
||||||
|
|
||||||
|
// The "duplicate-bar" tag was declared in the lower
|
||||||
|
// taglib so it should have been found since the taglib
|
||||||
|
// should not have been de-duped.
|
||||||
|
var barTag = lookup.getTag('duplicate-bar');
|
||||||
|
expect(barTag != null).to.equal(true);
|
||||||
|
|
||||||
|
// The "duplicate-foo" tag was declared in the higher
|
||||||
|
// up taglib so it should have been discarded
|
||||||
|
var fooTag = lookup.getTag('duplicate-foo');
|
||||||
|
expect(fooTag == null).to.equal(true);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user