diff options
Diffstat (limited to 'thirdparty/systemjs/lib/plugins.js')
-rw-r--r-- | thirdparty/systemjs/lib/plugins.js | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/thirdparty/systemjs/lib/plugins.js b/thirdparty/systemjs/lib/plugins.js new file mode 100644 index 000000000..33e81824e --- /dev/null +++ b/thirdparty/systemjs/lib/plugins.js @@ -0,0 +1,263 @@ +/* + SystemJS Loader Plugin Support + + Supports plugin loader syntax with "!", or via metadata.loader + + The plugin name is loaded as a module itself, and can override standard loader hooks + for the plugin resource. See the plugin section of the systemjs readme. +*/ + +(function() { + function getParentName(loader, parentName) { + // if parent is a plugin, normalize against the parent plugin argument only + if (parentName) { + var parentPluginIndex; + if (loader.pluginFirst) { + if ((parentPluginIndex = parentName.lastIndexOf('!')) != -1) + return parentName.substr(parentPluginIndex + 1); + } + else { + if ((parentPluginIndex = parentName.indexOf('!')) != -1) + return parentName.substr(0, parentPluginIndex); + } + + return parentName; + } + } + + function parsePlugin(loader, name) { + var argumentName; + var pluginName; + + var pluginIndex = name.lastIndexOf('!'); + + if (pluginIndex == -1) + return; + + if (loader.pluginFirst) { + argumentName = name.substr(pluginIndex + 1); + pluginName = name.substr(0, pluginIndex); + } + else { + argumentName = name.substr(0, pluginIndex); + pluginName = name.substr(pluginIndex + 1) || argumentName.substr(argumentName.lastIndexOf('.') + 1); + } + + return { + argument: argumentName, + plugin: pluginName + }; + } + + // put name back together after parts have been normalized + function combinePluginParts(loader, argumentName, pluginName, defaultExtension) { + if (defaultExtension && argumentName.substr(argumentName.length - 3, 3) == '.js') + argumentName = argumentName.substr(0, argumentName.length - 3); + + if (loader.pluginFirst) { + return pluginName + '!' + argumentName; + } + else { + return argumentName + '!' + pluginName; + } + } + + // note if normalize will add a default js extension + // if so, remove for backwards compat + // this is strange and sucks, but will be deprecated + function checkDefaultExtension(loader, arg) { + return loader.defaultJSExtensions && arg.substr(arg.length - 3, 3) != '.js'; + } + + function createNormalizeSync(normalizeSync) { + return function(name, parentName, isPlugin) { + var loader = this; + + var parsed = parsePlugin(loader, name); + parentName = getParentName(this, parentName); + + if (!parsed) + return normalizeSync.call(this, name, parentName, isPlugin); + + // if this is a plugin, normalize the plugin name and the argument + var argumentName = loader.normalizeSync(parsed.argument, parentName, true); + var pluginName = loader.normalizeSync(parsed.plugin, parentName, true); + return combinePluginParts(loader, argumentName, pluginName, checkDefaultExtension(loader, parsed.argument)); + }; + } + + hook('decanonicalize', createNormalizeSync); + hook('normalizeSync', createNormalizeSync); + + hook('normalize', function(normalize) { + return function(name, parentName, isPlugin) { + var loader = this; + + parentName = getParentName(this, parentName); + + var parsed = parsePlugin(loader, name); + + if (!parsed) + return normalize.call(loader, name, parentName, isPlugin); + + return Promise.all([ + loader.normalize(parsed.argument, parentName, true), + loader.normalize(parsed.plugin, parentName, false) + ]) + .then(function(normalized) { + return combinePluginParts(loader, normalized[0], normalized[1], checkDefaultExtension(loader, parsed.argument)); + }); + } + }); + + hook('locate', function(locate) { + return function(load) { + var loader = this; + + var name = load.name; + + // plugin syntax + var pluginSyntaxIndex; + if (loader.pluginFirst) { + if ((pluginSyntaxIndex = name.indexOf('!')) != -1) { + load.metadata.loader = name.substr(0, pluginSyntaxIndex); + load.name = name.substr(pluginSyntaxIndex + 1); + } + } + else { + if ((pluginSyntaxIndex = name.lastIndexOf('!')) != -1) { + load.metadata.loader = name.substr(pluginSyntaxIndex + 1); + load.name = name.substr(0, pluginSyntaxIndex); + } + } + + return locate.call(loader, load) + .then(function(address) { + if (pluginSyntaxIndex != -1 || !load.metadata.loader) + return address; + + // normalize plugin relative to parent in locate here when + // using plugin via loader metadata + return (loader.pluginLoader || loader).normalize(load.metadata.loader, load.name) + .then(function(loaderNormalized) { + load.metadata.loader = loaderNormalized; + return address; + }); + }) + .then(function(address) { + var plugin = load.metadata.loader; + + if (!plugin) + return address; + + // don't allow a plugin to load itself + if (load.name == plugin) + throw new Error('Plugin ' + plugin + ' cannot load itself, make sure it is excluded from any wildcard meta configuration via a custom loader: false rule.'); + + // only fetch the plugin itself if this name isn't defined + if (loader.defined && loader.defined[name]) + return address; + + var pluginLoader = loader.pluginLoader || loader; + + // load the plugin module and run standard locate + return pluginLoader['import'](plugin) + .then(function(loaderModule) { + // store the plugin module itself on the metadata + load.metadata.loaderModule = loaderModule; + + load.address = address; + if (loaderModule.locate) + return loaderModule.locate.call(loader, load); + + return address; + }); + }); + }; + }); + + hook('fetch', function(fetch) { + return function(load) { + var loader = this; + if (load.metadata.loaderModule && load.metadata.loaderModule.fetch && load.metadata.format != 'defined') { + load.metadata.scriptLoad = false; + return load.metadata.loaderModule.fetch.call(loader, load, function(load) { + return fetch.call(loader, load); + }); + } + else { + return fetch.call(loader, load); + } + }; + }); + + hook('translate', function(translate) { + return function(load) { + var loader = this; + var args = arguments; + if (load.metadata.loaderModule && load.metadata.loaderModule.translate && load.metadata.format != 'defined') { + return Promise.resolve(load.metadata.loaderModule.translate.apply(loader, args)).then(function(result) { + var sourceMap = load.metadata.sourceMap; + + // sanitize sourceMap if an object not a JSON string + if (sourceMap) { + if (typeof sourceMap != 'object') + throw new Error('load.metadata.sourceMap must be set to an object.'); + + var originalName = load.address.split('!')[0]; + + // force set the filename of the original file + if (!sourceMap.file || sourceMap.file == load.address) + sourceMap.file = originalName + '!transpiled'; + + // force set the sources list if only one source + if (!sourceMap.sources || sourceMap.sources.length <= 1 && (!sourceMap.sources[0] || sourceMap.sources[0] == load.address)) + sourceMap.sources = [originalName]; + } + + // if running on file:/// URLs, sourcesContent is necessary + // load.metadata.sourceMap.sourcesContent = [load.source]; + + if (typeof result == 'string') + load.source = result; + else + warn.call(this, 'Plugin ' + load.metadata.loader + ' should return the source in translate, instead of setting load.source directly. This support will be deprecated.'); + + return translate.apply(loader, args); + }); + } + else { + return translate.apply(loader, args); + } + }; + }); + + hook('instantiate', function(instantiate) { + return function(load) { + var loader = this; + var calledInstantiate = false; + + if (load.metadata.loaderModule && load.metadata.loaderModule.instantiate && !loader.builder && load.metadata.format != 'defined') + return Promise.resolve(load.metadata.loaderModule.instantiate.call(loader, load, function(load) { + if (calledInstantiate) + throw new Error('Instantiate must only be called once.'); + calledInstantiate = true; + return instantiate.call(loader, load); + })).then(function(result) { + if (calledInstantiate) + return result; + + load.metadata.entry = createEntry(); + load.metadata.entry.execute = function() { + return result; + } + load.metadata.entry.deps = load.metadata.deps; + load.metadata.format = 'defined'; + return instantiate.call(loader, load); + }); + else + return instantiate.call(loader, load); + }; + }); + +})();
\ No newline at end of file |