diff options
author | Florian Dold <florian.dold@gmail.com> | 2016-10-10 03:50:11 +0200 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2016-10-10 03:50:11 +0200 |
commit | 9af485a584e47fd503ed5c62b9f6482574715f1e (patch) | |
tree | 687abbcff412bd4ce5c51d51de030a06e3963cf5 /lib/meta.js | |
download | wallet-core-9af485a584e47fd503ed5c62b9f6482574715f1e.tar.xz |
Squashed 'thirdparty/systemjs/' content from commit 5ed69b6
git-subtree-dir: thirdparty/systemjs
git-subtree-split: 5ed69b6344e8fc1cd43bf758350b2236f57e1499
Diffstat (limited to 'lib/meta.js')
-rw-r--r-- | lib/meta.js | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/lib/meta.js b/lib/meta.js new file mode 100644 index 000000000..24e8b38ce --- /dev/null +++ b/lib/meta.js @@ -0,0 +1,155 @@ +/* + * Meta Extension + * + * Sets default metadata on a load record (load.metadata) from + * loader.metadata via SystemJS.meta function. + * + * + * Also provides an inline meta syntax for module meta in source. + * + * Eg: + * + * loader.meta({ + * 'my/module': { deps: ['jquery'] } + * 'my/*': { format: 'amd' } + * }); + * + * Which in turn populates loader.metadata. + * + * 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 + * "format amd"; + * "deps[] jquery"; + * "globals.some value" + * console.log('this is my/module'); + * + * Configuration meta always takes preference to inline meta. + * + * Multiple matches in wildcards are supported and ammend the meta. + * + * + * The benefits of the function form is that paths are URL-normalized + * supporting say + * + * loader.meta({ './app': { format: 'cjs' } }); + * + * Instead of needing to set against the absolute URL (https://site.com/app.js) + * + */ + +(function() { + + hookConstructor(function(constructor) { + return function() { + this.meta = {}; + constructor.call(this); + }; + }); + + hook('locate', function(locate) { + return function(load) { + var meta = this.meta; + var name = load.name; + + // NB for perf, maybe introduce a fast-path wildcard lookup cache here + // which is checked first + + // apply wildcard metas + var bestDepth = 0; + var wildcardIndex; + for (var module in meta) { + wildcardIndex = module.indexOf('*'); + 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)) { + var depth = module.split('/').length; + if (depth > bestDepth) + bestDepth = depth; + extendMeta(load.metadata, meta[module], bestDepth != depth); + } + } + + // apply exact meta + if (meta[name]) + extendMeta(load.metadata, meta[name]); + + return locate.call(this, load); + }; + }); + + // detect any meta header syntax + // only set if not already set + var metaRegEx = /^(\s*\/\*[^\*]*(\*(?!\/)[^\*]*)*\*\/|\s*\/\/[^\n]*|\s*"[^"]+"\s*;?|\s*'[^']+'\s*;?)+/; + var metaPartRegEx = /\/\*[^\*]*(\*(?!\/)[^\*]*)*\*\/|\/\/[^\n]*|"[^"]+"\s*;?|'[^']+'\s*;?/g; + + function setMetaProperty(target, p, value) { + var pParts = p.split('.'); + var curPart; + while (pParts.length > 1) { + curPart = pParts.shift(); + target = target[curPart] = target[curPart] || {}; + } + curPart = pParts.shift(); + if (!(curPart in target)) + target[curPart] = value; + } + + hook('translate', function(translate) { + return function(load) { + // shortpath for bundled + if (load.metadata.format == 'defined') { + load.metadata.deps = load.metadata.deps || []; + return Promise.resolve(load.source); + } + + // NB meta will be post-translate pending transpiler conversion to plugins + var meta = load.source.match(metaRegEx); + if (meta) { + var metaParts = meta[0].match(metaPartRegEx); + + for (var i = 0; i < metaParts.length; i++) { + var curPart = metaParts[i]; + var len = curPart.length; + + var firstChar = curPart.substr(0, 1); + if (curPart.substr(len - 1, 1) == ';') + len--; + + if (firstChar != '"' && firstChar != "'") + continue; + + var metaString = curPart.substr(1, curPart.length - 3); + var metaName = metaString.substr(0, metaString.indexOf(' ')); + + if (metaName) { + var metaValue = metaString.substr(metaName.length + 1, metaString.length - metaName.length - 1); + + if (metaName.substr(metaName.length - 2, 2) == '[]') { + metaName = metaName.substr(0, metaName.length - 2); + load.metadata[metaName] = load.metadata[metaName] || []; + load.metadata[metaName].push(metaValue); + } + else if (load.metadata[metaName] instanceof Array) { + // temporary backwards compat for previous "deps" syntax + warn.call(this, 'Module ' + load.name + ' contains deprecated "deps ' + metaValue + '" meta syntax.\nThis should be updated to "deps[] ' + metaValue + '" for pushing to array meta.'); + load.metadata[metaName].push(metaValue); + } + else { + setMetaProperty(load.metadata, metaName, metaValue); + } + } + else { + load.metadata[metaString] = true; + } + } + } + + return translate.apply(this, arguments); + }; + }); +})(); |