diff --git a/lib/meta.js b/lib/meta.js index 74a2b0db..2d424457 100644 --- a/lib/meta.js +++ b/lib/meta.js @@ -2,38 +2,29 @@ * Meta Extension * * Sets default metadata on a load record (load.metadata) from - * loader.meta[moduleName]. + * loader.meta. + * + * * Also provides an inline meta syntax for module meta in source. * * Eg: * - * loader.meta['my/module'] = { some: 'meta' }; + * loader.meta['my/module'] = { deps: ['jquery'] }; + * loader.meta['my/*'] = { format: 'amd' }; * - * load.metadata.some = 'meta' will now be set on the load record. + * load.metadata.deps and load.metadata.format will then be set + * for 'my/module' * * The same meta could be set with a my/module.js file containing: * * my/module.js - * "some meta"; - * "another meta"; + * "format amd"; + * "deps jquery"; * console.log('this is my/module'); * - * The benefit of inline meta is that coniguration doesn't need - * to be known in advance, which is useful for modularising - * configuration and avoiding the need for configuration injection. + * Configuration meta always takes preference to inline meta. * - * - * Example - * ------- - * - * The simplest meta example is setting the module format: - * - * System.meta['my/module'] = { format: 'amd' }; - * - * or inside 'my/module.js': - * - * "format amd"; - * define(...); + * Multiple matches in wildcards are supported and ammend the meta. * */ @@ -46,12 +37,34 @@ }; }); + function extend(a, b) { + for (var p in b) { + if (!(p in a)) + a[p] = b[p]; + } + } + hook('locate', function(locate) { return function(load) { - var meta = this.meta[load.name]; - for (var p in meta) { - if (load.metadata[p] === undefined) - load.metadata[p] = meta[p]; + var meta = this.meta; + var name = load.name; + + // apply exact meta + if (meta[name]) + extend(load.metadata, meta[name]); + + // NB for perf, maybe introduce a fast-path wildcard lookup cache here + // which is checked first + + // apply wildcard metas + var wildcardIndex; + for (var module in meta) { + wildcardIndex = indexOf.call(module, '*'); + if (wildcardIndex === -1) + continue; + if (module.substr(0, wildcardIndex) === name.substr(0, wildcardIndex) + && module.substr(wildcardIndex + 1) === name.substr(name.length - module.length + wildcardIndex + 1)) + extend(load.metadata, meta[module]); } return locate.call(this, load); }; @@ -84,9 +97,7 @@ if (metaName) { var metaValue = metaString.substr(metaName.length + 1, metaString.length - metaName.length - 1); - if (load.metadata[metaName] instanceof Array) - load.metadata[metaName].push(metaValue); - else if (load.metadata[metaName] === undefined) + if (!(metaName in load.metadata)) load.metadata[metaName] = metaValue; } } diff --git a/lib/register.js b/lib/register.js index 8a735c9e..abb00bcf 100644 --- a/lib/register.js +++ b/lib/register.js @@ -429,11 +429,13 @@ }); hook('translate', function(translate) { + // we run the meta detection here (register is after meta) return function(load) { - load.metadata.deps = load.metadata.deps || []; - - // we run the meta detection here (register is after meta) return Promise.resolve(translate.call(this, load)).then(function(source) { + + if (typeof load.metadata.deps === 'string') + load.metadata.deps = load.metadata.deps.split(','); + load.metadata.deps = load.metadata.deps || []; // dont run format detection for globals shimmed // ideally this should be in the global extension, but there is